使用Object.create进行继承的好处
我一直在努力解决Object.create
ECMAScript 5中引入的新方法。
通常,当我想使用继承时,我会执行以下操作:
var Animal = function(name) { this.name = name; }Animal.prototype.print = function() { console.log(this.name); }
var Dog = function()
{
return Animal.call(this, 'Dog');
}
Dog.prototype = new Animal();
Dog.prototype.bark = function() { console.log('bark'); }
我只是将一个新创建的Animal对象分配给Dog的原型,一切都像一个吊饰一样工作:
var dog1 = new Dog();dog1.print(); // prints 'Dog'
dog1.bark(); // prints 'bark'
dog1.name; //prints 'Dog'
但是人们(没有解释)说这Dog.prototype = new Animal();
不是继承的工作方式,我应该使用Object.create方法:
Dog.prototype = Object.create(Animal.prototype);
这也有效。
使用有什么好处,Object.create
或者我错过了什么?
回答:
在下面的内容中,我假设您仅对为什么Object.create
设置继承更好的原因感兴趣。
为了了解其好处,首先让我们澄清一下JavaScript中“类”的组成。您分为两个部分:
该 函数。该函数包含创建“类”实例(即实例特定代码)的所有逻辑。
该 对象。这是实例继承的对象。它包含应在所有实例之间共享的所有方法(和其他属性)。
建立了一个 is-a的 关系,例如,一个Dog
是 一个Animal
。这如何用构造函数和原型对象表达?
显然,狗必须有相同的方法作为一种动物,那就是Dog
原型 对象必须以某种方式合并从方法的Animal
原型
对象。有多种方法可以做到这一点。您会经常看到以下内容:
Dog.prototype = new Animal();
这是有效的,因为Animal
实例是 从Animal
原型 对象继承的。 也意味着每只狗都从 一个 特定的Animal
实例 继承。这似乎有点奇怪。实例特定的代码不应该仅在 构造 函数中运行吗?突然, 实例 特定的代码和 原型 方法似乎混杂在一起。
那时候我们实际上并不想要运行Animal
实例 特定的代码,我们只希望Animal
原型
对象中的所有方法。那就是Object.create
我们要做的:
Dog.prototype = Object.create(Animal.prototype);
在这里,我们 没有 创建新Animal
实例,仅获得了原型方法。该 实例 特定代码究竟执行的地方应该是,在构造函数中:
function Dog() { Animal.call(this, 'Dog');
}
最大的优点是Object.create
将 始终 有效。使用new
Animal()仅在构造函数不期待任何变量工作。想象一下,如果构造函数看起来像这样:
function Animal(name) { this.name = name.toLowerCase();
}
您始终必须将字符串传递给Animal
,否则会出现错误。当您这样做时,您会通过什么Dog.prototype = new
Animal(??);?传递哪个字符串实际上并不重要,只要传递 某些东西 ,就可以告诉您这是不好的设计。
有人说也
Dog.prototype = Animal.prototype;
可以。所以现在我很困惑
一切,补充说:“”从属性Animal.prototype
到Dog.prototype
意志的“工作”。但是解决方案的质量不同。在这种情况下,您将遇到一个问题,即您添加到的任何方法Dog.prototype
也将被添加到中Animal.prototype
。
例:
Dog.prototype.bark = function() { alert('bark');
};
由于Dog.prototype === Animal.prototype
,所有Animal
实例bark
现在都有一个方法,这当然不是您想要的。
Object.create
(甚至new
Animal)通过创建一个新对象来向继承添加一个间接级别,该新对象继承自Animal.prototype
该对象,并且该新对象成为Dog.prototype
。
ES6引入了一种新语法来创建构造函数和原型方法,如下所示:
class Dog extends Animal { bark() {
alert('bark');
}
}
这比我上面解释的要方便,但是事实证明,它extends
也使用内部等效项Object.create
来建立继承。请参阅ES6草案中的步骤2和3 。
这意味着使用Object.create(SuperClass.prototype)
是ES5中的“更正确”方法。
以上是 使用Object.create进行继承的好处 的全部内容, 来源链接: utcz.com/qa/431663.html