我不理解在不使用this
关键字时BigObject构造函数中的undefined
如何new
- 请参阅下面的示例。给出Firebug中的以下代码片段:
( function( global ){
"use strict";
var fromunderbutter = "fun";
global.BigObject = function( options ){
console.log( this );
console.log( this instanceof BigObject );
};
})( this );
以下代码有意义:
>>> var x = new BigObject();
>>> Object { } // new constructor creates blank object context that is assigned to BigObject
>>> true // BigObject was the object context ( this ) that invoked BigObject()
据我所知,this
指的是当前的对象上下文。在上面的示例中,由于new关键字,this
将引用一个空白对象,该对象将被新创建并应用于函数调用。
但是下一部分对我来说没有意义:
>>> BigObject()
>>> undefined
>>> false
为什么this
未定义?我假设this
会引用某些东西 - 可能是全局对象窗口。不确定如何考虑这个结果。
由于
答案 0 :(得分:4)
在严格模式下,在没有上下文的情况下调用函数时,this
为undefined
。
10.4.3 Entering Function Code # Ⓣ
当控件进入函数对象
F
中包含的函数代码的执行上下文,提供的调用者thisArg
以及调用者提供的argumentsList
时,执行以下步骤:
- 如果功能代码是严格代码,请将ThisBinding设置为
thisArg
。- 如果
thisArg
null 或未定义,请将ThisBinding设置为全局对象。- 如果
Type(thisArg)
不是Object,请将ThisBinding设置为ToObject(thisArg)
。- 否则将ThisBinding设置为
thisArg
。- 让
localEnv
成为调用NewDeclarativeEnvironment的结果,将[{Scope]] [{1}}的内部属性的值作为参数传递。- 将LexicalEnvironment设置为
F
。- 将VariableEnvironment设置为
localEnv
。- 让代码为
localEnv
的[[代码]]内部属性的值。- 使用功能代码
醇>F
和code
执行声明绑定实例化,如10.5中所述。
提供的代码是严格的代码,调用的argumentList
是thisArg
(没有为调用提供上下文)。
答案 1 :(得分:0)
如果没有元素事件,则无法定义。
答案 2 :(得分:0)
因为这就是语言规范所说的应该做的事情。
听起来像是一个翻转的答案,但事实并非如此。严格来说,这是任意的:你可以编写一个编译器来做任何事情,但是大多数可能想象的事情都是个坏主意。这些事情通常都有充分的理由。
在这种情况下,原因是当使用和不使用new时,相同的函数会执行完全不同的操作。这绝不是一个好主意。你可能会想出一个奇怪的案例,它可以做一些有用的事情,但是总会有更可读和可维护的方法来做同样的事情。
语言功能与法律相反:你不要仅仅因为需要超过三秒的时间来考虑任何理由,因为它们总是对绝对的每个人都是完全无法忍受的。只有当你有一个引人注目的,经过深思熟虑,经过充分研究和测试的理由,才能相信它们对很多人来说非常有用,并且几乎从不具有破坏性。或者,如果您正在设计Visual Basic或tcl,当然。
答案 3 :(得分:0)
如果您想解决此问题,请使用:
(function(global){
"use strict";
var fromunderbutter = "fun";
global.BigObject = function (options) {
if (!(this instanceof BigObject)) return new BigObject(options);
console.log(this);
console.log(this instanceof BigObject);
};
})(this);
正如zzzzBov所提到的,您需要绑定this
来模仿BigObject
this
才能使用您当前的代码。这需要做:BigObject.bind(new BigObject())({ /* options */ })
。这显然不是调用代码的理想方式。