什么已经取代了JavaScript中已弃用的__proto__

McS*_*man 2 javascript prototype

我试图找出如何从另一个实例化的对象实例化一个新对象,而无需使用new运算符.以下代码有效,但我听说__proto__属性已折旧.

var MyObject = function( arg ) {

    this.value = arg;

};

MyObject.prototype.getValue = function() {

    return this.value;

};

// Standard way of instantiating an object
var object1 = new MyObject( 'foo' );

// Creating new object based on another without using new operator
var object2 = {};
object2.__proto__ = object1.__proto__
object1.constructor.call( object2, 'bar' );

console.log( object1 );
console.log( object2 );
Run Code Online (Sandbox Code Playgroud)

那么如果没有__proto__属性我该如何做呢?

the*_*eye 7

引自__proto__MDN文档,

__proto__属性已弃用,不应使用.Object.getPrototypeOf应该使用而不是__proto__getter来确定对象的[[Prototype]].强烈建议不要改变对象的[[Prototype]],无论如何实现,因为它非常慢并且不可避免地减慢了现代JavaScript实现中后续执行的速度.但是,Object.setPrototypeOf在ES6中提供了作为__proto__设定器的非常优选的替代方案.

但是你的实际代码是有效的,让我们看看为什么.

  1. 首先,使用Object文字创建的任何对象都将具有与之__proto__相同的属性Object.prototype.你可以这样检查一下

    var object2 = {};
    console.log(object2.__proto__ === Object.prototype);
    # true
    
    Run Code Online (Sandbox Code Playgroud)
  2. 由于object1是使用MyObject函数创建的,因此以下是正确的

    console.log(object1.__proto__ === MyObject.prototype);
    # true
    
    Run Code Online (Sandbox Code Playgroud)
  3. 当你说

    object2.__proto__ = object1.__proto__;
    
    Run Code Online (Sandbox Code Playgroud)

    从2开始,我们可以看到它是一样的,

    object2.__proto__ = MyObject.prototype;
    
    Run Code Online (Sandbox Code Playgroud)

    所以,你只是让JavaScript相信,object2也是一个对象MyObject.

  4. 由于我们将MyObject原型分配给object1原型,因此constructor两个对象都是相同的

    console.log(object1.constructor === object2.constructor);
    
    Run Code Online (Sandbox Code Playgroud)
  5. 然后你MyObjectobject2as 调用函数this.

    object1.constructor.call( object2, 'bar' );
    
    Run Code Online (Sandbox Code Playgroud)

由于__proto__不建议更改,因此最好的方法是new仅使用关键字

var object1 = new MyObject('foo'),
    object2 = new MyObject('bar');
Run Code Online (Sandbox Code Playgroud)

但是,让我们说你只有object1,但不是定义MyObject.然后,您可以使用这样的constructor属性

object2 = new object1.constructor('bar');
Run Code Online (Sandbox Code Playgroud)