-
什么是原型
原型是一个对象
就我的理解原型就是 实例上的
__proto__
属性和构造函数的prototype
属性 指向的对象-
new 操作符生成对象时就干了3件事
var obj = {} //1.创建一个空对象 obj //2.我们将这个空对象的__proto__成员指向Foo函数对象prototypt obj.__proto__ = Foo.prototype //3.将Foo构造函数的this指针换为obj,然后再调用Base函数 Foo.call(obj)
-
-
构造函数、原型和实例之间的关系
-
原型链
什么是原型链?说白了,其实就是有限的实例对象和原型之间组成有限链,就是用来实现共享属性和继承的。
var arr = []; //arr -> Array.prototype ->Object.prototype -> null var o = new Object(); //o -> Object.prototype -> null;
但原型之间是如何实现继承的呢?
如果直接用
Array.prototype = Object.prototype
,那么所有对象就都指向一个原型了,修改一个对象的原型就会修改所有对象的原型,这显然是不行的。所以我们会通过一个新的对象来实现过渡
Array.prototype = new Object()
,这样Array既继承了Object原型的所有属性,也拥有了自己独立的原型,修改自己的原型也不会对其他对象构成影响。 -
关于对象 constructor 的指向错误
顾名思义,constructor是指向对象构造函数,但在面对继承的时候却不是这样的
function Father() { } var father = new Father(); function Son(){ } Son.prototype = father var son = new Son(); console.log(son.constructor) //Father
很明显son的构造函数是Son,但却指向了Father
这主要是因为son的原型上有了 constructor属性,son继承到了该属性,如果没有继承,那么son的constructor 就指向构造函数
但我们还是习惯实例的constructor指向构造函数
constructor属性不影响任何JavaScript的内部属性。constructor其实没有什么用处,只是JavaScript语言设计的历史遗留物。由于constructor属性是可以变更的,所以未必真的指向对象的构造函数,只是一个提示。不过,从编程习惯上,我们应该尽量让对象的constructor指向其构造函数,以维持这个惯例。
function Father() { } var father = new Father(); function Son(){ } Son.prototype = father Son.prototype.constructor = Son //让实例及原型的constructor都指向构造函数 var son = new Son(); console.log(son.constructor) //Father
虽然这里 son 的 constructor指向了它的构造函数,但 father 的构造函数也指向了 Son 。但这并不重要,因为在实际继承中,我们并不知道这个 father 对象的存在。我们通过Father创建出来的实例的constructor仍然指向 Father