【问题标题】:Javascript prototype and __proto__ and getPrototypeOf issueJavascript 原型和 __proto__ 和 getPrototypeOf 问题
【发布时间】:2011-05-24 15:40:21
【问题描述】:

我在 javascript 中有一个简单的类:

function foo() {
    this.bar = "bar";
}

var test = new foo;

console.log(foo.prototype,foo.__proto__)
/*output: foo {
               constructor: function foo() { 
               __proto__:   Object
              }
          ,
          function Empty() {}
*/
console.log(test,test.prototype,test.__proto__,test.__proto__.__proto__)
/*output: foo {
              bar: "bar"
              __proto__: foo
          }
          ,
          undefined
          ,
          foo {
              constructor: function foo() {
              __proto__: Object
          }
          ,
          Object {
              ...
          }
      */

我不明白的:

在第一个日志中,foo.prototype 具有 __proto__ 属性,这是一个 Object 在第二个日志中,test.__proto__ 具有 __proto__ 属性,这是一个 Object

什么时候用__proto__,什么时候用prototype,有什么区别?


更新:

instanceOf 部分的 John Resig's blog 中有一些我不明白的地方:

如果我使用 var asd = "asd";Object.getPrototypeOf(asd) 它会抛出 TypeError 但是
如果我使用var dsa = new String("dsa");Object.getPrototypeOf(dsa) 它返回String
但是 asd.constructor.prototype == dsa.constructor.prototypetrue

为什么Object.getPrototypeOf(asd) 会抛出错误?这是一个字符串,不是吗?

【问题讨论】:

    标签: javascript prototype-programming


    【解决方案1】:

    始终使用prototypeObject.getPrototypeOf

    __proto__ 是非标准的,已被Mozilla 弃用。

    John Resig 对此有很好的blog entry


    test.prototype 未定义的原因是因为您创建了一个没有构造函数原型的新对象。以下是何时使用Object.getPrototypeOf 的示例。

    js> function foo(){}
    js> typeof foo.prototype;
    object
    js> var f = new foo();
    js> typeof f.prototype;
    undefined
    js> typeof Object.isPrototypeOf(f);
    object
    js> typeof f.constructor.prototype;
    object
    js> foo.prototype === Object.getPrototypeOf(f);
    true
    js> foo.prototype === f.constructor.prototype;
    true
    

    如您所知,JavaScript 中的继承很棘手。让我们看一个例子:

    js> typeof "asdf";
    string
    js> typeof String("asdf");
    string
    

    字符串文字是字符串类型。将String() 作为函数调用时也是如此。现在,由于new 运算符的行为,一个新对象被创建,String() 的原型作为其父对象。

    js> var s = new String("asdf");
    js> typeof s;
    object
    

    因为 JS 喜欢强制,你可以通过以下几种方式获取字符串字面量:

    js> s
    asdf
    js> s.valueOf();
    asdf
    js> typeof s
    object
    js> typeof s.valueOf();
    string
    

    Crockford 的Prototypal Inheritance in JavaScript 在学习 JS 继承时帮助了我很多。

    来自 Mozilla 的 Strings 页面:

    字符串对象可以由 调用构造函数 new String()。 String 对象包装了 JavaScript 的 字符串原始数据类型与 下面介绍的方法。全球 函数 String() 也可以调用 没有新的在前面创建一个 原始字符串。中的字符串文字 JavaScript 是原始字符串。

    【讨论】:

    • 但是正如你看到的第二个日志,test.prototype ==undefined
    • 我用示例 repl 输出修改了我的答案。
    • 感谢这个非常好的例子。现在我什么都明白了。
    • 我更新了我的问题。约翰的博客中有一些我不明白的地方
    • 哪里有 Object.isPrototypeOf(f),我想你想要 Object.getPrototypeOf
    【解决方案2】:

    __proto__ 是对象与其原型之间的中间对象。使用它的最大好处是您可以完全更改对象的原型链,而无需修改实例或原型。

    例子:

    function F() {} 
    F.prototype.a = 1;
    var f = new F();
    f.__proto__ = { b : 2 }; 
    "a" in f => false; 
    "b" in f => true;
    

    但正如 Jeremy 所说,__proto__ 已被弃用。唯一的用例是,如果您想向对象添加一组属性,更改其原型而无需遍历每个属性。没什么大不了的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-05-23
      • 1970-01-01
      • 2012-04-15
      • 1970-01-01
      • 2015-09-29
      • 2011-08-25
      相关资源
      最近更新 更多