在JavaScript中定义全局对象的独立于实现的版本
Defining an implementation independent version of the global object in JavaScript
我试图在JavaScript中定义global
对象,如下所示:
var global = this.global || this;
上面的语句在全局作用域中。因此,在浏览器中,this
指针是window
对象的别名。假设它是在当前网页的上下文中执行的第一行JavaScript, global
的值将始终与this
指针或window
对象的值相同。
在CommonJS实现中,如ringgojs和node.js, this
指针指向当前的ModuleScope
。但是,我们可以通过在ModuleScope
上定义的属性global
来访问global
对象。因此,我们可以通过this.global
属性访问它。
因此,这段代码片段在所有浏览器中工作,至少在ringgojs和node.js中,但我没有测试其他commjs实现。因此,我想知道如果这段代码不会产生正确的结果时,运行在任何其他CommonJS实现,如果是这样,我如何修复它。
最终,我打算在lambda表达式中使用它来实现独立的JavaScript框架,如下所示(来自jQuery的想法):
(function (global) {
// javascript framework
})(this.global || this);
this
与scope无关。
(function(){
(function(){
(function(){
(function(){
alert( this ); //global object
})()
}).bind({})()
}).apply({})
}).call({})
this
仅在函数调用时解析,归结为几个简单的规则。
- 如果函数作为某个对象的属性被调用,那么该对象将在函数内部的
- 如果函数按原样调用,
this
将是未定义的,因此在非严格模式下,它将是全局对象 - 如果使用
.call/.apply
调用函数,则this
由您自己显式设置。
this
undefined
。由于没有"use strict";
:
编辑:我现在在ringgojs中运行了一些快速测试,他们实际上把"全局对象"放在实际的全局对象(按标准定义)中,这是将ThisBinding设置为全局对象
ModuleScope
。仅仅因为在大多数js实现中实际的全局对象有object和String等等,如果对象下也有这些对象,就不会使对象全局。你可以在ringgojs中访问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"
咆哮,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" 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
成为全局对象。
实现独立版本不是小事
(function (global) {
// javascript framework
})(
this && this.global || // ringoJS
typeof root !== "undefined" && root || // node.js
typeof global !== "undefined" && global || // more node.js
typeof GLOBAL !== "undefined" && GLOBAL || // more node.js
typeof window !== "undefined" && window || // browsers
this // either undefined or some global default?
);
你必须在每个环境下硬编码特征检测
在阅读了Esailija和Raynos的答案后,我明白了我的代码this.global || this
将不适用于node.js中的所有情况;如果一个名为global
的变量已经存在于全局作用域中,它甚至可能在浏览器中失败。
Esailija指出this.global
并不是真正的global
对象,而this
是ringgojs中的global
对象;虽然我理解他的论点,但为了我的目的,我需要this.global
而不是this
。
Raynos建议我为每个CommonJS环境硬编码特征检测。然而,由于我目前只支持ringgojs和node.js,我只需要测试global
和window
。因此,我决定坚持使用this.global || this
。
然而,正如我之前所说的,this.global || this
并不适用于node.js中的所有情况,正如我从benvie的评论中所理解的那样。在node.js REPL中,我意识到我需要this
而不是this.global
。而this.global || this
表达this.global
。在node.js模块中,我需要this.global
而不是this
。但是,它表示this
,因为this.global
是undefined
。因此,为了解决这个问题,我最终决定使用以下代码:
(function (global) {
// javascript framework
})(typeof global !== "undefined" && global || this);
我使用这段代码的原因是因为在node.js模块this.global
是undefined
。因此我们必须直接使用global
。因此,我们使用typeof global !== "undefined" && global
在ringgojs和node.js中获得global
对象;我们使用this
作为浏览器中的global
对象(window
),并作为默认的回退。
注意:我没有提供在node.js REPL中查找global
对象的任何逻辑,因为我不相信我的框架将直接在REPL中使用。然而,正如benvie指出的那样,一旦理解了在node.js中查找global
对象的复杂性,编写查找它的逻辑应该是相当简单的。我知道我没有。
- 如何使用动画实现纸张推车
- 客户端服务器REST API captcha实现
- 如何实现此布局
- JS编译器/包管理器,用于版本控制
- jQuery-2.1.1.min.js或最新版本jQuery-2.13.min.js不会't支持'@
- Chrome加载旧版本的Javascript文件
- 如何使用js将SNAPSHOT内部版本号转换为3位数的整数
- Meteor忘记了密码的实现
- 如何实现数据()的非jQuery版本
- 如何在Javascript中通过版本控制实现状态同步
- 当浏览器开始实现JavaScript时,如何在支持一两个版本较旧的浏览器的同时开始使用它们
- JavaScript:任何计划在未来版本中实现线程
- 如何实现低版本android设备的SWIPE VIEW
- 如何在javascript和html中实现android低版本设备的onclick
- 试图实现d3.js版本4作为一个聚合物组件
- 在JavaScript中定义全局对象的独立于实现的版本
- IE8和更低的版本不支持HTML5.我们如何实现canvas
- 性能-数组.forEach vs .实现版本
- Java' Rhino实现实现了哪个JavaScript (ECMAScript)版本(更新策略是什么?)
- 为视力不佳的人实现网站版本的最佳解决方案