Javascript原型和__proto__以及getPrototypeOf问题

时间:2011-05-24 15:40:22

标签: javascript prototype-programming

我在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的{​​{1}}属性为__proto__ 在第二个日志中,Object的{​​{1}}属性为test.__proto__

何时使用__proto__和何时Object,有什么区别?


更新

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

如果我使用__proto__ Object.getPrototypeOf prototype,则会引发var asd = "asd";但是 如果我使用(asd) Object.getPrototypeOf TypeError,则返回var dsa = new String("dsa");
(dsa) String

为什么Object.getPrototypeOf asd.constructor.prototype == dsa.constructor.prototype会引发错误?这是一个字符串,不是吗?

2 个答案:

答案 0 :(得分:6)

始终使用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
在学习JS继承时,Crockford的

Prototypal Inheritance in JavaScript给了我很多帮助。

来自Mozilla的Strings页面:

  

可以通过创建字符串对象   调用构造函数new String()。   String对象包装了JavaScript   字符串原始数据类型   方法如下所述。全球   函数String()也可以被调用   没有新的前面创造一个   原始字符串。字符串文字   JavaScript是原始字符串。

答案 1 :(得分:5)

__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__已被弃用。唯一的用例是,如果您想为对象添加一组属性,更改其原型而不必遍历每个属性。没什么大不了的。