我在Dojo: The Definitive Guide中找到了以下示例:
function Shape(centerX, centerY, color)
{
this.centerX = centerX;
this.centerY = centerY;
this.color = color;
};
function Circle(centerX, centerY, color, radius)
{
this.base = Shape;
this.base(centerX, centerY, color);
this.radius = radius;
};
c = new Circle(10, 20, "blue", 2);
请解释此示例的工作原理。我理解当我们调用构造函数Circle时,this
引用正在创建的对象,因此我很清楚c
对象为什么具有base
和radius
属性,但是如何获得centerX
,centerY
,color
?
答案 0 :(得分:3)
因为您已将Shape
功能分配给this
,然后通过执行this.base()
来调用它。
所以在这里,base
方法是Shape
函数,当您执行obj.method()
时,this
中method
的值设置为obj
。因此,this
中Shape
的值是您的新Circle
对象。
更常见的方法是使用.call()
而不是将函数设置到对象上。
Shape.call(this, centerX, centerY, color);
这会调用Shape
函数,其this
值设置为您提供的第一个参数。传递给.call()
的其余参数只是作为Shape
的常规参数传递。
我猜他们会使用this.base = Shape
,因为代码中其他地方的this.base
还有其他用途。
答案 1 :(得分:2)
您的Circle
获取了一个新的base
属性,该属性解析为名为Shape
的函数:
this.base = Shape;
然后,调用该函数并传递centerX
,centerY
和color
参数。由于您的this
对象永远不会更改,因此centerX
和朋友被分配到同一个对象,后来获取radius
属性:
this.base(centerX, centerY, color);
this.radius = radius;
答案 2 :(得分:2)
在JavaScript中,函数也是对象。 Shape
是一个向this
添加方法和属性的函数,new
运算符可以使用它来生成Shape
个对象。它也可以由Circle调用,以便为Circle
创建的对象添加方法和属性。
您可以这样做,而不是分配base
:
function Circle(centerX, centerY, color, radius)
{
Shape.call(this, centerX, centerY, color);
this.radius = radius;
};
答案 3 :(得分:1)
如果我在this
窗口中调用window.dosomething()而不是this
,则它与dosomething
的上下文有关。如果我从新创建的c实例中调用this.base
而不是this
....则要创建c实例。
this.base恰好是Shape,所以当它被执行时this
上下文是......(你猜对了;它是要创建的圆圈)。
Shape的第一行是:
this.centerX = centerX;
现在,如果你还记得你提到的this
可能会在哪里添加centerX属性。
这种继承不使用原型,因此console.log(c instanceof Shape)
是假的,而且Shape上的原型不是Circle的一部分。
对于原型继承,您可以阅读以下内容:Prototypical inheritance - writing up(只是基础知识)