zoukankan      html  css  js  c++  java
  • javascript prototype __proto__区别

    An Object's __proto__ property references the same object as its internal [[Prototype]] (often referred to as "the prototype"), which may be an object or, as in the default case of Object.prototype.__proto__, null . This property is an abstraction error, because a property with the same name, but some other value, could be defined on the object too. If there is a need to reference an object's prototype, the preferred method is to use Object.getPrototypeOf.

    __proto__ pseudo property has been included in §B.3.1 of the draft ECMAScript ed. 6 specification (note that the specification codifies what is already in implementations and what websites may currently rely on).

    var proto = obj.__proto__;

    一个对象的__proto__ 属性和自己的内部属性[[Prototype]]指向一个相同的值 (通常称这个值为原型),原型的值可以是一个对象值也可以是null(比如说Object.prototype.__proto__的值就是null).该属性可能会引发一些错误,因为用户可能会不知道该属性的特殊性,而给它赋值,从而改变了这个对象的原型. 如果需要访问一个对象的原型,应该使用方法Object.getPrototypeOf.

    __proto__ 属性已经被添加在了ES6草案 §B.3.1中.

    不要认为__proto__和prototype相等。

    Description

    When an object is created, it__proto__ property is set to reference the same object as its internal [[Prototype]] (i.e. its constructor's prototype object).  Assigning a new value to __proto__ also changes the value of the internal [[Prototype]] property, except where the object is non–extensible.

    To understand how prototypes are used for inheritance, see the MDN article Inheritance and the prototype chain.

    一个对象被创建时,它的 __proto__ 属性和内部属性[[Prototype]]指向了相同的对象 (也就是它的构造函数的prototype属性).改变__proto__ 属性的值同时也会改变内部属性[[Prototype]]的值,除非该对象是不可扩展的.

    想要知道如何使用原型来实现继承,查看MDN文章继承和原型链.

    Example

    In the following, a new instance of Employee is created, then tested to show that its __proto__ is the same object as its constructor's prototype.

    // 声明一个函数作为构造函数function Employee() {
      /* 初始化实例 */
    }
    
    // 创建一个Employee实例
    var fred = new Employee();
    
    // 测试相等性
    fred.__proto__ === Employee.prototype; // true

    这是, fred 继承了 Employee, 但是如果给fred.__proto__ 赋另外一个对象值,则会改变它的继承对象:

    // Assign a new object to __proto__
    fred.__proto__ = Object.prototype;

    现在,fred不在继承于Employee.prototype, 而是直接继承了Object.prototype, 也就丢失了所有从Employee.prototype继承来的属性.

    可是,这只适用于可扩展的 对象,一个不可扩展的对象的 __proto__ 属性是不可变的:

     
    var obj = {};
    Object.preventExtensions(obj);
    
    obj.__proto__ = {}; // throws a TypeError

    Note that even Object.prototype's __proto__ property can be redefined as long as the chain leads to null:

    var b = {};
    
    Object.prototype.__proto__ = {
        hi: function () {alert('hi');},
        __proto__: null
    };
    
     
    b.hi();

    If Object.prototype's __proto__ had not been set to null, or had not been set to another object whose prototype chain did not eventually lead explicitly to null, a "cyclic __proto__ value" TypeError would result since the chain must eventually lead to null (as it normally does on Object.prototype).

    参考:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto

    上面的

    bject.prototype.__proto__不能改成
    bject.prototype.prototype.
    为什么?
    我们可以:

    function func(){};
    alert(typeof Object.prototype);//Object,不是Function
    alert(typeof func); //Function。

    可以看出Object.prototype是一个object,没有prototype属性.alert( Object.prototype.prototype);显示undefined。

     (从这里我们可以看出Object 是 一个function,typeof Object 为function。)

    prototype is a property of a Function object. It is the prototype of objects constructed by that function.

    只有函数才有prototype属性,对象没有。

    我们可以看stackoverflow上的一个问题:

    This figure again shows that every object has a prototype. Constructor function Foo also has its own__proto__ which is Function.prototype, and which in turn also references via its __proto__property again to the Object.prototype. Thus, repeat, Foo.prototype is just an explicit property of Foo which refers to the prototype of b and c objects.

    var b =new Foo(20);var c =new Foo(30);

    What are the __proto__ and the prototype properties?

    (要仔细理解这幅图 typeof Object=='function' 为true,说明Object类型为function。

     Foo.prototype.__proto__ === Object.prototype 为true。

     (个人理解:上面的b->Foo.prototype-->Object.prototype组成了一条链,但b没有在自己中找到相应的属性和方法时,就会向上去寻找 。我们可以这么理解,继承与prototype无关,而与__proto__有关。?我们在这里简单地说下。每个对象都会在其内部初始化一个属性,就是__proto__,当我们访问一个对象的属性时,如果这个对象内部不存在这个属性,那么他就会去__proto__里找这个属性,这个__proto__又会有自己的__proto__,于是就这样一直找下去,也就是我们平时所说的原型链的概念。

    参考:http://www.cnblogs.com/youxin/archive/2013/03/08/2950751.html

    可以看到,Function.prototype是函数Foo的__proto__。我们只要在Function.prototype增加了一个方法,所有的函数都可以调用这个方法,如《javascript精粹》中的一个例子:

    Function.prototype.method=function(name,func){
        if(!this.prototype[name]){
            this.prototype[name]=func;
        }
        return this;
    };
     Foo.method("say2",function(){alert("say2");});
    //和上面的话作用一样:Foo.prototype.say2=function(){alert("say2");};
    
    var c=new Foo();
    c.say2();

    下面的这段代码是我编的。

    function Foo(){}
    var b=new Foo();
    alert(Foo.prototype==Foo.__proto__); //false
    alert( Foo.__proto__); //function Empty(){}
    alert(Foo.prototype); //[object object]

    alert(Foo.prototype.constructor); //function Foo(){}

    与上图对应的代码:

    // a constructor function
    function Foo(y) {
      // which may create objects
      // by specified pattern: they have after
      // creation own "y" property
      this.y = y;
    }
     
    // also "Foo.prototype" stores reference
    // to the prototype of newly created objects,
    // so we may use it to define shared/inherited
    // properties or methods, so the same as in
    // previous example we have:
     
    // inherited property "x"
    Foo.prototype.x = 10;
     
    // and inherited method "calculate"
    Foo.prototype.calculate = function (z) {
      return this.x + this.y + z;
    };
     
    // now create our "b" and "c"
    // objects using "pattern" Foo
    var b = new Foo(20);
    var c = new Foo(30);
     
    // call the inherited method
    b.calculate(30); // 60
    c.calculate(40); // 80
     
    // let's show that we reference
    // properties we expect
     
    console.log(
     
      b.__proto__ === Foo.prototype, // true
      c.__proto__ === Foo.prototype, // true
     
      // also "Foo.prototype" automatically creates
      // a special property "constructor", which is a
      // reference to the constructor function itself;
      // instances "b" and "c" may found it via
      // delegation and use to check their constructor
     
      b.constructor === Foo, // true
      c.constructor === Foo, // true
      Foo.prototype.constructor === Foo // true
     
      b.calculate === b.__proto__.calculate, // true
      b.__proto__.calculate === Foo.prototype.calculate // true
     
    );

    具体参考:http://dmitrysoshnikov.com/ecmascript/javascript-the-core/

    答案1:

    __proto__ is internal property of an object, pointing to its prototype. Current standards provide an equivalent Object.getPrototypeOf(O) method, though de facto standard __proto__ is quicker.

    You can find instanceof relationships by comparing a function's prototype to an object's__proto__ chain, and you can break these relationships by changing prototype.

    
    
    function Point(x, y) {
        this.x = x;
        this.y = y;
    }
    
    var myPoint = new Point();
    
    // the following are all true
    myPoint.__proto__ == Point.prototype
    myPoint.__proto__.__proto__ == Object.prototype
    myPoint instanceof Point;
    myPoint instanceof Object;
    
    

    Here Point is a constructor function, it builds an object (data structure) procedurally. myPoint is an object constructed by Point() so Point.prototype gets saved to myPoint.__proto__ at that time.

    答案2:

    __proto__ is the actual object that is used in the lookup chain to resolve methods, etc. prototype is the object that is used to build __proto__ when you create an object with new:

    (new Foo).__proto__ ===Foo.prototype
    (newFoo).prototype ===undefined
    转自:http://stackoverflow.com/questions/9959727/what-is-the-difference-between-proto-and-prototype-in-javascript
     看以前写的:

    Javascript原型链和原型的一个误区

     
  • 相关阅读:
    Java如何重置正则表达式的模式?
    Java如何创建用户自定义异常?
    Java如何使用线程异常?
    Java如何打印异常的堆栈?
    Java数组超出范围时如何处理多个异常?
    Java如何处理已检查异常?
    Java如何使用重载方法处理异常?
    Java如何使用catch来处理异常?
    Java如何处理空堆栈异常?
    Java如何处理运行时异常?
  • 原文地址:https://www.cnblogs.com/youxin/p/3219175.html
Copyright © 2011-2022 走看看