【问题标题】:Javascript Prototype Quirk - Can Anyone Explain This?Javascript Prototype Quirk - 谁能解释一下?
【发布时间】:2012-10-26 03:57:36
【问题描述】:

我对以下代码的期望是,如果我检查a.name,它将搜索原型并在声明时返回它。谁能指出是什么阻止了 JS 承认我的原型?

var obj = function(parent){
    return {
        prototype: parent
    }
};

var me = { name: 'keith' };

var a = new obj(me)
// => undefined

a.name
// => undefined

a.prototype.name
// => "keith"

【问题讨论】:

    标签: javascript prototypal-inheritance


    【解决方案1】:

    名为“prototype”的属性只是一个属性,它并不指向该对象所继承的对象。使用Object.getPrototypeOfnon-standard __proto__ property 来获取。

    所以您的函数obj(me) 返回的只是一个具有属性“原型”的对象,该对象指向一个具有属性“名称”的对象,该属性指向字符串keith。由于您的函数返回一个对象,因此是否使用 new keyword 调用它没有区别。

    对于继承,构造函数 [object] 的“原型”属性值得关注。此构造函数(不返回对象)使用new 关键字创建的每个对象都继承自构造函数 的“原型”属性指向的对象。所以你可以这样做:

    var Constructor = function() {
        console.log(this); // logs the currently created object
        // return nothing
    }
    Constructor.prototype = { name: 'keith' };
    
    var a = new Constructor(); // logs an empty object
    Object.getPrototypeOf(a) === Constructor.prototype; // true
    a.name; // "keith" - inherited
    

    【讨论】:

      【解决方案2】:

      在函数中你没有触及函数原型。您只是返回一个具有属性“原型”的新对象,其父值作为值。因此,您只能通过该属性访问它。

      您似乎正在尝试实现继承,这是一个很好的阅读:Prototypal Inheritance in JavaScriptClassical Inheritance in JavaScript

      【讨论】:

      • 嘿,你是对的,我在这里尝试继承。感谢那些文章。我已经彻底阅读了这两本书,但我只是认为必须使用一个返回对象的函数而不在其创建中使用“new”是很难看的。在我看来,这只是有点难以理解。希望找到一种方法使使用“新”成为可能
      【解决方案3】:

      我怀疑您正在以类似于覆盖 undefined“值”的方式覆盖 prototype 属性。

      【讨论】:

        【解决方案4】:

        这里的问题是你返回一个名为 prototype 的属性,其值为 parent,它是一个对象,所以你返回一对 prototype = {name = 'keith'} 并且当你调用 new obj 时,你正在添加到原型a 一个名为 prototype 的新属性。

        你只需要一点改变,我需要这就是你想要做的。这会起作用,只是要小心重载属性。

        var obj = function(parent){
           for(var propt in parent){
              this[propt] = parent[propt];
           }
        }
        
        var me = { name: 'keith' };
        var a = new obj(me);
        console.log(a);
        // => Object { name="keith"}
        console.log(a.name);
        // => "keith"
        

        编辑:如果您正在寻找使用原型的继承,您应该read this 或尝试TypeScript,一个新的 javascript 类型和 OO 库

        【讨论】:

        • 这实际上只是将属性从一个对象克隆到另一个对象,而我最终希望能够使用“原型”,就像在经典语言中使用“超级”一样。这会起作用,但它不是完全继承:-)
        • 你没有提到继承。您指的是java 中的super 关键字对吗?
        【解决方案5】:

        您似乎用假的原型覆盖了真正的原型。

        【讨论】:

        • 他刚刚给obj.prototype添加了一个新属性,命名为prototype
        • 我认为 Rod 实际上是正确的,看起来我以某种方式取消了“原型”的内部链接,并将其替换为 JavaScript 未实现原型功能的属性。我认为可能是new关键字先初始化对象,然后然后用新值覆盖原型,不再在作用域链中
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-04-07
        • 2015-12-21
        • 2015-11-23
        • 2013-05-23
        • 2017-07-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多