[英]Multiple prototypical inheritance in Javascript
我有2个基类,比如ParentClass1
和ParentClass2
。 现在,我想对ChildClass
进行多个原型继承。
在一个父类的情况下 ,我的代码如下。
var ParentClass = function() { }; ParentClass.prototype.greetUser = function(name) { console.log('Hi. Hello,', name); }; var ChildClass = function(name) { this.greetUser(name); }; ChildClass.prototype = Object.create(ParentClass.prototype); var obj = new ChildClass('John'); // Hi. Hello, John
现在,当我必须从2个父类继承时,我尝试了以下代码。
var ParentClass1 = function() { }; ParentClass1.prototype.greetUser = function(name) { console.log('Hi. Hello,', name); }; var ParentClass2 = function() { }; ParentClass2.prototype.askUser = function(name) { console.log('Hey, how are you,', name); }; var ChildClass = function(name) { this.askUser(name); this.greetUser(name); }; ChildClass.prototype = Object.create(ParentClass1.prototype); ChildClass.prototype = Object.create(ParentClass2.prototype); var obj = new ChildClass('John'); // Error.
但这似乎只接受最后提到的Object.create()
。
因此,稍后,它尝试将第二个Object.create()
切换为Object.assign()
,然后工作正常。
ChildClass.prototype = Object.create(ParentClass1.prototype);
ChildClass.prototype = Object.assign(ChildClass.prototype, ParentClass2.prototype);
但我担心的是Object.assign()
正在进行克隆 。 那是正确的方法吗? 还是有更好的选择?
很抱歉提出这个问题,冗长。 提前致谢。
对prototype
属性进行两次分配不是很有用,因为最后一个会覆盖第一个。 您可以这样做,因为Object.assign
接受更多参数:
Object.assign(ChildClass.prototype, ParentClass1.prototype, ParentClass2.prototype);
请注意, Object.assign
执行浅表副本。 必须确保必须进行复制:您需要一个与两个其他原型都不同的原型对象:两者的并集。 因此,您不可避免地需要以某种方式将父原型的成员复制到目标原型对象中。
Object.assign
进行浅表复制 由于Object.assign
执行浅表复制,因此您可能会遇到干扰父原型的情况。 这可能是您想要或不想要的。
例:
var ParentClass1 = function() { }; ParentClass1.prototype.userList = []; ParentClass1.prototype.addUser = function(name) { this.userList.push(name); }; var ParentClass2 = function() { }; ParentClass2.prototype.askUser = function(name) { console.log('Hey, how are you,', name); }; var ChildClass = function(name) { this.askUser(name); }; Object.assign(ChildClass.prototype, ParentClass1.prototype, ParentClass2.prototype); var p = new ParentClass1('Parent'); var obj = new ChildClass('John'); obj.addUser('Tim'); // Added to child, but console.log(p.userList); // now parent also has Tim...
Object.assign
仅复制可枚举的属性 这意味着在某些情况下,您将无法获得想要的属性。 假设您还想从Array.prototype
继承,那么您希望子对象具有length
属性,但是由于它不可枚举,因此无法通过Object.assign
获得它:
var ParentClass2 = function() { }; ParentClass2.prototype.askUser = function(name) { console.log('Hey, how are you,', name); }; var ChildClass = function(name) { this.askUser(name); }; Object.assign(ChildClass.prototype, Array.prototype, ParentClass2.prototype); var obj = new ChildClass('John'); console.log(obj.length); // undefined console.log(Array.prototype.length); // 0
Object.assign
执行吸气剂 Object.assign
无法复制吸气剂。 而是执行它们以检索副本的值。 在父原型上执行代码可能会对父原型的状态产生影响(通过该吸气剂的设计)。 在此副本的上下文中,这可能是不良行为。
其次,getter的值可以是对象的某种计算和状态的结果,每次引用该对象时都会返回不同的值。 但是object.assign
将仅引用一次,然后创建一个始终具有该单个值的属性。 在此示例中查看效果:
var ParentClass1 = function() { }; // Define a getter on the prototype which returns a // random number between 0 and 999, every time it is referenced: Object.defineProperty(ParentClass1.prototype, 'randomNumber', { get: function() { return Math.round(Math.random() * 1000); }, enumerable: true }); var ParentClass2 = function() {}; ParentClass2.prototype.askUser = function(name) { console.log('Hey, how are you,', name); }; var ChildClass = function(name) { this.askUser(name); }; Object.assign(ChildClass.prototype, ParentClass1.prototype, ParentClass2.prototype); var p = new ParentClass1('Parent'); var obj = new ChildClass('John'); console.log('different:'); console.log(p.randomNumber); console.log(p.randomNumber); console.log(p.randomNumber); console.log('always same:'); console.log(obj.randomNumber); console.log(obj.randomNumber); console.log(obj.randomNumber);
.as-console-wrapper { max-height: 100% !important; top: 0; }
将多个原型组合成一个新原型的概念通常被称为“ mixin” 。 以下是一些相关的问答:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.