我有一个方法
function MyClass(name){
this._name = name;
}
MyClass.prototype.test=function(){
console.log(this._name);
}
这项工作如果创建新实例
var a = new MyClass('demo');
a.test();
但是,现在我想把这个类称为没有创建实例的函数
MyClass('demo2').test();
这可能吗?
答案 0 :(得分:4)
您可以检查this
是否是该类的实例,如果检查为false,则表示它被调用为函数,您可以返回一个新实例:
function MyClass(name){
if (!(this instanceof MyClass)) {
return new MyClass(name);
}
this._name = name;
}
通过这种方式,您可以使用或不使用new
关键字获取该课程的新实例。
答案 1 :(得分:1)
是的,这是可能的。您可以返回具有必要属性的自定义对象。
function MyClass(name){
// private variable
var _name = name;
var getName = function(){
return _name;
};
// public properties
return {
test: getName
}
}
console.log(MyClass('Foo').test())
console.log(MyClass('Foo')._name)

或者您可以拥有仅在MyClass
内可用的内部私有类。
function MyClass(name){
function Person(){
this._name = name;
}
Person.prototype.getName = function(){
return this._name
}
return new Person()
}
console.log(MyClass('Foo').getName())
console.log(MyClass('Foo')._name)

答案 2 :(得分:1)
使用new
已久:)
新方法是使用Object.create,因为这样可以更好地控制创建的对象。如果您使用或不使用new来调用它并不重要,例如new MyClass('demo').test()
或MyClass('demo').test()
,它将始终返回您在构造函数中创建的对象。您可以完全控制属性,并可以将它们设置为只读,并且不可删除,并确定它们是否应该是可枚举的。您甚至可以创建getters和setters。
Object.create()方法使用指定的原型对象和属性创建一个新对象。
Object.create(proto [,propertiesObject])
proto 应该是新创建对象原型的对象。
<强> propertiesObject 强> 可选的。如果指定且未定义,则具有可枚举自身属性的对象(即,在其自身上定义的那些属性,而不是沿其原型链的可枚举属性)指定要添加到新创建的对象的属性描述符,以及相应的属性名称。这些属性对应于Object.defineProperties()的第二个参数。
<强>配置强> 当且仅当可以更改此属性描述符的类型并且可以从相应对象中删除属性时,才返回true。 默认为false 。
<强>枚举强> 当且仅当在枚举相应对象的属性期间显示此属性时,才返回true。 默认为false 。
<强>值强> 与属性关联的值。可以是任何有效的JavaScript值(数字,对象,函数等)。 默认为未定义。
<强>可写强> 当且仅当可以使用赋值运算符更改与属性关联的值时,才返回true。 默认为false 。
获取强> 一个函数,用作属性的getter,如果没有getter则不定义。函数return将用作property的值。 默认为未定义。
设置强> 用作属性的setter的函数,如果没有setter则为undefined。该函数将仅接收分配给属性的新值作为参数。 默认为未定义。
返回值 具有指定原型对象和属性的新对象。
// Constructor for MyClass
function MyClass(name){
// Create the new object with Object.create and using the
// prototype of MyClass as a base, and add a new read only
// property "name".
return Object.create(
MyClass.prototype,
{
name : {
//enumerable: false,
//writable : false,
value : name
}
}
)
}
// Dedine new properties on the prototype,
// using Object.defineProperties that allows
// more control over the properties.
Object.defineProperties(
MyClass.prototype,
{
test: // name of property
{
value: // value of property, in this case a function
function(){
console.log(this.name);
return this; // Return "this" to allow chaining
}
// No other attributes defined, and therefore using
// default values: read only, not enumerabe and
// not configurable.
},
setCord:
{
value:
function (x1, y1, x2, y2) {
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
return this;
}
},
width:
{
get: // A getter
function() {
return this.x2 - this.x1;
},
set: // A setter
function(value) {
this.x2 = this.x1 + value;
}
},
height:
{
get:
function() {
return this.y2 - this.y1;
},
set:
function (value) {
this.y2 = this.y1 + value;
}
}
}
);
var a= MyClass('DEMO').test();
a.setCord(10,20,50,60); // Set the cords.
// Display the cords, and using the getters of with an height
// that calculates the with and height on the fly.
console.log(
"x1:%d, y1:%s, x2:%d, y2:%d, width:%d, height:%d",
a.x1, a.y1, a.x2, a.y2, a.width, a.height
);
a.width = 100; // Using the setter to set the new width.
a.height = 100;
// Show the new coordinates. Notice that x2, y2, widtgh
// and height has changed.
console.log(
"x1:%d, y1:%s, x2:%d, y2:%d, width:%d, height:%d",
a.x1, a.y1, a.x2, a.y2, a.width, a.height
);
&#13;