1、prototype 与 [[Prototype]]
原型 (prototype) 这个词通常表示着两个概念。首先,构造器具有一个公用的prototype属性。
当构造器被用来创建新的对象时,新建对象会有一个[[Prototype]]属性用来作为创建它的构造器的prototype属性的引用。
其次,构造器又具有一个内部的[[Prototype]]属性,用来作为其构造器的prototype属性的引用,
再通常情况加引用了Function.prototype属性。总之,所有的Javascript对象都具有一个内部的[[Prototype]]属性,
而且仅当该对象时函数对象时,它同时还具有prototype属性。
首先使用new 创建对象
function Circle(radius) {
this.radius = radius;
}
var circ = new Circle(6);
var circ2 = {radius: 6};
按照上面原型的概念:
既 Circle 内部的[[Prototype]] 引用了 Object.prototype
circ内部的[[Prototype]] 引用了 Circle.prototype
circ2是直接继承(亦即,它的[[Prototype]]属性就是Object.prototype的引用)
2、 构造器原型
函数总是被分配一个prototype属性,而此函数作为构造器创建的所有对象内部的[[Prototype]]属性都被设置为该属性。
而这个函数所分配的原型对象的原型就是Object.prototype,另外,它还定义了一个constructor属性,
该属性是构造器本身的引用。new操作符可以被用在任何表达式中,并生成一个构造器,
这时我们就可以使用这个属性动态地创建与已知对象同类型的对象。
var circ = new Circle(6);
Circle.prototype.diameter = function() {
return this.radius * 2;
}
alert(circ.diameter()); // 12
alert(Circle,circle.constructor); // true
这里为 Circle.prototype 添加了 diameter 方法 并测试通过。有一部分人习惯用下面的方法来添加函数
Circle.prototype = {
diameter: function() {
return this.radius * 2;
}
}
var circ = new Circle(6); //声明变量如果放在 prototype被赋值的前面会导致circ.diameter未声明
alert(circ.diameter()); // 12
alert(Circle,circle.constructor); // false
当我们为Circle.prototype赋以新值时,javascript将不再为该对象创建constructor
属性。这就表示对constructor属性的[[Get]] 会引发解释器沿着原型链查找,直至找到相应的值。
再我们的构造器中,constructor属性查找的结果是将Object.prototype,而后者的constructor属性值是Object
解决方法就是手动为constructor属性赋值
Circle.prototype = {
constructor: Circle,
diameter: function() {
return this.radius * 2;
}
}
3、 instanceof
a 的内部属性[[Prototype]]或者它的原型链上的任一对象与 b.prototype 是同一对象,那么表达式 a instanceof b 就将返回true。
alert(circ instanceof Object );
alert(circ instanceof Circle);
alert(circ2 instanceof Object);