JavaScript立即执行函数学习
1.新建对象,方法内变量作用域理解错误
var md1 = { count: 0, add: function () { count++; }, sub: function () { count--; }, show: function () { console.log(count); } }; md1.add(); md1.add(); md1.show();
在不加this的情况之下,会试图与当前对象的作用域内寻找count。如果硬要这样写,就必须加入一个全局变量(或者在上级作用域内有count)count,如下。
var count = 100; var md1 = { count: 0, add: function () { count++; }, sub: function () { count--; }, show: function () { console.log(count); } }; md1.add(); md1.add(); md1.show();
当然,正确的方法是如下这样。
var md1 = { count: 0, add: function () { this.count++; }, sub: function () { this.count--; }, show: function () { console.log(this.count); } }; md1.add(); md1.add(); md1.show();
但是这样也不好,会暴露count这个理应是私有的成员,可直接在外部代码之中修改count,如下
var md1 = { count: 0, add: function () { this.count++; }, sub: function () { this.count--; }, show: function () { console.log(this.count); } }; md1.add(); md1.add(); md1.count = 100; md1.sub(); md1.add(); md1.show();
2.立即执行函数式,这种方式可以屏蔽count
var md1 = (function () { var count = 0; var add = function () { count++; }; var sub = function () { count--; }; var show = function () { console.log(count); }; return { add: add, sub: sub, show: show }; })(); md1.add(); md1.add(); md1.count = 100; md1.sub(); md1.add(); md1.show();
3.放大模式,用于向已有模块里面添加新的公共成员
var md1 = (function () { var count = 0; var add = function () { count++; }; var sub = function () { count--; }; var show = function () { console.log(count); }; return { add: add, sub: sub, show: show }; })(); var md2 = (function (md) { md.add2 = function () { md.add(); md.add(); }; return md; })(md1); md1.add(); md1.add(); md1.sub(); md2.add2(); md1.show(); md2.show();
4.宽放大模式
var md1 = (function () { var count = 0; var add = function () { count++; }; var sub = function () { count--; }; var show = function () { console.log(count); }; return { add: add, sub: sub, show: show }; })(); var md2 = (function (md) { md.add2 = function () { md.add(); md.add(); }; return md; })(md1 || {}); md1.add(); md1.add(); md1.sub(); md2.add2(); md1.show(); md2.show();
独立性是模块的重要特点,模块内部最好不与程序的其他部分直接交互。
为了在模块内部调用全局变量,必须显式地将其他变量输入模块。
var module1 = (function ($, YAHOO) {
//...
})(jQuery, YAHOO);
上面的module1模块需要使用jQuery库和YUI库,就把这两个库(其实是两个模块)当作参数输入module1。这样做除了保证模块的独立性,还使得模块之间的依赖关系变得明显。这方面更多的讨论,参见Ben Cherry的著名文章《JavaScript Module Pattern: In-Depth》。
这个系列的第二部分,将讨论如何在浏览器环境组织不同的模块、管理模块之间的依赖性。