根据道格拉斯·克罗克福德的说法,我可以使用类似http://javascript.crockford.com/prototypal.html的东西(稍微调整一下)......但我对jQuery的做法感兴趣。使用$ .extend是不错的做法?
我有4个班级:
var A = function(){ }
A.prototype = {
name : "A",
cl : function(){
alert(this.name);
}
}
var D = function(){}
D.prototype = {
say : function(){
alert("D");
}
}
var B = function(){} //inherits from A
B.prototype = $.extend(new A(), {
name : "B"
});
var C = function(){} //inherits from B and D
C.prototype = $.extend(new B(), new D(), {
name : "C"
});
var o = new C();
alert((o instanceof B) && (o instanceof A) && (o instanceof C)); //is instance of A, B and C
alert(o instanceof D); //but is not instance of D
所以,我可以调用A,B,C和D中的每个方法,属性......问题来了,当我想测试o是D的实例?我怎样才能克服这个问题?
答案 0 :(得分:4)
使用$ .extend
是不错的做法
$.extend
对单身人士很有用,但原型并不理想。
使用Object.create
(或Crockford的polyfill),您可以轻松创建这样的类。我正在使用$.extend
来处理属性并为它们提供默认值和模块模式以使其保持良好的组织。希望这会有所帮助:
// Helper that makes inheritance work using 'Object.create'
Function.prototype.inherits = function(parent) {
this.prototype = Object.create(parent.prototype);
};
var Person = (function PersonClass() {
var _defaults = {
name: 'unnamed',
age: 0
};
function Person(props) {
$.extend(this, props, _defaults);
}
Person.prototype = {
say: function() {
return 'My name is '+ this.name;
}
};
return Person;
}());
var Student = (function StudentClass(_super) {
Student.inherits(_super); // inherit prototype
var _defaults = {
grade: 'untested'
};
function Student(props) {
_super.apply(this, arguments); // call parent class
$.extend(this, props, _defaults);
}
Student.prototype.say = function() {
return 'My grade is '+ this.grade;
};
return Student;
}(Person));
var james = new Student({ name: 'James', grade: 5 });
console.log(james instanceof Student); // true
console.log(james instanceof Person); // true
答案 1 :(得分:1)
一个对象只有一个原型,所以你不能通过一次调用使它成为另外两种类型的实例。
$.extend(new B(), new D(), ...
创建一个B实例的对象。然后将D的所有属性复制到新创建的对象。但该对象仍然是B的实例。
使用$.extend
本身既不好也不坏。但是您必须使用jQuery,这会使您的代码不再可重用。而且你必须要知道$.extend
覆盖具有相同名称的属性,这可能是你想要的,也可能不是你想要的。