Javascript 是否有任何理由在构造函数中手动“返回”?

Javascript 是否有任何理由在构造函数中手动“返回”?,javascript,oop,compiler-construction,return,new-operator,Javascript,Oop,Compiler Construction,Return,New Operator,通常,在构造函数中,当使用new前缀调用绑定到函数中this的对象时,它将返回该对象。但我可以想象,手动返回您自己的值也是可能的(我想我甚至在crockford的书中读到了这一点)。有没有这样的实践有用的地方?如果您想实现单例模式,可以使用这种模式,方法是确保在第一次构造对象之后,您永远不会构造另一个对象,而是返回第一个构造的对象 i、 e 是的,这样想吧 item = function(id){ if(alreadytaken(id)){ return cache[id]; }

通常,在构造函数中,当使用
new
前缀调用绑定到函数中
this
的对象时,它将返回该对象。但我可以想象,手动返回您自己的值也是可能的(我想我甚至在crockford的书中读到了这一点)。有没有这样的实践有用的地方?

如果您想实现单例模式,可以使用这种模式,方法是确保在第一次构造对象之后,您永远不会构造另一个对象,而是返回第一个构造的对象

i、 e


是的,这样想吧

item = function(id){
  if(alreadytaken(id)){
    return cache[id];
  }else{
    cache[id] = this;
  }
}

var newitem = new item(1);
var newitem2 = new item(1);
本例检查ID是否已经存在。如果它这样做了,那么它将强制返回已经存在的对象,这是我在过去实际使用过的对象。

构造函数(即使用
new
调用的函数)总是返回一个对象,这是
是默认值。在某些情况下,您可能会在不使用
new
的情况下保护呼叫,例如:

function Foo(arg) {
  if ( !(this instanceof Foo) ) {
    return new Foo(arg);
  }
  this.blah = arg;
}

因此,您向函数的
this
返回一个不同的对象,但它仍然返回自身的实例。

如果您从构造函数返回一个值类型,您将根据是否使用了
new
获得不同的行为。这就是
String
的工作原理。在JavaScript控制台中查看此对象:

{
    s: String("abc"),
    S: new String("abc")
}
s
包含字符串值,但大
s
包含字符串对象。也许是细微的差别

除此之外,您还可以为不同的目的使用相同的功能:

function Foo() {
    return "abc";
}
Foo.prototype.DoSomething = function () {
    // something completely unrelated to "abc"
};
var a = Foo();      // The string "abc".  Does not have a DoSomething() method.
var b = new Foo();  // An Object with a DoSomething() method.  Doesn't know about "abc".

取决于是否使用了
new
,您会得到完全不同的结果。

如果它是一个对象,您只能返回您自己的值。如果您暗示
newitem==newitem2
,那么这绝对不是真的。代码的唯一特殊结果是,
cache[1]
将等于
newitem
,而不是
newitem2
。这个答案令人困惑,您不妨执行
返回操作。返回
cache[id]
不会返回任何内容,只要在调用时使用
new
关键字,它就会停止执行。@David:为什么它们不相等?如果已使用该ID创建对象,则返回缓存对象。(假设
alreadytaken
检查缓存中的ID)。所以是的,它们是相等的。@user1689607使用
new
关键字时,不能“强制返回”任何内容。您总是会得到新创建的对象作为回报。@David:那是不正确的。整个问题基于这样一个前提,即当使用
new
调用时,可以覆盖返回值。不是这样:问题是关于使用带有
new
关键字的构造函数。如果此代码位于构造函数
Foo
中,则唯一的效果是
class.singleton
将等于使用
new Foo()
创建的第一个实例。但是,您的代码意味着随后调用
var foo2=new Foo()
将返回单例,这绝对不是真的。如果这肯定不是真的,那么这个问题的整个前提不是不正确吗?还是我的代码有错误?@meetamit:测试一下。虽然我认为
如果(!TheClass.singleton)
是有意的。是的,我在很大程度上得到了纠正(我也尝试过:)。很抱歉用了“绝对”这个词。不过,这在很大程度上扰乱了我的世界。多年来,我一直认为这是行不通的。可能有一个旧版本的JavaScript不是这样吗?@meetamit如果你感兴趣,我在这里发布了一个关于这个版本的问题:如果
Foo
的原型包含
Foo
,那么这个
将引用一个已经存在的
Foo
对象,但我不确定首先设置这种情况的原因是什么…实际上,我刚刚意识到这可能是一个非常理想的结果-它本质上使调用
someFoo.Foo(arg)
重新初始化对象,这是一个非常整洁的代码重用工具…很酷的黑客,我相信crockford会同意,但是任何读到这篇文章的人都应该检查一下答案。@Jeff说如果Foo的原型包含Foo
没有意义,这可能会失败,除非你的意思是如果
Foo
被作为实例的方法调用(即
Foo.Foo()
)。我不使用这种方法,如果构造函数在应该调用的时候没有使用
new
调用,那么代码测试应该失败。这只是一个返回其他对象的原因示例。我知道,我正是指出了这种情况(
foo.foo()
)。这并不是对该方法的批评,只是对使用该技术的任何人的一个提示,在这种情况下,调用该方法时没有使用
new
关键字,而该关键字随后可能会出现意外行为。
function Foo() {
    return "abc";
}
Foo.prototype.DoSomething = function () {
    // something completely unrelated to "abc"
};
var a = Foo();      // The string "abc".  Does not have a DoSomething() method.
var b = new Foo();  // An Object with a DoSomething() method.  Doesn't know about "abc".