var a = 1; var b = 2; function c(){} function d(){}
var space = { a: 1, b: 2, c: function () { console.log('我是c'); return this.a; }, d: function () { console.log('我是d'); return this.b; }, }; console.log(space.a); console.log(space.b); console.log(space.c()); console.log(space.d());
这样就把变量挂载到 space 上了,而不是全局 window 上javascript
function Class() { this.a = 1; this.b = 2; } Class.prototype.c = function () { console.log('我是c'); return this.a; }; Class.prototype.d = function () { console.log('我是d'); return this.b; }; var instance = new Class(); console.log(instance.a); //1 console.log(instance.b); //2 console.log(instance.c()); //我是c //1 console.log(instance.d()); // 我是d //2
面向对象必定程度上解决了命名冲突的问题,可是 js 没有私有变量,暴露内部变量,外部可有对内部数据进行修改外部能够修改内部数据css
(function (window) { let a = 1; let b = 2; function c() { console.log('我是c'); return a; } function d() { console.log('我是d'); return b; } window.module = { c:c, d:d, } })(window); //或者 var module = (function(){ let a = 1; ... function c(){ ... } ... return { a:a, c:c } })()
这一方式能够作到私有变量,模块的基本写法,好比 jqueryhtml
(function () { var a = 1; window.module = { c: function () { return a }, } })(); (function (mod) { var b = 2; mod.d = function () { return b } })(window.module) console.log(module.c()); console.log(module.d()); console.log(module);
能够实现模块的分离和模块的继承,也具备私有变量,还能够将自执行函数拆分红多个文件进行加载,可是文件的执行顺序有必定的要求,要先声明对象 module前端
//将上面给module添加功能的函数添加个默认值 (function (mod) { var b = 2; mod.d = function () { return b } })(window.module || {})
能够将模块分红不一样的文件,同时文件不用再考虑加载顺序不对致使 module 不存在的状况java
(function ($) { var a = 'red'; $('.hello').css({ "background": a }); })(jQuery)
自执行函数jquery
自执行函数中()分组操做符是用来将 function(){}这个函数声明转化为一种能够执行的表达式,单纯的 function(){}不是可执行的表达式,是一个函数声明
()分组操做符能够替换为其余操做符,好比 '#','+','-','!','void'......等等git
//这样写也是能够的 +function ($) { var a = 'red'; $('.hello').css({ "background": a }); }(jQuery)
function(){}是函数声明,声明的是一个匿名函数,而(function(){})()是一个表达式,而 js 在预编译阶段会解释函数声明,确会忽略表达式.因此到(function(){})的时候,该表达式会返回一个匿名函数,以后该匿名函数遇到后面的(),便会被执行github
var lis = document.querySelectorAll('li'); for(var i=0;i<5;i++){ lis[i].onclick = function(){ alert(i); //5,5,5,5,5 } } //又是这个经典的题目 //这题最简单仍是用元素属性的方式去解决,好比 for(var i=0;i<5;i++){ lis[i].index = i; lis[i].onclick = function(){ alert(this.index); //0,1,2,3,4 } } //还有就是闭包 for(var i=0;i<5;i++){ (function(i){ lis[i].onclick = function(){ alert(i); //0,1,2,3,4 } })(i) } //闭包就是在循环中执行,将i的值保存到当前做用域中,当click绑定的函数触发时,会优先从离得最近的做用域去拿变量(就近原则) //因此,使用其余的方式将当前i值保存到本身的做用域中就行 for(var i=0;i<5;i++){ click(i); } function click(i){ lis[i].onclick = function(){ alert(i); //0,1,2,3,4 } } //这其实就跟上面的闭包有些相似了,闭包取i是从上级的匿名函数的做用域中取保存的i,而该方式就是从click函数的做用域中去取i值