7
var foo = function () {
    return new moo();
}

var moo = function () {
    return this;
}

如果我执行语句

new foo()

我真的会得到一个 moo 的实例吗?这似乎既明显又不直观。从功能上讲,这是应该发生的事情,但同时,如果您不了解内部情况,这也是意料之外的。

编辑:我意识到这在 Java 构造函数中似乎不直观 bc 不能返回任何东西。

这与 jquery 使用的构造函数模式非常相似。

4

2 回答 2

3

是的,你会得到一个 moo 的实例。

不直观是因为您可以在 javascvipt 构造函数中返回除对象本身之外的其他内容。这是可能的,因为所有函数实际上都是 js 中的对象。在像 java 和 c# 这样的语言中这是不可能的,构造函数总是返回构造函数所属的对象。在此类语言中,您也不能在没有 new 关键字的情况下调用构造函数。不从构造函数返回任何东西与return this;js 中的相同(假设它使用了构造函数)也增加了一些混乱。

于 2013-07-21T18:10:10.297 回答
2

你是对的,你会得到一个 moo 的实例

之所以如此模棱两可,是因为每当使用 new 关键字时,the newly created object's constructor is not executed until 'this' keyword is used. 新对象绑定到“this”关键字。

请参考:https ://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new

当执行代码 new foo(...) 时,会发生以下情况:

  1. 创建了一个新对象,继承自 foo.prototype。
  2. 构造函数 foo 使用指定的参数调用,并且 this 绑定到新创建的对象。new foo 等价于 new foo(),即如果没有指定参数列表,则调用不带参数的 foo。
  3. 构造函数返回的对象成为整个 new 表达式的结果。如果构造函数没有显式返回对象,则使用在步骤 1 中创建的对象。(通常构造函数不返回值,但如果他们想覆盖正常的对象创建过程,他们可以选择这样做。)

在您的示例中,也创建了一个新对象,但未使用“this”关键字,因此未调用 foo 的构造函数,因此该函数最终返回 moo 对象。

http://jsfiddle.net/v5aGu/

var foo = function () {
    return new moo();
}

var moo = function () {
    return this;
}

var myFoo = new foo(2);
if(myFoo instanceof moo){
    alert("moo");
}
if(myFoo instanceof foo){
    alert("foo");
}

编辑:回答@Desu 提出的问题

id = 0;

var foo = function(){

}

if(new foo() instanceof foo){
 alert("yes"); //alerts yes
}

JavaScript 构造函数 101:

  1. 构造函数的默认行为是返回 'this' 如果没有返回任何其他内容
  2. 如果从构造函数返回另一个对象,则绑定到“this”的新创建的对象将被丢弃

http://jsfiddle.net/xQVuX/1/

id = 0;

var foo = function(){
}

if(new foo() instanceof foo){
 alert("foo yes"); //alerts foo yes because foo returns this as a default behavior
}

var foo2 = function(){
    var i=new foo();
    return i;
}

if(new foo2() instanceof foo2){
 alert("foo2 yes");// does not alert because foo2 returns another object and the newly created object is discarded
}

var foo3 = function(){
    this.i = 10; 
}

if(new foo3() instanceof foo3){
    alert("foo3 yes"); // alerts foo3 yes because foo3 returns this as a default behavior
}
于 2013-07-21T18:03:03.797 回答