Javascript原型和__proto__以及getPrototypeOf问题

Ger*_*ári 4 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 {
              ...
          }
      */
Run Code Online (Sandbox Code Playgroud)

我不明白的是:

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

何时使用__proto__prototype什么时候有什么区别?


更新:

John Resig的 instanceOf部分的博客中,有一些我不明白的东西:

如果我使用它抛出一个,但 如果我使用它返回不过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)

Jer*_*emy 6

总是使用prototypeObject.getPrototypeOf.

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

John Resig有一篇很好的博客文章.


之所以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
Run Code Online (Sandbox Code Playgroud)

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

js> typeof "asdf";
string
js> typeof String("asdf");
string
Run Code Online (Sandbox Code Playgroud)

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

js> var s = new String("asdf");
js> typeof s;
object
Run Code Online (Sandbox Code Playgroud)

因为JS喜欢强迫事物,你可以通过以下几种方式获得字符串文字:

js> s
asdf
js> s.valueOf();
asdf
js> typeof s
object
js> typeof s.valueOf();
string
Run Code Online (Sandbox Code Playgroud)

在学习JS继承时,Crockford 在JavaScript中Prototypal继承帮助了我很多.

从Mozilla的Strings页面:

可以通过调用构造函数new String()来创建String对象.String对象使用下面描述的方法包装JavaScript的字符串原始数据类型.也可以在没有new的情况下调用全局函数String()来创建原始字符串.JavaScript中的字符串文字是原始字符串.


Ada*_*ark 5

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

例:

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

但正如杰里米所说,__proto__已被弃用.唯一的用例是,如果您想为对象添加一组属性,更改其原型而不必遍历每个属性.没有大碍.