在javascript中原型和原型链机制是最难懂的部分(没有之一),同时也是最重要的部分,在学习的过程中你可能认认真真的看了一遍但还是完全不懂书上说的什么,的确是这样的,我在学习的时候可是反复看了4、5遍才初步理解了。 下面我把我的理解总结了一下希望对你们有一点帮助。
对象
讲原型和原型链之前我们先讲基础知识——js对象。什么是对象呢? 这里引用别人的一句话“js中一切皆对象”,先不用完全明白,因为我也不明白,在后面的学习中慢慢理解。
首先在js中对象分为函数对象和普通对象两种,看下面的例子:
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
上面代码中fun1、fun2、fun3是函数对象,obj1、obj2、obj3是普通对象,那么怎么区分呢? 很简单,凡是通过 new Function() 创建的对象都是函数对象,其他的都是普通对象,fun1、fun2归根结底还是通过 new Function() 创建的,因此也是函数对象。
普通对象
首先我们来讲普通对象,我们通过一张图来看看普通对象在创建时都做了些什么。
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属性,所以接下来我们讲函数对象。
函数对象
用与上面类似的代码来解释:
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。
执行5、6行代码,我们可以看到控制台打印出来的结果如下:
结果印证了我们上面讲的内容:1.__proto__指向foo的构造函数function 2.prototype指向foo的原型对象prototype 3.原型对象中constructor指向构造函数foo。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。