Aad*_*hah 6 javascript jquery global commonjs node.js
我试图global在一行中用JavaScript 定义对象,如下所示:
var global = this.global || this;
Run Code Online (Sandbox Code Playgroud)
以上陈述属于全球范围.因此,在浏览器中,this指针是window对象的别名.假设它是在当前网页的上下文中执行的第一行JavaScript,其值global将始终与this指针或window对象的值相同.
在CommonJS实现中,例如RingoJS和node.js,this指针指向当前ModuleScope.但是,我们可以global通过上面global定义的属性访问该对象ModuleScope.因此,我们可以通过this.global酒店访问它.
因此,此代码段适用于所有浏览器以及至少RingoJS和node.js,但我还没有测试过其他CommomJS实现.因此,我想知道当在任何其他CommonJS实现上运行时,此代码是否不会产生正确的结果,如果是,我将如何解决它.
最后,我打算在lambda表达式中使用它来实现我的实现独立JavaScript框架,如下所示(来自jQuery的想法):
(function (global) {
// javascript framework
})(this.global || this);
Run Code Online (Sandbox Code Playgroud)
this 与范围无关.
(function(){
(function(){
(function(){
(function(){
alert( this ); //global object
})()
}).bind({})()
}).apply({})
}).call({})
Run Code Online (Sandbox Code Playgroud)
this 仅在函数的调用时间内解决,并归结为一些简单的规则.
this在函数内部this则将是未定义的,因此在非严格模式下它将是全局对象.call/.apply然后this明确自己设置.正如您所看到的,它将属于规则#2,后者将解析为undefined.而且因为没有"use strict";:
将ThisBinding设置为全局对象
编辑:我现在在RingoJS中运行了一些快速测试,他们将"全局对象"放在实际的全局对象(由标准定义)中ModuleScope.仅仅因为大多数js实现中的实际全局对象具有Object和String等等,如果对象下面也包含那些对象,则不会使对象成为全局对象.您可以访问的原因String,并Object在RingoJS是因为他们把它们放进ModuleScope原型:
var logs = require('ringo/logging').getLogger("h");
logs.info( Object.getPrototypeOf( this ) === this.global );
//true
Run Code Online (Sandbox Code Playgroud)
进一步证明ModuleScope是实际的全局对象:
this.property = "value";
logs.info( property );
//"value"
Run Code Online (Sandbox Code Playgroud)
所以没有从这种技巧中获得任何东西,它没有解决任何问题:
function injectGlobal(){
globalProperty = "value"; // "use strict" would fix this!
}
injectGlobal()
logs.info( globalProperty );
//"value"
Run Code Online (Sandbox Code Playgroud)
Rant over,this已经根据本文前面给出的规则引用了实际的全局对象.this.global它不是标准定义的真正的全局对象,它只是一个容器.
此外,您可以在浏览器中模拟此行为:
考虑scopehack.js
this.global = window.global || top.global || {};
Run Code Online (Sandbox Code Playgroud)
考虑main.html:
<script src="scopehack.js"></script>
<script>
this.global.helloWorld = "helloWorld"; //"global scope"
this.helloWorld = "helloWorld" //"ModuleScope"
</script>
<iframe src="module.html"></iframe>
Run Code Online (Sandbox Code Playgroud)
最后一个"模块"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>
Run Code Online (Sandbox Code Playgroud)
module.html和main.html中哪一个是实际的全局对象?它仍然是this.
TLDR:
var obj = {
"String": String,
"Object": Object,
.....
};
Run Code Online (Sandbox Code Playgroud)
不会成为obj全局对象.
阅读 Esailija 和 Raynos 的答案后,我了解到我的代码this.global || this并不适用于 Node.js 中的所有情况;global如果全局作用域中已经存在调用的变量,它甚至可能在浏览器中失败。
Esailija 指出这this.global并不是真正的global对象,而是RingoJS 中的对象this;global尽管我理解他的论点,但出于我的目的,我需要this.global而不是…… this。
Raynos 建议我为每个 CommonJS 环境硬编码特征检测。然而,由于我目前仅支持 RingoJS 和 node.js,因此我只需要测试global和window。因此我决定坚持使用this.global || this.
尽管如此,正如我之前所说,this.global || this正如我从 Benvie 的评论中了解到的那样,它并不适用于 Node.js 中的所有情况。在node.js REPL 中,我意识到我需要this而不是this.global。然而,this.global || this表示this.global。在 node.js 模块中,我需要this.global而不是this。然而,它表示thissince this.globalis undefined。因此为了解决这个问题我最终决定使用以下代码:
(function (global) {
// javascript framework
})(typeof global !== "undefined" && global || this);
Run Code Online (Sandbox Code Playgroud)
我使用这段代码的原因是因为在 node.js 模块中this.global是undefined. 因此我们必须global直接使用。因此我们在RingoJS和node.js中都使用typeof global !== "undefined" && global来获取对象;global我们将其用作浏览器中的this对象global( window) 并作为默认后备。
注意:我没有提供任何global在 node.js REPL 中查找对象的逻辑,因为我不相信我的框架会直接在 REPL 中使用。global然而,正如Benvie 指出的那样,一旦理解了在 Node.js 中查找对象的复杂性,编写查找它的逻辑就应该相当简单了。我知道我不知道。
| 归档时间: |
|
| 查看次数: |
578 次 |
| 最近记录: |