[英]Interesting JavaScript inheritance pattern
I have recently watched a video where Douglas Crockford was explaining inheritance patterns of Javascript. 我最近看了一段视频,其中道格拉斯·克罗克福德 ( Douglas Crockford)正在解释Java的继承模式。 The video itself is pretty old - it was filmed 6 years ago - but still useful. 该视频本身很旧-它是6年前拍摄的-但仍然有用。 In that video he showed one inheritance pattern he kinda invented (although I am not sure who the author is). 在该视频中,他展示了他发明的一种继承模式(尽管我不确定作者是谁)。 This is the code using his approach: 这是使用他的方法的代码:
// imitation of new operator function objectConstructor(obj, initializer, methods) { // create prototype var func, prototype = Object.create(obj && obj.prototype); // add methods to the prototype if(methods) Object.keys(methods).forEach(function(key) { prototype[key] = methods[key]; }); // function that will create objects with prototype defined above func = function() { var that = Object.create(prototype); if(typeof initializer === 'function') initializer.apply(that, arguments); return that; } func.prototype = prototype; prototype.constructor = func; return func; } var person = objectConstructor(Object, function(name) { this.name = name; }, { showName: function() { console.log(this.name); } }); var employee = objectConstructor(person, function(name, profession) { this.name = name; this.profession = profession; }, { showProfession: function() { console.log(this.profession); } }); var employeeInfo = employee('Mike', 'Driver'); employeeInfo.showName(); // Mike employeeInfo.showProfession(); // Driver
Unfortanately, he didn't show the invocation. 不幸的是,他没有显示该调用。 So, this part 所以这部分
var employeeInfo = employee('Mike', 'Driver');
employeeInfo.showName();
employeeInfo.showProfession();
is mine. 是我的。 It generally works, but it turns out that I repeat this.name = name;
它通常可以工作,但事实证明,我重复了this.name = name;
for both "classes" - person
and employee
. 对于“类”- person
和employee
。 I played around but I didn't manage to make it work properly without that repetition. 我玩了一下,但是没有重复就无法使其正常工作。 Seems I cannot get name
because such a property isn't contained in the prototypal chain for employee
. 似乎我无法name
因为employee
原型链中不包含这样的属性。 I didn't succeed either in mixing in stuff like person.call(this, arguments)
. 我也没有成功地混入诸如person.call(this, arguments)
类的东西。 So, apart from whether it is cool/nice/smart/sensible etc. or not in 2017, how could I remove this.name = name;
因此,除了在2017年是否酷/漂亮/智能/明智等之外,我如何删除this.name = name;
from employee
and get the same result? 从employee
那里得到相同的结果? Or everything is ok and this approach doesn't suppose it? 还是一切正常,这种方法不可行吗?
Since the func
constructor completely disregards this
, passing any context to it via call
or apply
will not work. 由于func
构造函数完全忽略了this
,因此无法通过call
或apply
将任何上下文传递给它。 Creating a way to copy over the super class' properties after creating an object is one of the ways you could accomplish your task. 创建对象后,创建一种复制超类属性的方法是您可以完成任务的一种方法。
// imitation of new operator function objectConstructor(obj, initializer, methods) { // create prototype var func, prototype = Object.create(obj && obj.prototype); // add methods to the prototype if(methods) Object.keys(methods).forEach(function(key) { prototype[key] = methods[key]; }); // function that will create objects with prototype defined above func = function() { var that = Object.create(prototype); if(typeof initializer === 'function') initializer.apply(that, arguments); return that; } func.prototype = prototype; prototype.constructor = func; return func; } function copyProperties(source, target) { for (var prop in source) { if (source.hasOwnProperty(prop)) { target[prop] = source[prop]; } } } var person = objectConstructor(Object, function(name) { this.name = name; }, { showName: function() { console.log(this.name); } }); var employee = objectConstructor(person, function(name, profession) { copyProperties(person.apply(null, arguments), this); this.profession = profession; }, { showProfession: function() { console.log(this.profession); } }); var employeeInfo = employee('Mike', 'Driver'); employeeInfo.showName(); // Mike employeeInfo.showProfession(); // Driver
Here is your snippet with 2 small modifications so that you can do a super(name) type of call. 这是您的代码段,其中进行了2处小的修改,因此您可以进行super(name)类型的呼叫。
I've placed comments were I've made the modifications.. with prefix keith: 我已经放置了注释,并且进行了修改..使用前缀keith:
// imitation of new operator function objectConstructor(obj, initializer, methods) { // create prototype var func, prototype = Object.create(obj && obj.prototype); // add methods to the prototype if(methods) Object.keys(methods).forEach(function(key) { prototype[key] = methods[key]; }); // function that will create objects with prototype defined above func = function() { var that = Object.create(prototype); if(typeof initializer === 'function') initializer.apply(that, arguments); return that; } func.prototype = prototype; //keith: store the initialization in constructor, //keith: as func is already creating the object.. prototype.constructor = initializer; return func; } var person = objectConstructor(Object, function(name) { this.name = name; }, { showName: function() { console.log(this.name); } }); var employee = objectConstructor(person, function(name, profession) { //keith: call our super person(name) person.prototype.constructor.call(this, name); this.profession = profession; }, { showProfession: function() { console.log(this.profession); } }); var employeeInfo = employee('Mike', 'Driver'); employeeInfo.showName(); // Mike employeeInfo.showProfession(); // Driver
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.