`new function(){this.x=1}` 和 `{x:1}` 的区别

3
var Foo = new function(){
    this.A = 1;
    this.B = 2;
};
var Bar = {
    A: 1,
    B: 2
};
typeof Foo === "object"
typeof Bar === "object"

这两者有何区别呢?我只发现它们的__proto__对象不同:


1
是的,你找到了不同之处。它们有不同的原型。 - Felix Kling
除了原型的差异外,实际上并没有太多实用的差别,但由于原型上没有任何关于第一个对象的内容,所以它什么也不做。 - Pointy
你可以把Foo看作是一个类,但Bar是一个对象。 - Ji_in_coding
@Ji_in_coding 不是的,Foo只是一个对象。匿名构造函数是由new运算符调用的。 - Pointy
4个回答

0

好的:

var Foo = new function(){
    this.A = 1;
    this.B = 2;
};

我们有一个var Foo = new函数,这意味着运行时将使用新构造的对象调用该函数,并将其内部原型链接设置为该函数的"prototype"属性的值。因为那只是在初始化中实例化的一个匿名函数,它的"prototype"属性只是一个普通的空对象,所以它实际上什么也不做。构造函数确实会初始化新对象的两个属性,并且该新对象是new表达式的返回值。因此,Foo被分配了对该构造对象的引用,并且该对象具有一些已分配的属性。它还具有一个原型链,其中包括来自匿名构造函数的空对象,然后是从Object构造函数继承的原型。
在这个例子中:
var Bar = {
    A: 1,
    B: 2
};

我们有一个变量 (Bar) 被设置为对象初始化表达式的结果。这总是创建一个仅从 Object 原型继承的普通对象。这个对象与 Foo 对象不同的唯一方式是,Foo 对象在其原型链中有一个额外的(空)对象。

所以:

  • Foo 最终将成为一个普通对象,而不是函数。
  • Bar 也将成为一个普通对象,更明显地不是函数。
  • FooBar 将是相似的,但不是相同的(好吧,两个不同的对象永远不会相同,但我指的是它们特定的特征),因为 Foo 在其原型链中具有额外的空对象。

-1
在Javascript中,所有的函数都是对象。在你的情况下,Foo和Bar是相同的,但你可以构造第一个。
同样地,我认为在这种情况下构造函数的关键洞察力是,如果我们有:
function myFoo (){
    this.A = 1;
    this.B = 2;
};

那么

var Foo1 = new myFoo();

this 上下文是 Foo。

var Foo2 = myFoo();

this绑定到当前上下文,即在这种情况下是window对象(这意味着您实际上有window.A = 1)。

请参阅MDN文档以获取更详细的描述。

Function

Constructor

new operator


你的答案是正确的,但在这种情况下,Foo和Bar都不是函数,它们都是对象。 - Pointy
新的 function() {}, 不是 new function() {} (). - djechlin
1
@djechlin ()是可选的! - Pointy
@Pointy 我在研究这个问题时学到了这一点...我认为指出这一点是答案中非常重要的部分。顺便说一下,你应该提交一个答案。 - djechlin
@djechlin ,这个问题变得相当疯狂 :) - Pointy
@Pointy 这是一个非常好的问题。我很惊讶到目前为止只有我的赞同。或者找到一个好的重复问题。 - djechlin

-1

首先注意使用new调用匿名函数时省略括号是无关紧要的。JSLint会警告你这样做很容易引起混淆,但实际上就是这么回事。

我相信内部原型是唯一的区别。按照通常的方式编写可能更容易理解。

var Car = function() {
    this.seats = 4;
};

var car1 = new Car();
var car2 = {
    seats: 4
};

阅读此内容,我清楚地知道car1是一个对象,其内部原型是Car - 在您的情况下,它是一个不直接由变量持有的匿名函数 - 而car2是一个对象,其内部原型是Object。

car1的原型将是Car的“prototype”属性的值,而不是Car本身。 - Pointy

-1
第一个是函数构造器,它输出一个函数对象(即分配给Foo的内容),而另一个则只是一个普通的JavaScript对象。

你忽略了构造函数是通过 new 运算符调用的这一事实。 - Pointy
@Ji_in_coding Foo只是一个对象;它不是函数,也不是构造函数。 - Pointy
不是这样的。new 运算符会导致该函数被 调用,并将新构造的对象分配给 Foo。 - Pointy
我们的意思是一样的。new function(){} 是一个函数构造器,它输出一个函数对象。 - justinledouxweb
@justinledouxweb 不,我们并不是在说同一件事情。new后跟一个函数会导致该函数立即被调用,结果是创建的新对象。虽然涉及到一个函数,但该函数已被调用,Foo的值将是一个普通对象。在浏览器控制台中自己试试吧! - Pointy
显示剩余7条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接