我一直在阅读Stoyan Stefanov撰写的JavaScript Patterns一书,其中一个强制构造函数的新运算符的模式就像这样
function Waffle() {
if (!(this instanceof Waffle)) {
return new Waffle();
}
this.tastes = "yummy";
}
Waffle.prototype.wantAnother = true;
Run Code Online (Sandbox Code Playgroud)
以这种方式书写时,您可以使用其中一种方式调用Waffle
var first = new Waffle(),
second = Waffle();
Run Code Online (Sandbox Code Playgroud)
我认为这是一个有用的功能,不确定它是否在未来版本的ecma/javascript中实现
我想出了一些东西,我认为每次创建构造函数时都可以复制和粘贴
这样的事情
function checkInstance (name) {
if (name.constructor.name === undefined) {
return "construct it"
} else {
return false;
}
}
function Waffle() {
var _self = checkInstance.call(this, this);
if (_self === "construct it") {
return new Waffle()
}
this.tastes = "yummy"
}
var waffle = Waffle()
waffle
Run Code Online (Sandbox Code Playgroud)
因此我可以调用Waffle新的Waffle或Waffle()并且仍然让它返回一个对象
我遇到的问题就在这里
if (_self === "construct it") {
return new Waffle()
}
Run Code Online (Sandbox Code Playgroud)
无论如何我可以参考new Waffle()而不参考构造函数的实际名称,这意味着我每次都可以复制和粘贴它,而不必改变任何东西.意思是我可以将Waffle()保存为变量并执行类似的操作
return new var
Run Code Online (Sandbox Code Playgroud)
我希望我可以使用this.name但是在调用之前它不起作用.
我有一种感觉,我不得不至少问一些有关堆栈溢出的人,如果有可能的话
再次,您的意见和反馈表示赞赏
我有一个更好的解决方案.这就是你目前正在做的事情:
function Waffle() {
if (!(this instanceof Waffle))
return new Waffle;
this.tastes = "yummy";
}
Waffle.prototype.wantAnother = true;
Run Code Online (Sandbox Code Playgroud)
这种模式并不是很好,因为你混合代码来构造一个新的对象,用代码检查new关键字是否被使用.
我之前提到过,你不应该new在JavaScript中使用关键字,因为它会破坏功能特性.相反,让我们创建另一个做同样事情的函数:
Function.prototype.new = (function () {
return function () {
functor.prototype = this.prototype;
return new functor(this, arguments);
};
function functor(constructor, args) {
return constructor.apply(this, args);
}
}());
Run Code Online (Sandbox Code Playgroud)
此函数允许您创建函数的实例,如下所示:
var waffle = Waffle.new();
Run Code Online (Sandbox Code Playgroud)
但是我们根本不想使用new.因此,为了消除它,我们将创建一个包装构造函数的函数,如下所示:
function constructible(constructor) {
function functor() { return Function.new.apply(constructor, arguments); }
functor.prototype = constructor.prototype;
return functor;
}
Run Code Online (Sandbox Code Playgroud)
现在我们可以定义Waffle函数如下:
var Waffle = constructible(function () {
this.tastes = "yummy";
});
Waffle.prototype.wantAnother = true;
Run Code Online (Sandbox Code Playgroud)
现在您可以创建或不使用new以下对象:
var first = new Waffle;
var second = Waffle();
Run Code Online (Sandbox Code Playgroud)
注意:该constructible功能非常慢.请使用以下版本constructible- 它更快一点:
function constructible(constructor) {
constructor = Function.bind.bind(constructor, null);
function functor() { return new (constructor.apply(null, arguments)); }
functor.prototype = constructor.prototype;
return functor;
}
Run Code Online (Sandbox Code Playgroud)
我个人不会使用这两种方法中的任何一种.我只记得写new,或者(更有可能)我会重构我的代码如下:
var waffle = {
create: function () {
var waffle = Object.create(this);
waffle.tastes = "yummy";
return waffle;
},
wantAnother: true
};
var first = waffle.create();
var second = waffle.create();
Run Code Online (Sandbox Code Playgroud)
如果您想了解有关此模式的更多信息,请阅读以下答案:https://stackoverflow.com/a/17008403/783743
| 归档时间: |
|
| 查看次数: |
999 次 |
| 最近记录: |