首页 > Web开发 > 详细

js原型与原型链

时间:2016-01-19 23:36:01      阅读:359      评论:0      收藏:0      [点我收藏+]

一、prototype与__proto__

  1、prototype(显式原型):每一个函数在创建之后都会拥有一个名为prototype的属性,这个属性指向函数的原型对象。它只存在于函数里,例如下面的例子中:

function Person(name) {
            this.name = name;
            this.showMe = function() {
                alert(this.name);
            }
        };

        Person.prototype.from = function() {
            alert(‘I come from prototype.‘);
        }
 var p = new Person(‘js‘);
 p.from();

  Person拥有prototype对象,我们向对象中添加了一个from方法,构造函数中有一个prototype的属性,改属性是一个指针,指向对应的prototype对象(注意区分一个是属性一个是对象),这里还有一个重要的属性,就是prototype对象中有一个属性constructor,该属性指向对应的构造函数,是一种对应的关系。

  p是Person构造函数新建的一个实例,new这个方法分为3个部分,最重要的一步是第2步,就本例子来说 

    <1> var p={}; 也就是说,初始化一个对象p。

    <2> p.__proto__=Person.prototype;

    <3> Person.call(p);也就是说构造p,也可以称之为初始化p。

  p这个对象没有prototype属性,但是有__proto__属性,这个在下面会提到。

 

 

二、__proto__

  隐式原型,每一个对象都拥有该属性,上面提到新建的实例p,在实例化的时候,可以得出p.__proto__=Person.prototype。那么当我们调用p.Say()时,首先p中没有Say这个属性, 于是,他就需要到他的__proto__中去找,也就是Person.prototype,而我们在上面定义了 Person.prototype.Say=function(){}; 于是,就找到了这个方法。

  具体的例子如下图:

  技术分享

1.构造函数Foo()
构造函数的原型属性Foo.prototype指向了原型对象,在原型对象里有共有的方法,所有构造函数声明的实例(这里是f1,f2)都可以共享这个方法。

2.原型对象Foo.prototype
Foo.prototype保存着实例共享的方法,有一个指针constructor指回构造函数。

3.实例
f1和f2是Foo这个对象的两个实例,这两个对象也有属性__proto__,指向构造函数的原型对象,这样子就可以像上面1所说的访问原型对象的所有方法。

另外:
构造函数Foo()也有__proto__属性,
指向它的构造函数的原型对象。函数的构造函数就是Function,因此这里的__proto__指向了Function.prototype。

原型对象的__proto__属性
指向它的构造函数的原型对象。这里是Object.prototype.

最后,Object.prototype的__proto__属性指向null。
 
因此,这几个属性的具体总结是:
  1、__proto__:指向其构造函数的原型对象,所有的对象都拥有该属性
  2、prototype:指向函数的原型对象,只有函数拥有
  3、constructor:这个属性从字面上来理解,就是指向它的构造函数,其本意也可以这么理解。实例的构造函数是Person,Person的构造函数是Function等等
 
三、原型链与继承
  继承实际是就是已原型链为基础,通过__proto__属性的一层层查找,来找到父对象原型中的方法,获取使用
  先看代码:
  
function Person(name) {
			this.name = name;
			this.showMe = function() {
				alert(this.name);
			}
		};

		Person.prototype.from = function() {
			alert(‘I come from prototype.‘);
		}
 
  
		function SubPer() {}
		SubPer.prototype = new Person(‘js‘);   
		

		var son = new SubPer();
		son.showMe(); //js   
		son.from(); //I come from prototype.   
		alert(son.constructor); 

  代码里Person具有原型方法,SubPer通过SubPer.prototype = new Person(‘js‘)这句代码实现了继承,new的新实例son可以获取Person的方法。

  技术分享

  继承实现的方法就是:把子类的prototype设置为父类的一个(实例化)对象;
  SubPer.prototype = new Person();
  利用之前学到的new方法,可以转换为
  SubPer.prototype.__proto__ = Person.prototype;
  由图上可以看出   实例的__proto__指向prototype,所以
  p.__proto__.__proto__ = Person.prototype;
  这样就形成了一个已__proto__为连接的原型链。
 
  其实只从图上观察,也可以看到__proto__形成的一条线路,SubPer实例——SubPer的prototype(Person实例)——Person的prototype,这就一条原型链。
  
四、继承过程中的constructor
  未完待续

js原型与原型链

原文:http://www.cnblogs.com/stoneox/p/5143728.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!