将窗口对象传递到Javascript命名空间中
Passing a window object into Javascript namespace
我试图更好地理解javascript中的名称空间,并找到了一个javascript立即调用函数表达式的例子,该表达式将窗口对象作为参数。这是它的代码:
var CG = CG || {};
CG.main = (function(window) {
var FOCAL_LENGTH = 8.0;
var context, width, height, startTime;
var init = function() {
var element = document.getElementById("canvas1");
context = element.getContext("2d");
width = element.width;
height = element.height;
startTime = (new Date()).getTime() / 1000.0;
tick();
}
var original_onload = window.onload || function() {};
window.onload = function() {
original_onload();
CG.main.init();
}
return {
init: init,
draw: draw_shape,
clear: clear_canvas
};
}(window));
在名称空间定义的末尾,有一行括号中有window,我对它的功能感到困惑。我认为将window的参数添加到定义末尾的目的是将全局窗口变量绑定到命名空间,然后命名空间将向窗口添加不同的属性,但我真的不能确定。
在另一个例子中,有一个随机变量名称被传递到命名空间的定义中,在命名空间定义的末尾,命名空间的实际名称被作为参数传递:
var namespace = namespace || {};
// here a namespace object is passed as a function
// parameter, where we assign public methods and
// properties to it
(function( o ){
o.foo = "foo";
o.bar = function(){
return "bar";
};
})(namespace);
console.log(namespace);
所以这里确实有几个问题:
在命名空间定义的末尾传递参数的功能是什么?
如果我对这一切的直觉是不正确的,那么这种名称空间创建javascript的一般结构是什么?
很明显,我对这件事很陌生,所以任何帮助都将不胜感激,谢谢。
我会尽力解释这一点,但我对它的理解来自Kyle Simpson。他太棒了,你应该去看看他-D
您正在询问一个关于立即调用函数表达式(IIFE)的问题,向它们传递参数,以及为什么有人会这样做。
首先,在这种情况下使用IIFE的原因是为了限制变量的范围。
这一点很重要,因为随着程序变得越来越大,添加了许多部分,您很容易在一个变量与另一个变量之间发生冲突。
app.js可能有
variable = "thing";
不久之后,Gelse.js可能会出现
variable = "not thing";
这是一个巨大的问题。在javascript中,可以通过创建立即运行并运行一次的"模块"或函数来避免这种情况。
这样,您在函数中创建的变量和方法就不会"污染全局范围/命名空间"
但是,如果您需要或希望全局窗口对象上有可用的内容,该怎么办?
好吧,您可以将它添加到"窗口"中,这是javascript中的全局范围。
(function Module(window){
var _thing = "private thing that only exists in this function";
window.thing = _thing;
//IS NOW AVAILABLE GLOBALLY AND EXPLICITLY ON WINDOW OBJECT
//window.onload you can wait for DOM/page before running the rest
})(window);
你也可以在你的函数中随意命名它:
(function niftyModule(global){
global.variable = "nifty text!";
})(window)
当您使用多个库时,这一点变得尤为重要。
出于某种原因,每个人都喜欢使用"$"作为他们库的表示,这样你就可以访问他们的私有方法(它们实际上也只是IIFE中的函数!(这是一种非常流行的构建好东西的方法)。
那么,如果您正在使用jQuery和另外两个同样使用$访问其公共方法/api的库,该怎么办??
很简单,您可以通过将函数/模块范围内的变量作为参数传入,来指定要指定的变量!
(function NiftyModule(window, $){
//Now, every time you use $ in here it means jQuery and not something else!
})(window, jQuery);
重要的是要充分考虑功能和范围。以不同的方式构建一些变量。
例如,is…
var text = "nifty text";
与相同
text = "nifty text";
如果你在函数内部做同样的事情呢?这两个版本有何不同?
此外,要习惯于在IIFE中构建自己的程序,并适当地限制您正在编写的代码的范围。
您还可以从函数中返回对象,这些函数具有要全局访问的方法和变量,而无需将它们添加到窗口对象中。
一开始它很复杂,但将来它会为你省去很多麻烦和bug!
最后,在你的例子中:
//initialize a global variable called namespace. If this already
//existed then assign it the previous values. If not, make it an empty
//object.
var namespace = namespace || {};
//pass namespace into an IIFE. Within the IIFE refer to namespace as "o"
(function( o ){
//assign a variable to namespace
o.foo = "foo";
//assign a method to namespace
o.bar = function(){
return "bar";
};
})(namespace);
//now when you log namespace it will have those properties.
console.log(namespace);
- 如何使用javascript命名空间
- 转换自的JavaScript命名空间
- 在Firebug控制台中监视javascript命名空间变量
- 怎么了?通过字符串定义 JavaScript 命名空间
- Javascript 命名空间/最佳实践
- IE中的Javascript命名空间抛出错误
- 将索引值传递给javascript命名空间数组
- 如何正确设置 JavaScript 命名空间和类
- 在 JavaScript 命名空间中共享变量
- socket.io + Sencha 中的 JavaScript 命名空间问题
- Javascript命名空间 - 是这种特殊方法的良好实践
- 如何在 Javascript 命名空间脚本中创建函数数组
- 将单个项添加到 javascript 命名空间
- 新的 Google reCAPTCHA JavaScript 命名空间回调
- Javascript 命名空间在从函数返回数组时出现问题
- 如何将原型模式引入 javascript 命名空间
- Javascript - 命名空间与闭包之间的区别
- Javascript 命名空间就绪函数
- 使用 Javascript 命名空间/singleton 将不接受传递给成员方法的参数
- JavaScript命名空间是否被污染了