this
与范围无关。
(function(){
(function(){
(function(){
(function(){
alert( this ); //global object
})()
}).bind({})()
}).apply({})
}).call({})
this
仅在函数调用期间解决,归结为几个简单的规则。
- 如果函数作为某个对象的属性被调用,那么该对象将
this
在函数内部
- 如果函数按原样调用,
this
将是未定义的,因此在非严格模式下它将是全局对象
- 如果调用该函数,
.call/.apply
则由this
您自己显式设置。
如您所见,它属于规则 #2,它解析为undefined
. 而且由于没有"use strict";
:
将 ThisBinding 设置为全局对象
编辑:我现在在 RingoJS 中进行了一些快速测试,他们实际上将“全局对象”放在了实际的全局对象(由标准定义)中,即ModuleScope
. 仅仅因为大多数 js 实现中的实际全局对象都有 Object 和 String 等,如果它下面也有这些对象,则不会使对象成为全局对象。在 RingoJS 中可以访问的原因String
是Object
他们将它们放入ModuleScope
原型中:
var logs = require('ringo/logging').getLogger("h");
logs.info( Object.getPrototypeOf( this ) === this.global );
//true
进一步证明ModuleScope
是实际的全局对象:
this.property = "value";
logs.info( property );
//"value"
所以这种诡计没有任何收获,它不能解决任何问题:
function injectGlobal(){
globalProperty = "value"; // "use strict" would fix this!
}
injectGlobal()
logs.info( globalProperty );
//"value"
Rant over,this
指的是已经根据本文前面给出的规则的实际全局对象。this.global
不是标准定义的真正的全局对象,它只是一个容器。
此外,您可以在浏览器中模拟此行为:
考虑 scopehack.js
this.global = window.global || top.global || {};
考虑 main.html:
<script src="scopehack.js"></script>
<script>
this.global.helloWorld = "helloWorld"; //"global scope"
this.helloWorld = "helloWorld" //"ModuleScope"
</script>
<iframe src="module.html"></iframe>
最后是“模块”module.html:
<script src="scopehack.js"></script>
<script>
with( this.global ) { //poor mans RhinoJS scope injection, doesn't work for writing
console.log( helloWorld ); //"global scope" - "helloWorld"
console.log( this.helloWorld ); //"ModuleScope" undefined
}
</script>
哪个是 module.html 和 main.html 中的实际全局对象?它仍然是this
。
TLDR:
var obj = {
"String": String,
"Object": Object,
.....
};
不obj
生成全局对象。