我对如何定义原型属性有疑问。因此,您不必编写" MyClass.prototype。"为了将每个属性添加到原型,人们创建新对象并将其设置为原始对象。
喜欢这个。
var MyClass = function() {}
MyClass.prototype = {
sayHi : function() {
alert('hi');
}
}
但是如果你这样做,当你试图从任何实例访问构造函数时,它可能会导致问题。
var o1 = new MyClass();
alert( o1 instanceof MyClass ); // true
alert( o1.constructor === MyClass ); // false !!!
o1.constructor
通常指向MyClass,但由于原始原型已更改,因此不再适用。
我设法通过MyClass.prototype.constructor = MyClass;
解决了这个问题,并且它再次正常工作。
问题是,还有哪些其他问题会改变原始原型?
如何定义原型属性?
答案 0 :(得分:2)
我通常使用简单的defclass
函数在JavaScript中创建“类”:
function defclass(prototype) {
var constructor = prototype.constructor;
constructor.prototype = prototype;
return constructor;
}
这个函数允许我按如下方式创建类:
var MyClass = defclass({
constructor: function () {},
sayHi: function () {
alert("hi");
}
});
该方法具有以下优点:
constructor
函数本身只是另一个原型属性。constructor
属性。例如:
var o1 = new MyClass;
alert(o1 instanceof MyClass); // true
alert(o1.constructor === MyClass); // true
您还可以轻松修改defclass
以支持继承:
function defclass(uber, body) {
var base = uber.prototype;
var prototype = Object.create(base);
var constructor = body.call(prototype, base), prototype.constructor;
constructor.prototype = prototype;
return constructor;
}
然后您可以按如下方式使用它:
var Rectangle = defclass(Object, function () {
this.constructor = function (width, height) {
this.height = height;
this.width = width;
};
this.area = function () {
return this.width * this.height;
};
});
继承也很简单:
var Square = defclass(Rectangle, function (base) {
this.constructor = function (side) {
base.constructor.call(this, side, side);
};
});
一切都按预期工作:
var sq = new Square(5);
alert(sq.area()); // 25
alert(sq instanceof Square); // true
alert(sq instanceof Rectangle); // true
alert(sq.constructor === Square); // true
那是所有人。
答案 1 :(得分:1)
您可以使用合并/扩展功能(常见于jQuery或Lodash等库中):
$.extend(MyClass.prototype, { prop: ..., ... });
答案 2 :(得分:1)
constructor
属性只是一个方便的参考,你可以简单地重新分配它:
MyClass.prototype = {
constructor: MyClass,
sayHi : function() {
alert('hi');
}
}
重新定义原型对象不应该有任何其他“问题”,除非您正在使用预定义的原型属性扩展另一个对象。
如果您想要勇于学习语法,请尝试使用with
。我不推荐它,但如果你只想缩短语法,它仍然是一个选项:
var MyClass = function() {}
with (MyClass.prototype) {
sayHi = function() {
alert('hi');
}
}
答案 3 :(得分:1)
我通常选择:
function MyClass() {}
MyClass.prototype = {
constructor: MyClass,
foo: function foo() {
// do something
}
};
我意识到它覆盖了constructor
属性,但是维护起来比较干净,在实践中我没有注意到10年来我一直在编写JavaScript"类和#34;这样。
也可以使用原生Object.create方法。
前段时间我创建了一个小型JavaScript库来帮助编写课程: Inherit.js
它允许您创建这样的类:
var Point = Object.extend({
includes: [
Mixin1,
Mixin2
],
self: {
// class or "static" methods and properties go here
},
prototype: {
// instance methods and properties go here
}
});
var Point3D = Point.extend({ ... });
它为" mixins"提供支持。如果它们被声明为这样:
var Mixin = {
includes: [
// Yup, mixins can include mixins too
],
included: function(Klass) {
// Klass is the constructor function that just included this mixin
},
self: {
// class or "static" methods and properties go here
},
prototype: {
// instance methods and properties go here
}
};
有些人会反对打字本地课程,但我全都是为了它。
为什么我走这条路:
instanceof
操作员仍然可以使用