JavaScript 中的 `new` 有什么作用呢? [英] What does `new` in JavaScript do, anyway?

查看:19
本文介绍了JavaScript 中的 `new` 有什么作用呢?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

鉴于此代码:

function Foo(x) {返回 {酒吧:函数(){返回x;}};}

调用 myFoo = Foo(5)myFoo = new Foo(5) 有什么区别?或者,换句话说,Javascript 中的构造函数究竟做了什么do?

解决方案

调用 myFoo = Foo(5)myFoo = new Foo(5) 有什么区别?

该代码没有区别,因为它返回一个对象,并且规范说:

<块引用>
  • result 是调用 F 的 [[Call]] 内部属性的结果,提供 obj 作为 this 值并提供作为参数传入 [[Construct]] 的参数列表.
  • 如果 Type(result)Object,则返回 result.

由于该函数返回的结果是一个对象,因此使用其结果.如果它没有返回一个对象,或者如果它检查了this,你会注意到一个不同,例如如果你把它改写为:

function Foo(x) {if (!(this instanceof Foo)) { return new Foo(x);}this.bar = function() { 返回 x;};}//现在 instanceof 起作用了.alert((new Foo) instanceof Foo);

<块引用>

JavaScript 中的 new 到底做了什么?

new 操作符导致函数被调用,this 绑定到一个新创建的 Object,其原型是该函数的 prototype 属性.

对于用户定义的函数,

new f(a, b, c)

相当于

//使用 f 的原型创建一个新实例.var newInstance = Object.create(f.prototype), result;//调用函数结果 = f.call(newInstance, a, b, c),//如果结果是非空对象,则使用它,否则使用新实例.结果&&结果类型 === '对象' ?结果:新实例

注意,语言规范实际上定义了两个操作的函数,[[Call]][[Construct]],所以在某些极端情况下 new 的行为很奇怪.

例如绑定和内置函数:

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

应该定义一个函数,调用时只调用f,所以g在各方面都应该和f相同,但是

new g()

生产

TypeError: function call() { [native code] } 不是构造函数

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

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

I am very confused about how constructors work in Javascrpt; despite using the language for several years (mostly as if it were like a semi-imperative version of LISP) I would like to know more about how objects are supposed to work in it.

Given this code:

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

What is the difference between calling myFoo = Foo(5) and myFoo = new Foo(5)? Or, in other words, what exactly does a constructor in Javascript do?

解决方案

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

There's no difference for that code, because it returns an object, and the spec says:

  • 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.

Since that function returns a result that is an Object, its result is used. You would notice a difference if it did not return an object, or if it checked this, for example if you rewrote it as:

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?

The new operator causes the function to be called with this bound to a newly created Object whose prototype is that function's prototype property.

For user-defined functions,

new f(a, b, c)

is equivalent to

// 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

Note, that the language specification actually defines functions with two operations, [[Call]] and [[Construct]], so there are some corner cases where new behaves oddly.

For example, bound and built-in functions:

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

should define a function that when called, just calls f, so g should be the same as f in all respects, but

new g()

produces

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

because the builtin function Function.prototype.call supports [[Call]] but not [[Construct]].

Function.prototype.bind also behaves differently around new and regular calls. The this value is always the bound thisValue when called, but is a newly constructed instance when you use new.

这篇关于JavaScript 中的 `new` 有什么作用呢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆