【问题标题】:What happens to the prototype when a function redefines itself?当一个函数重新定义自己时,原型会发生什么?
【发布时间】:2013-01-04 13:59:13
【问题描述】:

我在 Stoyan Stefanov 的 JavaScript Patterns 书中看到了以下代码(经过编辑以去除多余的脂肪):

function Universe() {
    var instance = this;
    Universe = function() {
        return instance;
    }
}

Universe.prototype.nothing = true;
var uni = new Universe();
Universe.prototype.everything = true;
var uni2 = new Universe();

uni.nothing;     // true
uni2.nothing;    // true, but I was expecting undefined
uni.everything;  // undefined
uni2.everything; // undefined, but I was expecting true

我期待nothing 被分配给原始函数的原型,everything 被分配给闭包的原型(因为第二次分配发生在重新定义之后)。但是,输出显示发生了一些奇怪的事情,而这本书确实没有解释它。我还注意到:

  1. Universe.prototype 确实在重新定义函数后指向不同的对象,正如我所料。
  2. 重新定义后创建的其他实例仍将原始原型对象作为其__proto__。这就是我不明白的。

谁能解释一下?

【问题讨论】:

    标签: javascript prototype


    【解决方案1】:

    这是一个单例模式。首次创建 Universe 时,重新定义了 Universe 符号。 (不过,它仍然存在于一种不确定状态:实例对它有一些引用。例如,__proto__ 在非严格模式下。)

    新的宇宙符号不是实际上是一个构造函数,它只是返回第一个创建的实例。第二次调用中的 new 关键字创建了一个以第二个 Universe 作为原型的新实例,但新函数只是忽略它并返回存储的第一个实例。

    【讨论】:

    • 谢谢,正如我在上面评论的那样,我非常关注代码的其他方面,而错过了返回内容的基本“细节”。哦!
    【解决方案2】:

    uniuni2 是同一个对象,因为instance 的值在Universe 函数的两个版本中都会返回。

    这是相同的代码,但没有从重新定义的Universe 返回的instancehttp://jsfiddle.net/nmaBn/

    【讨论】:

    • 当然!我怎么能错过!我专注于原型和重新定义,忘记了返回值(实际上这就是示例的全部内容)。
    • @bfavaretto 我错过了,不得不打破 jsFiddle... 但是,我认为你发现了单例模式的这种实现的一些真正问题:原型链被交换,正如有人指出的那样在评论中,instanceof 运算符失败。如果对原始Universe 函数的引用存储在某个地方,则会出现另一个潜在问题。这些显示在this jsFiddle 中。一些更改解决了它们,但它们增加了复杂性:demo
    • 我想底线是(必须对那本书给予应有的赞扬):在 js 中创建单例的最简单方法就是使用对象文字。
    猜你喜欢
    • 2018-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-05
    相关资源
    最近更新 更多