By
君羽
Updated:
prototype chain
prototype 是 constructor 的其中一个属性
拥有在创建实例的过程中引用给实例的功能
首先,有个问题,在new 一个构造函数的时候,js为我们做了什么?
1 把函数内部的this指针指向新创建的对象
2 把新对象的proto属性指引到构造函数的prototype
3 完成对象的初始化
4 把这个对象隐式地return 出来
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| 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 }; b.calculate(30); c.calculate(40);
|
既然已经知道了prototype的规则,
也可以按照如上的方式,直接修改新对象的proto,此方式与
1 2 3 4 5 6 7 8 9 10 11
| var a = function(){ return this; } a.prototype.x = 10; a.prototype.calculate = function(z){ return this.x+this.y+z } var b = new a(); b.y = 20; console.log(b) console.log(b.calculate(30));
|
构造出来的这个对象是一致的
而经过不断的创建实例,其实proto属性是存在嵌套的,
如一个对象会展现如下姿态
1 2 3 4 5 6 7 8 9 10 11 12
| a={ x:1, __proto__:{ y:2, __proto__:{ z:3, __proto__:{ n:0 } } } }
|
此时a可以获取到来自祖先prototype的n属性的
不过通过 console.log(a.hasOwnProperty(“n”));
可以确定n不是来自a本身,而是来自他的prototype层的
看了原型链,接下来我们来看看对象的继承,一般有两种常见的方式
1 空对象实例化后赋给 prototype
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| function a(){ this.x=1; } a.prototype.m = function(){ alert(1); } function Empty(){ } Empty.prototype = a.prototype; Empty.constructor = Empty; function b(){ a.apply(this,arguments); } b.prototype=new Empty(); b.constructor = b;
|
2 对象的枚举
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| function a(){ this.x=1; } a.prototype.m = function(){ alert(1); } function b(){ a.apply(this,arguments); } for(var i in a.prototype){ b.prototype[i] = a.prototype[i]; } b.constructor = b;
|