2013-04-18 45 views
3

我有一个问题要问你我们真的必须改为Object.create吗?

据我所知,new运营商以这种方式工作

function fakeNew(Ctor) { 
    var instance = Object.create(Ctor.prototype); 
    instance.constructor(); 
    // I skip the conditional for simplicity 
    return instance; 
} 

这一切开始的时候我做了一个Object.create polifill这样我就可以不使用new创建对象。

Object.create = function(proto) { 
    function F() { } 
    F.prototype = proto; 
    return new F(); 
} 

我开始创建大量objcts和prototiping他们,但很多次话,需要initializa其属性我做了一个.init()方法把它们

var base = { 
    init: function() { 
    EmitterMixin.call(this); 
    return this; 
    } 
}; 

var obj = Object.create(base).init(); 

但当然,我不得不rembember返回this总是从.init()多次我忘记它或最差,我忘了拨.init()。所以试图简化对象初始化,我想创建一个全局帮助器来执行它:调用Object.create,调用初始化函数并返回它。

function create(proto) { 
    var child = Object.create(proto); 
    child.init(); 
    return child; 
} 

当时,当我想打我的头靠在墙上,当我意识到我在做什么几乎被什么new符不,但慢了很多。而如果polifill适用,我甚至会使用new

所以我问自己,扔什么好处new?它在主要浏览器上为notably quicker,并且由于JavaScript的性质,我们通常需要调用一个启动器函数,而不是new开始启动。

而且最糟糕的,我发现比我用了两个不同类型的对象的,“抽象”和“实例”,更大的区别是比情况下,我不得不调用.init(),同时附有摘要它不是necesasary因为他们只会被用作其他物体的原型。我已经看到了在使用new这个模式:

function Foo() { } 
Foo.prototype.method = function() { ... }; 

function Bar() { } 
// "abstract" doesnt invoke initializer 
Bar.prototype = Object.create(Foo.prototype); 
Bar.prototype.other = function() { ... }; 

// "instance", the constructor is called as initializer 
var obj = new Bar(); 

是否真的有益处,如果我们再看到new?我们确定它不是一个更高级别的工具,而是简化我们必须做的事情吗? 你看到newObject.create有什么优点/缺点?

+0

Main [反对'new'的参数](http:// stackoverflow.com/questions/383402/is-javascript-s-new-keyword-considered-harmful)是“被遗忘时会造成多大的伤害”,以及“基于类的继承太多” – Bergi

回答

1

我已经尝试了两种方法,并且我个人没有看到使用new的传统方法的任何问题。 Object.create的主要参数是它使原型继承更清晰 - 您不必了解函数构造函数的prototype属性的复杂性以及它如何与对象的实际原型相关。但它确实要求初始化是一个单独的步骤。

我的首选方法是结合两种方法,例如,:

function Animal(name) { 
    this.name = name || null; 
} 
Animal.prototype.eat = function() { 
    console.log('yum'); 
} 

function Cat(name) { 
    Animal.call(this, name); 
} 
Cat.prototype = Object.create(Animal.prototype); 
Cat.prototype.constructor = Cat; 

Cat.prototype.meow = function() { 
    console.log('meow'); 
} 

var garfield = new Cat('garfield'); 
garfield.eat(); 
garfield.meow(); 

Object.create是继承更好地在这里比Cat.prototype = new Animal()有两个原因:

  1. 如果你想要求name参数(投掷如果没有通过它的一个例外),你可以这样做和继承(Cat.prototype = Object.create(Animal.prototype))仍然有效。
  2. 如果您忘记从Animal构造函数中调用Cat的构造函数,那么Animal构造函数创建的所有属性都将被定义为undefined,从而使您能够快速发现错误。

虽然这种方法(使用构造函数和new)小于“纯粹”的原型,它仍然是原型继承并且只要你知道如何使用它正确的它工作得很好,需要多一点的打字少Object.create方法。

我在我的Javascript OO库文档simpleoo的文档中写了一些关于此的其他说明。 (注意:我可能会很快为该库更改API;我正在链接到它,主要是因为文档更详细地讨论了其中一些概念。)

相关问题