【问题标题】:value of this in the prototype inheritancethis 在原型继承中的值
【发布时间】:2009-07-15 14:43:46
【问题描述】:

如果我有:

var Shape = function()
{ 
    this.toString_ = function() { alert(this.UL)}
}

Shape.prototype.UL = "<UL></UL>"

var _2D = function() { this.name = "_2D"}

_2D.prototype = new Shape()

var i = new _2D()

i.toString_()

当我调用 i.toString_() 时,JS 引擎会尝试查找我是否有 toString_ 函数但没有找到它,然后进入 _2D.prototype(一个 Shape 实例)并找到该函数。

this 指的是 Shape 实例吗?

然后它执行该函数并在警报this.UL 中找到它现在没有找到它它转到具有该属性的Shape.prototype...

现在this是谁?

有人能解释一下this 在继承链中的价值吗?

它是否以i... 开头并以Shape.prototype 结尾?

困惑!

【问题讨论】:

  • 你的 toString() 方法被命名为 toString_() 的任何原因?
  • 没有理由写入 toString_()。

标签: javascript inheritance


【解决方案1】:

JavaScript 中的原型继承是这样工作的。

每个 Function 对象都有一个名为“prototype”的属性。当使用“new”创建对象时,运行时分配一个空对象并将其“prototype”属性设置为与构造函数的“prototype”属性相同的值。标准 JS 之后无法更新这个空白对象的原型。然后可以在构造函数中或以后在此对象中添加或删除属性。默认值为:

MyFunction.prototype = Object.prototype

每当使用“this.[property]”访问属性时,运行时首先查看上面创建的“this”对象是否具有该属性。如果未找到,则运行时查找“this.prototype”,然后查找“this.prototype.prototype”等,直到检查 Object.prototype。在那里找不到它将返回“未定义”作为属性值。

obj -> obj.prototype -> obj.prototype.prototype -> Object.prototype

例如,

var myPrototype = { prop : "ABC" }
function MyConstructor()
{
}
MyConstructor.prototype = myPrototype
var o = new MyConstructor()
alert( o.prop )

在上面,当解析“o.prop”时,运行时首先在“o”上查找名为“prop”的属性。未能在“o”上找到它,运行时在“myPrototype”上查找。在那里找到它,返回值“ABC”。

请注意,“this”引用总是引用上面创建的对象(例如,“o”)。因此,如果您要使用“this”为原型上的属性分配一个值,运行时实际上将创建一个具有该名称的新属性并将其放在使用“this”引用的对象上,而不是而不是更新原型中的值,从而“隐藏”原始值。为了修改原型的值,需要直接引用原型对象,或者通过“this.prototype”。或者通过对该对象的不同引用,说“thePrototypeObject.[property]”,假设您有一个变量分配给原型对象。

o.prop = "DEF"
alert( o.prop )
alert( myPrototype.prop )

在这种情况下,赋值语句在“o”上创建一个名为“prop”的新属性。因此,第一个警报打印“DEF”,而第二个警报打印“ABC”。

var o = new MyConstructor()
myPrototype.prop = "DEF"
alert( o.prop )
alert( myPrototype.prop )

这种的情况下,原始原型的“prop”属性被更新,所以两者都将打印相同的值(“ABC”)。

在你上面的例子中,

var Shape = function()
{ 
    this.toString_ = function() { alert(this.UL)}
}
Shape.prototype.UL = "<UL></UL>"
var _2D = function() { this.name = "_2D"}
_2D.prototype = new Shape()
var i = new _2D()

i.toString_()

原型链如下所示:

Shape.prototype -> Object.prototype

Object.prototype.UL = "<UL></UL>"

_2D.prototype -> (new Shape) -> Object.prototype

i.prototype -> (new Shape) -> Object.prototype

因此,当解析“toString_()”时,运行时会首先检查“i”,如果没有找到它,则查看(新 Shape)对象。在那里找到它,它调用“toString_()”将“i”传递为“this”。解析“this.UL”时,运行时首先查看“i”,然后是(new Shape),然后是“Object.prototype”,最后返回它在那里找到的值。

【讨论】:

  • 只有一个注释:MyFunction.prototype = Object.prototype 给出错误,如果我这样做:while(p = My.prototype) p = p.prototype 这里我有一个无限循环,但使用 while(m = m.__proto__) m = m.__proto__ 它在 m 为空时结束
  • new (function(){})().__proto__.__proto__ === Object.prototype
【解决方案2】:

只需添加:

alert(this instanceof Shape);
alert(this instanceof _2D);

toString_ 方法中,您会看到您拥有哪个this

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-07-07
    • 1970-01-01
    • 1970-01-01
    • 2010-09-28
    • 2013-11-07
    • 2013-05-20
    相关资源
    最近更新 更多