我可以在不使用 new 关键字的情况下构造 JavaScript 对象吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1889014/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can I construct a JavaScript object without using the new keyword?
提问by pr1001
Here is what I'd like to do:
这是我想要做的:
function a() {
// ...
}
function b() {
// Some magic, return a new object.
}
var c = b();
c instanceof b // -> true
c instanceof a // -> true
b instanceof a // -> true
Is it possible? I can make bbe an instance of aeasily by hooking ainto its prototype chain but then I have to do new b(), which is what I'm trying to avoid. Is what I want possible?
是否可以?我可以通过挂钩到它的原型链b来a轻松地成为一个实例,a但是我必须这样做new b(),这是我试图避免的。我想要的可能吗?
Update:I feel that it might be possible with judicious use of b.__proto__ = a.prototype. I'm going to experiment more after work.
更新:我觉得明智地使用b.__proto__ = a.prototype. 下班后我会尝试更多。
Update 2:Below is what seems to be the closest you can get, which is good enough for me. Thanks all for the interesting answers.
更新 2:下面是你能得到的最接近的东西,这对我来说已经足够了。感谢大家的有趣答案。
function a() {
// ...
}
function b() {
if (!(this instanceof arguments.callee)) {
return new arguments.callee();
}
}
b.__proto__ = a.prototype
var c = b();
c instanceof b // -> true
c instanceof a // -> false
b instanceof a // -> true
Update 3:I found exactly what I wanted in a blog post on 'power constructors', once I added the essential b.__proto__ = a.prototypeline:
更新 3:一旦我添加了基本行,我就在关于 'power constructors'的博客文章中找到了我想要的内容b.__proto__ = a.prototype:
var object = (function() {
function F() {}
return function(o) {
F.prototype = o;
return new F();
};
})();
function a(proto) {
var p = object(proto || a.prototype);
return p;
}
function b(proto) {
var g = object(a(proto || b.prototype));
return g;
}
b.prototype = object(a.prototype);
b.__proto__ = a.prototype;
var c = b();
c instanceof b // -> true
c instanceof a // -> true
b instanceof a // -> true
a() instanceof a // -> true
回答by KooiInc
You can use this pattern:
您可以使用此模式:
function SomeConstructor(){
if (!(this instanceof SomeConstructor)){
return new SomeConstructor();
}
//the constructor properties and methods here
}
after which you can do:
之后你可以这样做:
var myObj = SomeConstructor();
In addition to this (rather old) answer: you can use a module patternto create an object:
除了这个(相当旧的)答案:您可以使用模块模式来创建一个对象:
function Person(name, age, male) {
name = name || 'unknown';
age = age || 0;
function get() {
return ['This person is called ', name,
(!male ? ', her' : ', his'),' age is ',
age].join('');
}
function setAge(nwage) {
age = nwage;
}
return Object.freeze({get: get, setAge: setAge});
}
// usage
var jane = Person('Jane', 23)
,charles = Person('Charles', 32, 1)
,mary = Person('Mary', 16);
console.log(jane.get()); //=> This person is called Jane, her age is 23
mary.setAge(17);
console.log(mary.get()); //=> This person is called Mary, her age is 17
Here's a jsFiddlefor some Datefunctionallity I created using that pattern.
这是我使用该模式创建的某些功能的jsFiddleDate。
回答by Matt Ball
What's wrong with using the newkeyword?
使用new关键字有什么问题?
At any rate, it sounds like the best thing to do is read up on Javascript inheritance: http://javascript.crockford.com/inheritance.html
无论如何,听起来最好的办法是阅读 Javascript 继承:http: //javascript.crockford.com/inheritance.html
回答by Zoidberg
Someone posted an article by douglas crockford in this question, and it explains exactly what your asking.
有人在这个问题上发表了 douglas crockford 的一篇文章,它准确地解释了你的问题。
OO Javascript constructor pattern: neo-classical vs prototypal
回答by AnthonyWJones
The simple answer to your specific question is: no.
对您的具体问题的简单回答是:不。
It would help you identified why you want to avoid new. Perhaps the patterns alluded to by one of the other answers will help. However none of them result in the instanceofreturning true in your tests.
它将帮助您确定为什么要避免new. 也许其他答案中提到的模式会有所帮助。但是,它们都不会导致instanceof在您的测试中返回 true。
The new operation is essentially:-
新的操作本质上是:-
var x = (function(fn) { var r = {}; fn.call(r); return r;}(b);
However there is the difference that the constructing fnis attached to the object using some internal property (yes you can get it with constructorbut setting it doesn't have the same effect). The only way to get instanceofto work as intended is to use the newkeyword.
然而,不同之处在于fn使用一些内部属性将构造附加到对象(是的,您可以使用它,constructor但设置它没有相同的效果)。instanceof按预期工作的唯一方法是使用new关键字。
回答by T.J. Crowder
You can't avoid newin the general case (without going to extremes, as per the Crockford article Zoidberg indirectly linked to) if you want inheritance and instanceofto work, but then (again), why would you want or need to?
new如果你想要继承和instanceof工作,你不能在一般情况下避免(不走极端,根据 Crockford 文章 Zoidberg 间接链接),但是(再次),你为什么想要或需要?
The only reason I can think of where you'd want to avoid it is if you're trying to pass a constructor function to another piece of code that doesn't know it's a constructor. In that case, just wrap it up in a factory function:
我能想到您想要避免它的唯一原因是,如果您试图将构造函数传递给另一段不知道它是构造函数的代码。在这种情况下,只需将其包装在工厂函数中:
function b() {
// ...
}
function makeB() {
return new b();
}
var c = makeB();
回答by nemisj
You can create instances without the new operator (here is a great article written about this by Douglas Crockford http://yuiblog.com/blog/2006/11/13/javascript-we-hardly-new-ya/). But it will not help you with the "instanceof" story.
您可以在没有 new 操作符的情况下创建实例(这里是 Douglas Crockford 写的一篇很棒的文章http://yuiblog.com/blog/2006/11/13/javascript-we-hardly-new-ya/)。但它不会帮助您处理“instanceof”故事。
回答by nemisj
Yes you can do this.
是的,你可以这样做。
var User = function() {
var privateMethod = function() {
alert('hello');
}
return {
sayHello : function() {
privateMethod();
this.done = true;
}
}
}
var user1 = User();
Is anything wrong with this method?
这种方法有什么问题吗?
回答by Upperstage
The only way to get instanceof to work is to use the new keyword. instanceof exploits ____proto____ which is established by new.
使 instanceof 工作的唯一方法是使用 new 关键字。instanceof 利用了由new建立的____proto____ 。
回答by Awin
JavaScript objects can be created without using the new keyword.
JavaScript 对象可以在不使用 new 关键字的情况下创建。
For example the following function returns an object without using new keyword
例如下面的函数不使用 new 关键字返回一个对象
function a(){
var obj ={};
obj.name = "hello";
obj.age = 12;
return obj;
}
回答by diyism
In a javascript bookmarklet, you could use eval(unescape("...")) to create object without "new" operator:
在 javascript 书签中,您可以使用 eval(unescape("...")) 来创建没有“new”运算符的对象:
javascript:xhr=eval(unescape('new\x20XMLHttpRequest();'));alert(xhr);

