var add = (function(){
var counter = 0;
return function(){
return counter += 1;
}
})();
add(); // 1
add(); // 2
add(); // 3
console.log(add()); // 4
闭包:
闭包可以理解成定义在一个函数内部(或对象内部)的函数可以访问该函数内部的变量或方法,但是外部不能访问,这个函数内部的函数在外部有引用时,不会被回收机制回收,并且连父级函数一起常驻与内存中。它的作用是可以使得私有变量变成可能。
函数的四种存在形式:
1.函数形态形式
var foo = function(){
alert(this); // this === window
}
2.方法形态形式
var o = {};
o.foo = foo;
o.foo(); // 弹出object
var lib = {
text:function(){
alert(this); // 弹出object
(function(){
alert(this); // 此处匿名函数不属于lib对象所有this任然是window
})()
}
}
3.构造器形式
var Person = function() {
this.age = 19;
this.name = 'Mr李';
return {}; // 默认不写retrun的话,返回undefined或null
}
var p = new Person();
alert(p.name); // undefined
var Person = function() {
this.age = 19;
this.name = 'Mr李';
return 123; // 非引用类型的话,使用new关键字return是对象的话使用对象,否则使用this
}
var p = new Person();
alert(p.name); // 'Mr李'
4.上下文调用模式
var fool = function(a, b) {
alert(this);
return a > b ? a : b;
}
var mun = fool.apply(null, [112,114]); // 此时this为window
var mun = fool.apply({}, [112,114]); // 此时this为{}
var mun = fool.call(null, 112, 114); // 此时this为window
var mun = fool.call({}, 112, 114); // 此时this为{}
// apply与call就是参数列表不一样,其他功能一致
// apply与call作用是改变this的指向,或用于继承
function a(name, age) {
this.name = name
this.age = age;
}
function b(name,age, sex) {
a.call(this, name, age);
this.sex = sex;
}
var tempObj = new b('李俊扬', 18, '男');
console.log(tempObj);
函数模块化介绍:
html:
<script src="/asset/main.js" data-page="a"></script>
JS:
let script = doucument.script[doument.script.length];
let pageName = script.getAttribute('data-page');
if (pageName === 'a') {
require(["./a.js"]);
} else if (pageName === 'b') {
requite(["./b.js"]);
}
一,原始写法, 缺点污染全局变量
function m1 {
// ...
}
function m2 {
// ...
}
二,对象的写法,缺点是对外暴露所有成员,变量可以被外部修改
var model1 = new Object({
_count: 0,
m1: function(){//...},
m2: function(){//...},
});
三,立即执行函数,对外没有暴露私有成员,变量不可以被外部修改了
var model1 = (function(){
var _count = 0;
var getCount = function(){//...};
var setCount = function(){//...};
return {
getCount: getCount,
setCount: setCount,
}
})();
四,放大模式,模块太大,必须分几部分,或者一个模块继承另一个模块
// 前提必须有一个jquery模块
var jquery$ = (function(mod){
mod.m1 = function(){//...};
})(jquery)
jquery$ = (function(mod){
mod.m2 = function(){//...};
})(jquery$)
五,宽大模式,模块由网络加载无法知道那个模块先加载
var jquery$ = (function(mod){
mod.m1 = function(){//...};
})(jquery || {})
独立性是模块的重大的特点,模块内部最好不要与程序其他部分直接交互。为了在函数内部调用全局变量,必须显示的将变量输入
var model = (function($, YAHOO){
// ....
})(jQuery, YAHOO);