JavaScript继承:Object.create vs new

Chr*_*ich 120 javascript inheritance object-create

在JavaScript中,这两个示例之间的区别是什么:

先决条件:

function SomeBaseClass(){
}

SomeBaseClass.prototype = {
    doThis : function(){
    },

    doThat : function(){
    }
}
Run Code Online (Sandbox Code Playgroud)

继承示例A使用Object.create:

function MyClass(){
}

MyClass.prototype = Object.create(SomeBaseClass.prototype);
Run Code Online (Sandbox Code Playgroud)

继承示例B使用new关键字

function MyClass(){
}

MyClass.prototype = new SomeBaseClass();
Run Code Online (Sandbox Code Playgroud)

这两个例子似乎做同样的事情.你什么时候选择一个而不是另一个?

另一个问题:考虑下面链接中的代码(第15行),其中对函数自身构造函数的引用存储在原型中.为什么这有用?

https://github.com/mrdoob/three.js/blob/master/src/loaders/ImageLoader.js

摘录(如果您不想打开链接):

THREE.ImageLoader.prototype = {

    constructor: THREE.ImageLoader
}
Run Code Online (Sandbox Code Playgroud)

The*_*pha 110

在你提出的问题中,你提到过Both examples seem to do the same thing,这根本不是真的,因为

你的第一个例子

function SomeBaseClass(){...}
SomeBaseClass.prototype = {
    doThis : function(){...},
    doThat : function(){...}
}
function MyClass(){...}
MyClass.prototype = Object.create(SomeBaseClass.prototype);
Run Code Online (Sandbox Code Playgroud)

在这个例子中,你只是继承SomeBaseClass' prototype,但如果你在你有一个属性SomeBaseClass

function SomeBaseClass(){ 
    this.publicProperty='SomeValue'; 
}
Run Code Online (Sandbox Code Playgroud)

如果你喜欢它

var obj=new MyClass();
console.log(obj.publicProperty); // undefined
?console.log(obj);?
Run Code Online (Sandbox Code Playgroud)

obj对象不具有此示例中的publicProperty属性.

你的第二个例子

MyClass.prototype = new SomeBaseClass();
Run Code Online (Sandbox Code Playgroud)

它正在执行该constructor函数,创建SomeBaseClass并继承整个SomeBaseClass对象的实例.所以,如果你使用

    var obj=new MyClass();
    console.log(obj.publicProperty); // SomeValue
    console.log(obj);?
Run Code Online (Sandbox Code Playgroud)

在这种情况下,其publicProperty属性也可用于此obj对象,如此示例中所示.

由于Object.create在某些旧浏览器中不可用,在这种情况下您可以使用

if(!Object.create)
{
    Object.create=function(o){
        function F(){}
        F.prototype=o;
        return new F();
    }
}
Run Code Online (Sandbox Code Playgroud)

上面的代码只是增加了Object.create函数,如果它不可用,所以你可以使用Object.create函数,我认为上面的代码描述了Object.create实际的功能.希望它在某种程度上有所帮助.

  • 嗨谢赫.感谢您为此付出的努力.是的,不同之处在于构造函数是在第二个示例中运行的,而不是在第一个示例中运行的.(这在我的情况下是可取的).关于未从超级实现继承的未定义公共属性,您只需要在子构造函数中调用super:SomeBaseClass.call(this).检查这个小提琴:http://jsfiddle.net/NhQGB/ (6认同)

Ber*_*rgi 39

这两个例子似乎做同样的事情.

在你的情况下这是真的.

你什么时候选择一个而不是另一个?

SomeBaseClass有一个函数体时,这将使用new关键字执行.这通常不是意图 - 您只想设置原型链.在某些情况下,它甚至可能导致严重问题,因为您实际实例化了一个对象,其私有范围变量由所有MyClass实例共享,因为它们继承了相同的特权方法.其他副作用是可以想象的.

所以,你应该更喜欢Object.create.然而,某些传统浏览器不支持它; 这就是你看到new-approach太频繁的原因,因为它往往没有(明显的)伤害.还看看这个答案.


jAn*_*ndy 8

如果您Object.create()按预期使用,差异就会变得明显.实际上,它完全隐藏了prototype你的代码中的单词,它将完成工作.使用Object.create(),我们可以去

var base =  {
    doThis : function(){
    },

    doThat : function(){
    }
};
Run Code Online (Sandbox Code Playgroud)

然后我们可以从中扩展/继承其他对象

var myObject = Object.create( base );
// myObject will now link to "base" via the prototype chain internally
Run Code Online (Sandbox Code Playgroud)

所以这是另一个概念,一种更"面向对象"的方式.例如,没有开箱即用的"构造函数" Object.create().但是当然你可以在这些对象中创建并调用自定义的构造函数.

使用一个论据Object.create()是,它可能看起来更自然,以混合/**继承其他对象,不是使用Javascript角默认的方式.

  • 当需要构造函数时,`Object.create`不能真正用`new`替换经典方法 (7认同)

归档时间:

查看次数:

42461 次

最近记录:

9 年,2 月 前