在javascript中原型和原型链机制是最难懂的部分(没有之一),同时也是最重要的部分,在学习的过程当中你可能认认真真的看了一遍但仍是彻底不懂书上说的什么,的确是这样的,我在学习的时候但是反复看了四、5遍才初步理解了。 下面我把个人理解总结了一下但愿对大家有一点帮助。javascript
讲原型和原型链以前咱们先讲基础知识——js对象。什么是对象呢? 这里引用别人的一句话“js中一切皆对象”,先不用彻底明白,由于我也不明白,在后面的学习中慢慢理解。
首先在js中对象分为函数对象和普通对象两种,看下面的例子:java
function fun1(){}; var fun2 = function(){}; var fun3 = new Function(); var obj1 = new fun1(); var obj2 = {}; var obj3 =new Object(); console.log(typeof Object); // function console.log(typeof Function); // function console.log(typeof obj1); // object console.log(typeof obj2); // object console.log(typeof obj3); // object console.log(typeof fun1); // function console.log(typeof fun2); // function console.log(typeof fun3); // function
上面代码中fun一、fun二、fun3是函数对象,obj一、obj二、obj3是普通对象,那么怎么区分呢? 很简单,凡是经过 new Function() 建立的对象都是函数对象,其余的都是普通对象,fun一、fun2归根结底仍是经过 new Function() 建立的,所以也是函数对象。segmentfault
首先咱们来说普通对象,咱们经过一张图来看看普通对象在建立时都作了些什么。函数
1 var foo = { 2 x: 10, 2 y: 20 3 } 4 console.log(foo.__proto === Object.prototype) // true
上面的代码中咱们建立了一个普通对象foo,并初始化了两个属性(自身属性)x、y,同时在对象内部还自动建立了一个属性__proto__,这个__proto__属性其实是个指针,指向构造foo的构造函数的原型,这里foo对象实际是经过 new Object 建立的,所以第4行代码结果为true. 这里讲到了Object.prototype就涉及到函数对象了,由于只有函数对象才有prototype属性,因此接下来咱们讲函数对象。学习
用与上面相似的代码来解释:this
1 function foo() { 2 this.x = 10 3 } 4 foo.prototype.y = 20; 5 console.log(foo.__proto__); 6 console.log(foo.prototype);
当咱们建立foo函数时,初始化了一个自身属性x = 10,同时函数对象中自动建立了一个prototype属性和__proto__属性,还为foo建立了一个原型对象foo.prototype。其中__proto__属性咱们上面已经讲过了,而prototype属性则指向foo新建立的prototype原型对象,这个原型对象中自动建立了一个constructor属性,指向构造函数foo。
(注:原型对象prototype也是一个普通对象,所以会自动建立__proto__属性,为避免文章变得晦涩难懂,此处省略,后面再深刻讲解)
执行第4行代码,为新建立的prototype原型对象添加了一个原型属性y = 20。
执行五、6行代码,咱们能够看到控制台打印出来的结果以下:spa
结果印证了咱们上面讲的内容:1.__proto__指向foo的构造函数function 2.prototype指向foo的原型对象prototype 3.原型对象中constructor指向构造函数foo。prototype