javascript - JavaScript 中的 'new' 到底有什么作用?

标签 javascript oop

我对 JavaScript 中的构造函数如何工作感到非常困惑;尽管使用该语言已有多年(主要是它就像 Lisp 的半命令式版本),但我想更多地了解对象应该如何在其中工作。

鉴于此代码:

function Foo(x) {
    return {
        bar: function() { return x; }
    };
}

调用myFoo = Foo(5)有什么区别和myFoo = new Foo(5) ?或者,换句话说,JavaScript 中的构造函数到底是做什么的?

最佳答案

What is the difference between calling myFoo = Foo(5) and myFoo = new Foo(5)?

该代码没有区别,因为它返回一个对象,而 spec说:

  • Let result be the result of calling the [[Call]] internal property of F, providing obj as the this value and providing the argument list passed into [[Construct]] as args.
  • If Type(result) is Object then return result.

由于该函数返回一个对象结果,因此使用其结果。如果它不返回对象,或者它检查了 this,您会注意到差异,例如,如果您将其重写为:

function Foo(x) {
  if (!(this instanceof Foo)) { return new Foo(x); }
  this.bar = function() { return x; };
}
// Now instanceof works.
alert((new Foo) instanceof Foo);

What does new in JavaScript do, anyway?

new 运算符会调用函数,并将 this 绑定(bind)到新创建的 Object,其原型(prototype)是该函数的 prototype 属性。

对于用户定义的函数,

new f(a, b, c)

相当于

// Create a new instance using f's prototype.
var newInstance = Object.create(f.prototype), result;

// Call the function
result = f.call(newInstance, a, b, c),

// If the result is a non-null object, use it, otherwise use the new instance.
result && typeof result === 'object' ? result : newInstance

请注意,语言规范实际上定义了具有两个操作的函数,[[Call]][[Construct]] ,因此在某些极端情况下 new 的行为会很奇怪。

例如,绑定(bind)函数和内置函数:

var g = f.call.bind(f);

应该定义一个函数,在调用时只调用f,因此g在所有方面都应该与f相同,但是

new g()

产生

TypeError: function call() { [native code] } is not a constructor

因为内置函数Function.prototype.call支持[[Call]],但不支持[[Construct]]

Function.prototype.bindnew 和常规调用方面的行为也有所不同。 this 值在调用时始终是绑定(bind)的 thisValue,但在使用 new 时是新构造的实例。

关于javascript - JavaScript 中的 'new' 到底有什么作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27712703/

相关文章:

javascript - 将简单 View 模型与单个记录绑定(bind)

javascript - 引用另一个 .html 文件中的标签

c++ - 为什么在类外定义静态变量时需要重新指定数据类型

c - 人们真的用 C 做 OO 吗?

javascript - 当 ES6 中存在结构相似性时,减少分配对象属性的冗余

oop - 一个类在其自身上执行功能是好的约定吗?

javascript - 使用 javascript 将 HTML 转换为 Word

javascript - 这个函数可以用正则表达式重写吗?

Javascript 或 jQuery 正在缓存我的 javascript 变量。我该如何重置?

python - @classmethod 和 @staticmethod 对初学者的意义