JavaScript库的代码模式
在JavaScript库(jQuery、MathJax、Markdown渲染库等)中,我经常看到各种模式: 模式#1 index.htmlJavaScript库的代码模式,javascript,design-patterns,Javascript,Design Patterns,在JavaScript库(jQuery、MathJax、Markdown渲染库等)中,我经常看到各种模式: 模式#1 index.html ... <script src="mylibrary.js"></script> </body> </html> <html> <head> ... <script src="mylibrary.js"></script> </head> <b
...
<script src="mylibrary.js"></script>
</body>
</html>
<html>
<head>
...
<script src="mylibrary.js"></script>
</head>
<body>
...
</body>
</html>
<html>
<head>
...
<script src="mylibrary.js"></script>
</head>
<body>
...
<script>
mylibrary.run(); // explicitly needs to be run
</script>
</body>
</html>
模式#2 index.html
...
<script src="mylibrary.js"></script>
</body>
</html>
<html>
<head>
...
<script src="mylibrary.js"></script>
</head>
<body>
...
</body>
</html>
<html>
<head>
...
<script src="mylibrary.js"></script>
</head>
<body>
...
<script>
mylibrary.run(); // explicitly needs to be run
</script>
</body>
</html>
...
...
相同的mylibrary.js
var mylibrary = (function() {
...
var myVar = ...
...
})();
模式#3 index.html
...
<script src="mylibrary.js"></script>
</body>
</html>
<html>
<head>
...
<script src="mylibrary.js"></script>
</head>
<body>
...
</body>
</html>
<html>
<head>
...
<script src="mylibrary.js"></script>
</head>
<body>
...
<script>
mylibrary.run(); // explicitly needs to be run
</script>
</body>
</html>
...
...
mylibrary.run();//显式地需要运行
相同的mylibrary.js
var mylibrary = (function() {
...
var myVar = ...
...
})();
问题:
var mylibrary=(function(){…})()的用途是什么代码>技巧
看起来这两个都很有趣。例如:模式#2是有意义的(它将自动划分DOM并呈现数学公式),这是他们选择的(请参阅)。模式#3,要求实际运行渲染的操作也有意义
var exampleGlobal = "I'm an example global variable";
function one() {
exampleGlobal = 1;
}
....
function two() {
exampleGlobal.charAt(0);
}
one(); // Changes the exampleGlobal to a Number
two(); // Tries to use a string-based instance method but throws an error since exampleGlobal is now a number
在这里,我们看到exampleGlobal
已公开并可用于此脚本中的所有函数。在这种情况下,在脚本中的任何位置都很容易出错并更改此变量的值/用途。这里是生命发挥作用的地方:
var exampleModule = (function() {
var privatized = "I'm only accessible within this module";
return {
privatized: privatized
}
}());
在上面,我们只创建了一个全局变量,作为一个模块,并封装了只与它相关的值/函数。尝试全球私有化。您会发现,除非显式调用该模块及其返回值,否则它将返回undefined,因为它在全局范围内不可用:
var exampleModule = (function() {...}());
console.log(privatized); // undefined
console.log(exampleModule.privatized); // returns: "I'm only accessible within this module"
iLife的优势还在于,您可以安全地避免应用程序中可能出现的命名冲突。例如,jQuery和Mootools共享$
字符来调用各自的函数调用。如果希望安全地使用jQuery而不与Mootools发生任何冲突,可以将$
对象作为参数传递到IIFE中,这样将使其不受全局范围的影响
(function($) { // Here this is just the parameter we'd like to refer jQuery as
$('div');
}(jQuery)); // You pass in the actual jQuery object here which is when/where the function is immediately invoked.
var exampleGlobal = "I'm an example global variable";
function one() {
exampleGlobal = 1;
}
....
function two() {
exampleGlobal.charAt(0);
}
one(); // Changes the exampleGlobal to a Number
two(); // Tries to use a string-based instance method but throws an error since exampleGlobal is now a number
在这里,我们看到exampleGlobal
已公开并可用于此脚本中的所有函数。在这种情况下,在脚本中的任何位置都很容易出错并更改此变量的值/用途。这里是生命发挥作用的地方:
var exampleModule = (function() {
var privatized = "I'm only accessible within this module";
return {
privatized: privatized
}
}());
在上面,我们只创建了一个全局变量,作为一个模块,并封装了只与它相关的值/函数。尝试全球私有化。您会发现,除非显式调用该模块及其返回值,否则它将返回undefined,因为它在全局范围内不可用:
var exampleModule = (function() {...}());
console.log(privatized); // undefined
console.log(exampleModule.privatized); // returns: "I'm only accessible within this module"
iLife的优势还在于,您可以安全地避免应用程序中可能出现的命名冲突。例如,jQuery和Mootools共享$
字符来调用各自的函数调用。如果希望安全地使用jQuery而不与Mootools发生任何冲突,可以将$
对象作为参数传递到IIFE中,这样将使其不受全局范围的影响
(function($) { // Here this is just the parameter we'd like to refer jQuery as
$('div');
}(jQuery)); // You pass in the actual jQuery object here which is when/where the function is immediately invoked.
myVar
外部mylibrary
myVar
外部mylibrary
谢谢@lexicore。如果我把脚本放在
中,如果这个脚本使用iLife,它会在DOM完成后执行还是在加载后立即执行?@Basj通过在注释中提出更多的问题,你已经足够宽泛了。你自己做一个快速搜索怎么样?例如,为了找到类似这样的内容。我最后做了@lexicore,发现即使我使用iLife,如果
在实际正文内容之前,它也无法查看此正文内容。谢谢@lexicore。如果我把脚本放在
中,如果这个脚本使用iLife,它会在DOM完成后执行还是在加载后立即执行?@Basj通过在注释中提出更多的问题,你已经足够宽泛了。你自己做一个快速搜索怎么样?例如,我最终找到了@lexicore,发现即使我使用iLife,如果
在实际正文内容之前,它也无法查看此正文内容。请参阅我更新的ans