推荐两篇好文:
主讲原型链
http://www.zhuoda.org/lunzi/101543.html
涉及到原型链
http://www.cn-cuckoo.com/2007/08/01/understand-javascript-closures-72.html
主讲原型链
http://www.zhuoda.org/lunzi/101543.html
涉及到原型链
http://www.cn-cuckoo.com/2007/08/01/understand-javascript-closures-72.html
不知道LZ对function的prototype和obj的__proto__有没有认识,以及,new操作到底干了什么。先看看这个:function A(){};
A.prototype.test = "someValue";
var a = {};
a.constructor = A;
a.__proto__ = A.prototype;
a.test; //"someValue"其实,new操作符做的工作,大致如下:function A(){};
A.prototype.test = "someValue";
var a = new A();
a.test; //"someValue
a instanceof A; //true
A.prototype.isPrototypeOf(a); //true
这里再说own property。故名思议,就是固有属性的意思。先看看这个:var a = {};
a.toString(); // "[object Object]"
'toString' in a; // true
a.hasOwnProperty('toString'); //false
a.toString = function(){return "a";};
a.toString(); // "a"
a.hasOwnProperty('toString'); //true这说明,a对象确实有toString方法,但是'toString'并不是a对象的固有属性,当给a对象注册一个toString属性后,toString把之前的来自Object的方法屏蔽了,并且hasOwnProperty也返回了true。那我们来分析一下使用a.toString的时候,js解析器是如何查找的。首先,在a的固有属性中查找toString方法,如果找到,则直接返回,使用该值即可。如果未找到,对,未找到,那怎么办呢?于是,解析器会继续在a的__proto__中查找toString。如果还未找到怎么办?嘿嘿,别忘了__proto__这个属性的本质也是一个对象,所以a.__proto__也会有__proto__属性。于是就在__proto__的__proto__中查找toString。直到,直到,直到什么?那这样岂不会死循环?No,js中有一个对象,他没有原型,那就是Object.prototype,也就是(new Object()).__proto__。({}).__proto__; //Object {}
({}).__proto__.__proto__; //null于是,这个递归过程找到了出口。很多js环境,都不允许直接操作__proto__这个属性,因此,js中书写继承看起来相当诡异。function A(){}
A.prototype.a = "valueFromA";
function B(){}
B.prototype = new A();
//B.prototype.__proto__ = A.prototype;
//B.prototype = Object.create(A.prototype);
B.prototype.b = "valueFromB";
var inst = new B();
inst.a; //valueFromA
inst.b; //valueFromB;
B.prototype = new A();这一句着实让人费解,但是知道new操作的背后,如果我们可以操作__proto__,那么,B.prototype.__proto__ = A.prototype,这一句就语义清晰多了。当然,用最新的Object.create方法,
B.prototype = Object.create(A.prototype),那就更明白了,从A的prototype构造B的prototype,和B extends A已经相差不远了。
var foo = {
x: 10,
y: 20
};
当我不指定__proto__的时候,foo也会预留一个这样的属性, 如果有明确的指向,那么这个链表就链起来啦。 很明显,下图中b和c共享a的属性和方法,同时又有自己的私有属性。 __proto__默认的也有指向。它指向的是最高级的object.prototype,而object.prototype的__proto__为空。 var a ={
x: 10,
calculate: function (z)
{
return this.x + this.y + z
}
}; var b = {
y: 20,
__proto__: a
}; var c = {
y: 30,
__proto__: a
}; // call the inherited method
b.calculate(30); // 60 理解了__proto__这个属性链接指针的本质。再来理解constructor。 当定义一个prototype的时候,会构造一个原形对象,这个原型对象存储于构造这个prototype的函数的原形方法之中。function Foo(y){
this.y = y ;
} Foo.prototype.x = 10; Foo.prototype.calculate = function(z){
return this.x+this.y+z;
}; var b = new Foo(20); alert(b.calculate(30));
http://blog.csdn.net/siczxw555/article/details/6138428 浅析JS原型链,这篇文章讲得浅显易懂
http://dmitrysoshnikov.com/ecmascript/javascript-the-core/ 这篇文章的图不错我觉得应该记住的是:
如果构造器(函数)有个原型对象A,则由构造器构造的对象实例都复制于这个原型对象A。对象实例是没有原型的,也就是没有prototype这个属性,构造器(函数)才有原型对象,原型对象的constructor属性会指向构造器(函数)。所以,记住:对象实例只是构造于某个原型,而不拥有某个原型。但是,每个对象在内部会有个__proto__属性,指向构造其的原型,由这个属性维护的被称为内部原型链,它是js引擎支持js原型继承机制所需要的。而由prototype和constructor维护的被称为外部原型链,供我们写js代码回溯用。
要么空要么有
有的话就成了一个链
2.将自己的原型即prototype属性指向第一步中得到的实例。如:A要继承B
1.var c=new B();
2.A.prototype=c;
那么此时,当实例化A的时候(var d=new A()),实例d的原型(prototype属性)指向c,而c的原型(prototype)又指向B.prototype,z这就形成了实例与原型的链条。这就是原型链的基本概念。
http://blog.csdn.net/a569171010/article/details/7467514
http://www.iteye.com/topic/195409
http://stauren.net/log/eggxfygvg.html
http://blog.endlesscode.com/2010/01/23/javascript-prototype-chain/
http://www.cnblogs.com/ziyunfei/archive/2012/10/15/2723963.htmlhttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/JavaScript_Overview?redirectlocale=en-US&redirectslug=JavaScript%2FGuide%2FJavaScript_Overview
https://developer.mozilla.org/zh-CN/docs/JavaScript/Guide
__proto__:所有对象都有,prototype只有函数有。
this.y = y;
}
Foo.prototype.x = 10;
Foo.prototype.calculate = function (z) {
return this.x + this.y + z;
};
var b = new Foo(20);
var c = new Foo(30);
b.calculate(30); // 60
c.calculate(40); // 80
console.log(
b.__proto__ === Foo.prototype, // true
c.__proto__ === Foo.prototype, // true
b.constructor === Foo, // true
c.constructor === Foo, // true
b.prototype===undefined,
c.prototype===undefined,
Foo.constructor===Function,
Foo.prototype,
Foo.__proto__===Function.prototype,
Foo.prototype.constructor === Foo, // true
Foo.prototype.__proto__===Object.prototype,
Function.__proto__,//是一个空函数
Object.prototype.__proto__===null,
b.calculate === b.__proto__.calculate, // true
b.__proto__.calculate === Foo.prototype.calculate // true);