JavaScript类/对象可以有构造函数吗?它们是如何产生的?
当前回答
这是一个构造函数:
function MyClass() {}
当你这样做时
var myObj = new MyClass();
MyClass被执行,并返回该类的一个新对象。
其他回答
在大多数情况下,在调用传递此信息的方法之前,必须以某种方式声明所需的属性。如果你不需要一开始就设置一个属性,你可以像这样在对象中调用一个方法。可能不是最漂亮的方法,但这仍然有效。
var objectA = {
color: '';
callColor : function(){
console.log(this.color);
}
this.callColor();
}
var newObject = new objectA();
下面是一个模板,我有时会在JavaScript中使用类似oop的行为。如您所见,您可以使用闭包模拟私有(静态和实例)成员。新的MyClass()将返回一个对象,该对象仅具有分配给这个对象和“类”的原型对象中的属性。
var MyClass = (function () {
// private static
var nextId = 1;
// constructor
var cls = function () {
// private
var id = nextId++;
var name = 'Unknown';
// public (this instance only)
this.get_id = function () { return id; };
this.get_name = function () { return name; };
this.set_name = function (value) {
if (typeof value != 'string')
throw 'Name must be a string';
if (value.length < 2 || value.length > 20)
throw 'Name must be 2-20 characters long.';
name = value;
};
};
// public static
cls.get_nextId = function () {
return nextId;
};
// public (shared across instances)
cls.prototype = {
announce: function () {
alert('Hi there! My id is ' + this.get_id() + ' and my name is "' + this.get_name() + '"!\r\n' +
'The next fellow\'s id will be ' + MyClass.get_nextId() + '!');
}
};
return cls;
})();
有人问过我使用这种模式的继承问题,所以如下:
// It's a good idea to have a utility class to wire up inheritance.
function inherit(cls, superCls) {
// We use an intermediary empty constructor to create an
// inheritance chain, because using the super class' constructor
// might have side effects.
var construct = function () {};
construct.prototype = superCls.prototype;
cls.prototype = new construct;
cls.prototype.constructor = cls;
cls.super = superCls;
}
var MyChildClass = (function () {
// constructor
var cls = function (surName) {
// Call super constructor on this instance (any arguments
// to the constructor would go after "this" in call(…)).
this.constructor.super.call(this);
// Shadowing instance properties is a little bit less
// intuitive, but can be done:
var getName = this.get_name;
// public (this instance only)
this.get_name = function () {
return getName.call(this) + ' ' + surName;
};
};
inherit(cls, MyClass); // <-- important!
return cls;
})();
还有一个例子:
var bob = new MyClass();
bob.set_name('Bob');
bob.announce(); // id is 1, name shows as "Bob"
var john = new MyChildClass('Doe');
john.set_name('John');
john.announce(); // id is 2, name shows as "John Doe"
alert(john instanceof MyClass); // true
正如您所看到的,类之间正确地交互(它们共享来自MyClass的静态id, announce方法使用正确的get_name方法,等等)。
需要注意的一点是需要对实例属性进行阴影处理。您实际上可以让继承函数遍历所有实例属性(使用hasOwnProperty)是函数,并自动魔术般地添加一个super_<方法名>属性。这将允许您调用This .super_get_name(),而不是将其存储在临时值中并使用call调用它。
对于原型上的方法,你不需要担心上面的问题,如果你想访问超类的原型方法,你可以调用this.constructor.super.prototype.methodName。如果你想让它不那么冗长,你当然可以添加便利属性。:)
使用原型:
function Box(color) // Constructor
{
this.color = color;
}
Box.prototype.getColor = function()
{
return this.color;
};
隐藏“color”(有点像私有成员变量):
function Box(col)
{
var color = col;
this.getColor = function()
{
return color;
};
}
用法:
var blueBox = new Box("blue");
alert(blueBox.getColor()); // will alert blue
var greenBox = new Box("green");
alert(greenBox.getColor()); // will alert green
也许它变得简单了一点,但以下是我在2017年想出的:
class obj {
constructor(in_shape, in_color){
this.shape = in_shape;
this.color = in_color;
}
getInfo(){
return this.shape + ' and ' + this.color;
}
setShape(in_shape){
this.shape = in_shape;
}
setColor(in_color){
this.color = in_color;
}
}
在使用上面的类,我有以下:
var newobj = new obj('square', 'blue');
//Here, we expect to see 'square and blue'
console.log(newobj.getInfo());
newobj.setColor('white');
newobj.setShape('sphere');
//Since we've set new color and shape, we expect the following: 'sphere and white'
console.log(newobj.getInfo());
如您所见,构造函数接受两个参数,我们设置对象的属性。我们还通过使用setter函数改变对象的颜色和形状,并证明在这些改变之后调用getInfo()时它的变化仍然存在。
有点晚了,但我希望这能帮到你。我已经用摩卡单元测试了这个功能,效果很好。
http://www.jsoops.net/对于Js中的oop非常好。提供私有、受保护、公共变量和函数,并具有继承特性。示例代码:
var ClassA = JsOops(function (pri, pro, pub)
{// pri = private, pro = protected, pub = public
pri.className = "I am A ";
this.init = function (var1)// constructor
{
pri.className += var1;
}
pub.getData = function ()
{
return "ClassA(Top=" + pro.getClassName() + ", This=" + pri.getClassName()
+ ", ID=" + pro.getClassId() + ")";
}
pri.getClassName = function () { return pri.className; }
pro.getClassName = function () { return pri.className; }
pro.getClassId = function () { return 1; }
});
var newA = new ClassA("Class");
//***Access public function
console.log(typeof (newA.getData));
// function
console.log(newA.getData());
// ClassA(Top=I am A Class, This=I am A Class, ID=1)
//***You can not access constructor, private and protected function
console.log(typeof (newA.init)); // undefined
console.log(typeof (newA.className)); // undefined
console.log(typeof (newA.pro)); // undefined
console.log(typeof (newA.getClassName)); // undefined