JavaScript可以通过多种方式创建对象。
我尝试以下代码以避免new关键字创建一个新的A类对象。
我的问题是A.prototype.init()这里是否等于新的A()?这对练习有好处吗?为什么?
function A(){
}
A.prototype.init=function(){
return this;
}
var a = A.prototype.init();
console.log(a);
var a1=new A();
console.log(a1);
答案 0 :(得分:2)
您所做的只是返回A.prototype
对象。你没有真正初始化任何东西,而你没有使用结果。
console.log(A.prototype === A.prototype.init()); // true
因此,除非你有特别的用途,否则我会说,不,这不是一个好习惯。
不确定为什么要避免使用new
,但无论如何,您可以更改构造函数,以便可以使用或不使用new
调用它,并且仍然像构造函数一样。
function A() {
var ths = Object.create(A.prototype);
ths.foo = "bar";
return ths;
}
现在使用new
无关紧要。无论如何,你都会得到一个继承自A.prototype
的新对象。
您仍然可以使用.init()
方法,但您也可以将逻辑放在构造函数中。
此外,您可以轻松创建一个处理样板代码的工厂。
function Ctor(fn) {
return function() {
var ths = Object.create(fn.prototype);
fn.apply(ths, arguments);
return ths;
};
}
所以现在你要创建这样的构造函数:
var A = Ctor(function() {
this.foo = "bar";
});
答案 1 :(得分:1)
您可以通过使用模块模式封装代码并返回调用构造函数的函数来避免new
,换句话说:
var A = (function ClassA() {
// Constructor
function A(prop) {
this.prop = prop; // instance property
this._init();
}
// Public methods
A.prototype = {
_init: function() {
}
};
// Mini factory to create new instances
return function(prop) {
return new A(prop); // well, only one `new`
};
}());
现在您可以创建没有new
的新实例:
var a = A('foo'); //=> A { prop: "foo", init: function }
答案 2 :(得分:0)
通常使用instanceof
来捕获直接函数调用:
function MyConstructor (a, b, c) {
if (!(this instanceof MyConstructor)) {
return new MyConstructor(a, b, c);
}
// ...
}
但是没有充分的理由避免使用new
。 Object.create
和其他替代方案可能会对性能产生重大影响。