正在封装外部jQuery脚本
Enclosing external jQuery script
我有一个外部JavaScript文件,它将用于包含许多其他脚本的页面。我的脚本包含了大量侦听事件的jQuery,并且在设计中,我声明了许多全局var。我一直在阅读最佳实践文章,其中有很多关于"污染全局命名空间"和无意中的脚本交互的内容。
封装JavaScript文件的最佳方式是什么
- 我仍然可以访问外壳外的变量
- jQuery事件侦听器将功能正常
我不能随意透露代码,所以即使是一般的回复也很感激。此外,欢迎提供任何其他提示,使脚本不易受到页面上其他脚本的攻击。
我发现了常规JavaScript的外壳样式,但是jQuery的使用会使其复杂化吗?
一般来说,这归结为将对象封装到一个"命名空间"中。我在这里使用引号是因为这个术语不是JavaScript中的官方语义,而是通过基本对象封装实现的。
有几种方法可以做到这一点,最终取决于个人偏好。
一种方法是只使用一个基本的JS对象,并将所有内容都保留在其中。对象的名称应该是语义的,并赋予对象一些意义,但除此之外,它的目的只是包装您自己的代码,并将其排除在全局名称空间之外。
var SomeName = {
alpha: 1,
beta: {a: 1, b: 2},
gamma: function(){
SomeName.alpha += 1;
}
}
在这种情况下,全局命名空间中只有SomeName。这种方法的一个缺点是,命名空间内的所有内容都是公共的,您必须使用完整的命名空间来引用对象,而不是使用"this"-例如,在SomeName.gamma中,我们必须使用SomeName.alpha来引用alpha的内容。
另一种方法是使命名空间成为具有属性的函数。这种方法的一个好特性是可以通过闭包创建"private"变量。它还允许您在没有完全命名空间引用的情况下访问封闭函数和变量。
var SomeName = (function(){
var self = this;
var privateVar = 1;
var privateFunc = function() { };
this.publicVar = 2;
this.publicFunc = function(){
console.log(privateVar);
console.log(this.publicVar); // if called via SomeName.publicFunc
setTimeout(function(){
console.log(self.publicVar);
console.log(privateVar);
}, 1000);
};
}();
这种方法的另一个好处是,它可以保护希望使用的全局变量。例如,如果您使用jQuery,并使用另一个创建$变量的库,您可以通过以下方法确保在使用$时引用jQuery:
var SomeName = (function($){
console.log($('div'));
})(jQuery);
一种方法是这样命名名称空间:
var MyNamespace = {
doSomething: function() {},
reactToEvent: function() {},
counter: 0
}
您只需要使用名称空间MyNamespace.reactToEvent
来引用函数或变量。这可以很好地分离window
(所有对抗都在那里)中通常会有的内容。
您可以将代码封装在一个匿名的Javascript函数中,只返回您想向外界公开的内容。您需要将var
作为全局变量的前缀,以便它们只保留在匿名函数的作用域中。类似这样的东西:
var myStuff = (function() {
var globalVar1;
var globalVar2;
var privateVar1;
function myFunction() {
...
}
function myPrivateFunction() {
...
}
return {
var1: globalVar1,
var2: globalVar2,
myFunction: myFunction
};
})();
现在您可以访问myStuff.var1
和myStuff.myFunction()
。
封装或限制命名空间污染的两种方法
1) 创建一个全局var,并将您需要的一切都放入其中。
var g = {};
g.somevar = "val";
g.someothervar = "val2";
g.method1 = function()
{
// muck with somevar
g.somevar = "something else";
};
2) 对于内联脚本,请考虑限制调用的函数的范围。
<script>
(
function(window)
{
// do stuff with g.somevar
if(g.somevar=="secret base")
g.docrazystuff();
}
)(); // call function(window) then allow function(window) to be GC'd as it's out of scope now
</script>
我刚开始使用RequireJS,现在已经痴迷于它了。
它基本上是一个模块化JavaScript格式的依赖关系管理系统。通过这样做,您实际上可以消除将任何内容附加到全局命名空间的情况。
好的是,您只引用页面require.js
上的一个脚本,然后告诉它先运行哪个脚本。从那里开始,一切都变得神奇。。。
下面是一个示例实现脚本:
require([
//dependencies
'lib/jquery-1.6.1'
], function($) {
//You'll get access to jQuery locally rather than globally via $
});
阅读RequireJS API,看看这是否适合您。我现在所有的剧本都是这样写的。这很好,因为在每个脚本的顶部,您都可以确切地知道与服务器端语言(Java或C#)相似的依赖项。
这是jQuery插件的常见做法,原因与您提到的相同:
;(function ($) {
/* ... your code comes here ... */
})(jQuery);
这是一个直接的功能。如果您在里面声明您的"全局"变量,它们将是这个闭包的本地变量(对于您在里面创建的代码来说仍然是"全局"的)。您的事件监听器也将在这里工作,您仍然能够访问真实的全局变量。
- JQuery添加元素需要在我的js之前再次添加JQuery脚本
- 导入jQuery脚本获胜'我不处理html文件
- 用于发现哪个JS/jQuery脚本正在冻结页面的工具或技术
- JQuery脚本在IE中不起作用
- 自定义jQuery脚本无法在Wordpress上运行
- jQuery脚本在googlechrome中不起作用
- 重新启动jquery脚本后,角度停止工作
- 一个简单的粘性头jQuery脚本的问题
- 如何让C#代码在页面加载时运行的jquery脚本之后运行
- 为什么我用于检查所需输入字段的jQuery脚本如此缓慢
- MVC5更改jquery脚本中的图像src
- Jquery脚本未在运行时加载编辑:意外的令牌
- 用于wooccommerce的简单JQuery脚本不起作用
- JQuery脚本没有'Don’我不能工作两次
- 在jQuery脚本中放置15秒的延迟
- jquery脚本只能在一个方向上正常工作
- 注入的元素和jQuery脚本.如何让他们一起工作
- 如果视图中没有Jquery脚本引用,Unobtrusive Javascript Validation是不起作用的
- 让两个 jquery 脚本像它们应该的那样协同工作
- 如何在 Django Form 中使用 Jquery 脚本的值