如何通过clone()实现对象继承?

时间:2013-07-13 09:09:37

标签: javascript

我正在How ECMAScript 5 still does not allow to subclass an array阅读kangax的博客。在这里,他使用了与正常原型构造

不同的子类化方法
BaseClass.prototype = new Superclass();

他正在做的是:

function clone(obj) {
  function F() { }
  F.prototype = obj;
  return new F();
}
  

然后像这样设置继承:

function Child() { }
Child.prototype = clone(Parent.prototype);

有人可以解释这两部分的继承方法,以及它对上述简单的单线方法有什么好处?

修改:我从评论中了解到,现在有一个标准Object.create()基本上解决了与clone()方法相同的目的,但clone()的实施方式如何运作?

2 个答案:

答案 0 :(得分:0)

这是一个有趣的问题。你给出的那段代码(克隆功能)被Douglas Crockford称为“原型继承”,并描述in this article on his website.这种模式变得流行并在ECMA script 5 into Object.create(), if you look at specification of object create中形式化,它与Crockford函数的规范。 它的使用方式如下:

var Animal = {
    species: "mammal",
    noises: function () {
        console.log("makes noises")
    },
    actions: ["roll back", "jump up"]
}

var Cat = Object.create(Animal);
Cat.name = "blacky"
Cat.miau = function () {
    console.log("miau miau");
}

Crockford也称这种差异继承,因为在定义子类的新属性时,您只需指定子类和超类之间的差异。猫现在有自己的属性“名称”和自己的方法“miau”。

我认为这个问题的主要问题是你仍然在实例之间共享参数值,例如数组。

如果我们这样做:

var Cat2 = Object.create(Animal);
Cat2.actions.push("bite Henry");
Cat2.actions
["roll back", "jump up", "bite Henry"]
Cat.actions
["roll back", "jump up", "bite Henry"]

但至少不共享实例原始属性,这很好。

Cat2.name
undefined
Cat.name
"blacky"

答案 1 :(得分:0)

要说明为什么要使用Object.create或辅助函数来设置继承原型,请参阅以下代码:

function Hamster(name){
  if(name ===  undefined){
    throw new Exception("Name cannot be undefined");
  }
  this.name=name;
};

function RussionMini=function(name){
  Hamster.apply(this,arguments);
};
RussionMini.prototype=new Hamster();//throws Error

您可以执行RussionMini.prototpe=new Hamster("dummyvalue");,但是如果需要传递的值在声明对象(如DOM元素)时不可用,那该怎么办呢?您仍然可以传递一个虚拟对象,但它会使您的代码在重构时更复杂,更容易破解。

两个示例都不修复prototype.constructor,因此this.constructor将指向错误的函数(当您使用Object.create(Parent.prototype)时也会发生;`

有关继承的更多信息,可以在此处找到使用构造函数的覆盖函数和原型:Prototypical inheritance - writing up