Javascript prototype and __proto__ and getPrototypeOf issue

独自空忆成欢 提交于 2020-01-24 07:38:42

问题


I have a simple class in 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 {
              ...
          }
      */

What i dont understand:

At the first log the foo.prototype had the __proto__ attribute which was an Object At the second log the test.__proto__ had the __proto__ attribute which was an Object

When to use __proto__ and when prototype, what is the difference?


UPDATE:

In John Resig's blog in the instanceOf section there is something waht I don't understand:

If i use var asd = "asd";Object.getPrototypeOf(asd) it throws a TypeError but
If i use var dsa = new String("dsa");Object.getPrototypeOf(dsa) it returns String
But asd.constructor.prototype == dsa.constructor.prototype is true

Why is the Object.getPrototypeOf(asd) throws error? This is a string, isn't it?


回答1:


Always use prototype or Object.getPrototypeOf.

__proto__ is non-standard and has been deprecated by Mozilla.

John Resig has a good blog entry about it.


The reason why test.prototype is undefined is because you created a new object that does not have a constructor prototype. Here's an example of when to use 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

As you can tell, inheritance in JavaScript is tricky. Lets look at an example:

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

The string literal is of type string. The same is true when calling String() as a function. Now, because of behavior of the new operator, a new object is created, with the prototype of String() as its parent.

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

Because JS likes to coerce things, you can get at the string literal a few ways:

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

Prototypal Inheritance in JavaScript by Crockford helped me a lot when learning about JS inheritance.

From Mozilla's Strings page:

String objects may be created by calling the constructor new String(). The String object wraps JavaScript's string primitive data type with the methods described below. The global function String() can also be called without new in front to create a primitive string. String literals in JavaScript are primitive strings.




回答2:


__proto__ is an intermediary object between an object and it's prototype. The biggest benefit in using it is that you can change the prototype chain for an object entirely without modifying the instance or the prototype.

Example:

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

But as Jeremy said, __proto__ is deprecated. The only use case would be if you would like to add a set of properties to an object, changing its prototype without having to iterate through each one. Not a big deal.



来源:https://stackoverflow.com/questions/6113040/javascript-prototype-and-proto-and-getprototypeof-issue

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!