`

JS prototype 理解

阅读更多
JS里的对象在Ajax发展之后, 就跟着疯狂起来, 要玩好JS的对象, 就要搞清楚构造器(constructor), 指针(pointer), 原型(prototype)

这篇文章主要记录我对prototype的理解

prototype

最初的用法是, 为了避免方法在构造器里随机数据被实例化时而产生重复的副本
后来被用在"继承"上面了, 注意, JS语义上是没有继承的, 这里说的是人为的实现

总结, prototype其实也是指针, 默认是实例的指针, 当然也可以人为的改变,

父类A, 子类B

默认情况, B.prototype=A.prototype
这样, B可以访问A的所有原型方法, 这时, B的构造器也变成A了

改变一下, B.prototype=A
这样, B可以访问A的所有静态方法, 这时, B的构造器也变成类A的指针->类的指针->Function的指针->Function的构造器

以下是实例验证

	function demo(){
		var A=function(name){
			this.name=name;
		}
		A.prototype.showName=function(){alert(this.name);}
		var B=function(name, age){
			A.call(this, name);
			this.age=age;
		}
		//B.prototype=new A();    //这里2行代码的效果是一样的
		B.prototype=A.prototype;  //目的是返回A的"实例"的指针

		B.prototype.showAge=function(){alert(this.age);}
		var b=new B("david", 31);
		b.showName();
		b.showAge();
	}


严重注意以上代码的备注, 是new之后的instance的指针, 不是Class的指针,
下面改一下代码验证一下

	var A=function(name){
		this.name=name;
		//return this; 这是隐式代码, JS会自动帮我们执行, 这里是关键
	}

改为

	var A=function(name){
		var o=new Object();
		o.name=name;
		return o;
	}

然后, 当执行到b.showName();时, 就会抛出异常了, 因为 showName是prototype方法, 是指定在A的实例指针下的, 给A添加方法pointer()以获取实例的指针, 然后把它赋予B.prototype

	function demo(){
		var A=function(name){
			this.name=name;
		}
		A.prototype.showName=function(){alert(this.name);} //the function return this, "this" is the pointer of instance
		A.prototype.pointer=function(){return this;}
		var B=function(name, age){
			A.call(this, name);
			this.age=age;
		}
		//B.prototype=new A();
		//B.prototype=A.prototype;
		B.prototype=new A().pointer();

		B.prototype.showAge=function(){alert(this.age);}
		var b=new B("david", 31);
		b.showName();
		b.showAge();
	}


以上代码运行正常, 证明了prototype实质上就是指于实例的指针
那么, 如果, 把prototype的指针指于类, 又会如何呢, 我的想法是, 会得到类的静态方法或属性

以下代码, 给A添加静态方法showSex和静态属性city, 然后把A的类,
结果应该是A的原型方法showName会报错, 而b.showSex和alert(b.city)会得到正确的执行

	function demo(){
		var A=function(name){
			this.name=name;
		}
		A.prototype.showName=function(){alert(this.name);} //the function return this, "this" is the pointer of instance
		A.prototype.pointer=function(){return this;}
		A.showSex=function(){alert("male");}
		A.city="shenzhen";

		var B=function(name, age){
			A.call(this, name);
			this.age=age;
		}
		//B.prototype=new A();
		//B.prototype=A.prototype;
		B.prototype=A;

		B.prototype.showAge=function(){alert(this.age);}
		var b=new B("david", 31);
		try {
			b.showName();
		} catch (exception) {
			alert(exception);
		}
		b.showAge();
		b.showSex();
		alert(b.city);
	}


代码执行正常, 验证无误

再检验一下constructor

function demo(){
		var A=function(name){
			this.name=name;
		}
		A.prototype.showName=function(){alert(this.name);} //the function return this, "this" is the pointer of instance
		A.prototype.showSex=function(){alert("male");}
		A.prototype.city="shenzhen";

		var B=function(name, age){
			A.call(this, name);
			this.age=age;
		}
		B.prototype=A.prototype;
		B.prototype.showAge=function(){alert(this.age);}
		var b=new B("david", 31);
		try {
			alert(b.constructor);	//output Class A construct
			alert(b.constructor==A);//output true
		} catch (exception) {
			alert(exception);
		}
	}


结果表明
alert(b.constructor), 连 B 的构造器都变成 A 的了
alert(b.constructor==A), 再比较一次, 输出true, 没有悬念了

继续挖掘, 把B.prototype=A, 即把A的类指针赋予B的prototype

function demo(){
		var A=function(name){
			this.name=name;
		}
		A.prototype.showName=function(){alert(this.name);} //the function return this, "this" is the pointer of instance
		A.prototype.showSex=function(){alert("male");}
		A.prototype.city="shenzhen";

		var B=function(name, age){
			A.call(this, name);
			this.age=age;
		}
		B.prototype=A;
		B.prototype.showAge=function(){alert(this.age);}
		var b=new B("david", 31);
		try {
			alert(b.constructor==Function.constructor);//output true
			alert(b.constructor);  //output Function's constructor
		} catch (exception) {
			alert(exception);
		}
	}


结果表明, B.prototype指到类A的指针去了, 而类的指针, 又指向类的构造器了

再看看A, 被B"继承"后的样子, 在B.prototype=A的时候, this就已经是指向A了, showAge是不是也应该存在于A的实例呢? 在做个实验, 一个是A被继承前, 一个是A被继承后

function demo(){
		var A=function(name){
			this.name=name;
		}
		A.prototype.showName=function(){alert(this.name);} //the function return this, "this" is the pointer of instance
		A.prototype.showSex=function(){alert("male");}
		A.prototype.city="shenzhen";

		var a=new A("mochacoffee");

		var B=function(name, age){
			A.call(this, name);
			this.age=age;
		}
		B.prototype=A.prototype;
		B.prototype.showAge=function(){alert(this.age);}
		B.prototype.post="518000";	//add property for test
		
		var c=new A("reno");
		a.showAge();		//*1
		alert(a.showAge);	//*2
		c.showAge();		//*3
		alert(c.showAge);	//*4
		alert(a.post);		//*5
		alert(c.post);		//*6
	}


结果为: 
1: undefined
2: function showAge(){...}
3: undefined
4: function showAge(){...}
5: 518000
6: 518000

可以看出, expend之前之后的A, 其实已经是一样了,
undefined, 是因为没有给变量赋值, 但函数指针已经正确指到B的showAge了
关于prototype也是, 对于a, 在被B继承后, 也可以获取了518000了, 用java语言来说, prototype只是实例指针而已, 而不论showAge还是post, 都是一个对象, 所以当a的指针指向这个"后来"加上的对象时, 当然也就可以得到518000了

但这样的话, B被继承A之后, A也得到了B的prototype了, 对于继承机制来说, 这样还算是继承吗? A和B的区别, 仅仅是静态方法和属性而已
分享到:
评论

相关推荐

    关于JS中prototype的理解.docx

    关于JS中prototype的理解.docx

    关于JS中prototype的理解

    每一个构造函数都有一个属性叫做原型(prototype)。这个属性非常有用:为一个特定类声明通用的变量或者...2 javascript的方法可以分为三类: a 类方法 b 对象方法 c 原型方法 例子: function People(name) { th

    js prototype深入理解及应用实例分析

    本文实例讲述了js prototype深入理解及应用。分享给大家供大家参考,具体如下: 上一篇讲了js的prototype概念,在这里回顾一下prototype的定义: prototype是函数的一个属性,并且是函数的原型对象。引用它的必然是...

    简单理解js的prototype属性及使用

    在进入正文之前,我得先说说我认识js的prototype这个东西的曲折过程。 百度js的prototype的文章,先看看,W3School关于prototype的介绍: 你觉得这概念适合定义js的prototype这个东西吗?你是否也认为prototype是...

    JavaScript prototype属性详解

    在具体说prototype前说几个相关的东东,可以更好的理解prototype的设计意图。之前写的一篇JavaScript 命名空间博客提到过JavaScript的函数作用域,在函数内定义的变量和函数如果不对外提供接口,那么外部将无法访问...

    谈谈js中的prototype及prototype属性解释和常用方法

    prototype是javascript中笔记难理解的一部分内容,下面通过几个关键知识点给大家讲解js中的prototype,对js中的prototype相关知识感兴趣的朋友一起学习吧

    JS 面向对象之神奇的prototype

    JavaScript中对象的prototype属性,可以返回对象类型原型的引用。这是一个相当拗口的解释,要理解它,先要正确理解对象类型(Type)以及原型(prototype)的概念。 1 什么是prototype JavaScript中对象的prototype属性,...

    prototype.js源码解度

    prototype.js源码解度.doc 收集来给大家研究。重要的是理解作者的风格思路,对JS的水平提高很有帮助。

    深入理解javascript prototype的相关知识

    主要介绍了深入理解javascript prototype的相关知识,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

    javascript prototype 原型链

    JavaScript中的prototype概念恰如其分地反映了这个词的内含,我们不能将其理解为C++的prototype那种预先声明的概念。 JavaScript 的所有function类型的对象都有一个prototype属性。这个prototype属性本身又是一个...

    浅谈javascript中的prototype和__proto__的理解

    在工作中有时候会看到prototype和__proto__这两个属性,对这两个属性我一直比较蒙圈,但是我通过查阅相关资料,决定做一下总结加深自己的理解,写得不对的地方还请各位大神指出。 跟__proto__属性相关的两个方法 ...

    深入理解JS中的Function.prototype.bind()方法

    对于函数绑定(Function binding)很有可能是大家在使用JavaScript时最少关注的一点,但是当你意识到你需要一个解决方案来解决如何在另一个函数中保持this上下文的时候,你真正需要的其实就是 Function.prototype.bind...

    理解JavaScript的prototype属性

    其实,关于prototype只要几句话就可以总结: 任何原型都是对象,只有对象有原型 只有Function有prototype属性,它是这个Function作为构造器时生成对象所... 上面说的二义性,是文字理解上的,语法本身没有歧义。prot

    JavaScript prototype 使用介绍

    用过JavaScript的同学们肯定都对prototype如雷贯耳,但是这究竟是个什么东西却让初学者莫衷一是,只知道函数都会有一个prototype属性,可以为其添加函数供实例访问,其它的就不清楚了,最近看了一些 JavaScript高级...

    JS中prototype的用法实例分析

    本文实例讲述了JS中prototype的用法。分享给大家供大家参考。具体分析如下: JS中的phototype是JS中比较难理解的一个部分   本文基于下面几个知识点:   1 原型法设计模式 在.Net中可以使用clone()来实现原型法 ...

Global site tag (gtag.js) - Google Analytics