好的,所以我们试图让原型继承按照我们想要的方式工作,我已经阅读了一些示例,但我们想要的一个要求是我们可以轻松地调用父类上的方法。我们希望遵循模块模式+ jQuery 样板样式,我们有默认值、非空构造函数和原型函数
;(function($, window, undefined){
"use_strict";
var defaultsHuman = {
id: 1,
age: 0
};
function Human( options ){
this.options = $.extend(defaultsHuman, options || {});
this.age = this.options.age;
this.gender = 'male';
//save originals for ref
this._defaults = defaultsHuman;
};
Human.prototype = {
_className: 'Human',
init: function(){
console.log('My class is ' + this._className + ' my gender is ' + this.gender + ' and my age is ' + this.age);
}
};
//Right now Human's function prototype's constructor is Object(), but IE8 uses constructor.prototype
//well now it's Object which is native so it's undefined?, anyways we lose the original reference to the constructor from the instance
//so lets reset it to the constructor - constructor is now enumerable!
Human.prototype.constructor = Human; //note this is cyclical!
//END fn Human
var defaultsChild = {
name: ''
};
//we want to create a new constructor B that has properties, its constructor prototype is an instance of Human
function Child( options ){
//merge the parent defaults with my defaults, then extend dynamic options on top
this.options = $.extend(this.constructor.prototype._defaults, defaultsChild, options || {});
this.name = options.name;
//A.call(this);
};
//new Human() calls Human's constructor and returns an object with prototype set to Human.prototype
Child.prototype = new Human();
$.extend(Child.prototype, {
school: 'St. Peter\'s',
init: function(){
//create reference to super class
this._super = this.constructor.prototype;
//this._super.init.call(this);
this._super.init();
console.log('My name is ' + this.name + ' and my school is ' + this.school);
}
});
Child.prototype.constructor = Human;
//END Child
//export modules - old method before define
window.Human = Human;
window.Child = Child;
})(jQuery, window, undefined);
//some other closure somewhere where it is required in
;(function(window, undefined, Human, Child){
"use_strict";
var me = new Child({
name: 'Clarence',
age: 7
}).init();
})(window, undefined, Human, Child);
让我感到困惑的是,在Human's init
函数中this
引用了一个Human
实例,但处于一种Human constructor
从未运行过的状态,因此静态设置为男性的性别甚至不存在。
My class is Human my gender is undefined and my age is undefined
My name is Clarence and my school is St. Peter's
我可以通过调用来轻松解决这个问题this._super.init.call(this);
,我可能会这样做,但我仍然很好奇。
在构造函数运行后,我将 Child的函数原型显式设置为完整的 Human 对象: Child.prototype = new Human();
当我检查 child 的最终实例时me
,原型是 Human,构造函数已经运行(如预期的那样),但在Human init
变量内部this
是这样的人类构造函数从未运行过。
当我引用我的超级时:this._super = this.constructor.prototype;
这不是对此处声明的原型的引用Child.prototype = new Human();
吗?当我打电话时this.super.init()
,它不是在返回的上下文中运行new Human()
吗?
另请注意,我避免使用proto以与 IE8 兼容