将新返回命名函数构造函数实例-

Will new return the named function constructor instance-?

本文关键字:函数 构造函数 实例 新返回 返回      更新时间:2023-09-26
var foo = function () {
    return new moo();
}
var moo = function () {
    return this;
}

如果我执行语句

new foo()

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

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

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

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

非直观性是因为您可以在 Javascvipt 构造函数中返回对象本身以外的其他内容。这是可能的,因为所有函数实际上都是 js 中的对象。 在 java 和 c# 等语言中,这是不可能的,构造函数总是返回构造函数所属的对象。在此类语言中,如果没有新关键字,您也不能调用构造器。不从构造函数返回任何内容与 js 事物中的return this;相同(假设它使用了构造函数(也增加了一点混乱。

你是对的,你会得到一个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 使用指定的参数调用,并绑定到新创建的对象。 等价于 new foo((,即如果没有指定参数列表,foo 是 没有参数调用。
  3. 构造函数返回的对象将成为整个新表达式的结果。如果构造函数没有 显式返回一个对象,使用步骤 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
}