[js] 闭包(old)
1.取函数内部的变量
2.让变量的值保持在内存中(滥用可能会导致内存泄漏)
#立即调用的函数表达式的各种写法 (IIFE)
// jshint expr: true (function() { // child scope })(); !function () { // child scope }(); +function () { // child scope }(); -function () { // child scope }(); ~function () { // child scope }(); void function () { // child scope }(); // maybe you're feeling whacky (hint: don't use these) 1^function () { // child scope }(); 1&function () { // child scope }();
#
(function(window) { var lastId = 0; var data = {}; function Lib() { var id = ++lastId; Object.defineProperty(this, '_id', { value: id }); //freeze data[this._id] = { state: 'idle' }; this.delay = 3000; } Lib.prototype.version = '0.0.1'; Lib.prototype.waitForNoReason = function(method) { data[this._id].state = 'waiting'; window.setTimeout(then.bind(this), this.delay); function then() { data[this._id].state = 'executing'; var update = done.bind(this); method(update); } }; function done() { data[this._id].state = 'done'; } Lib.prototype.getState = function() { return data[this._id].state; }; window.Lib = Lib; })(window); var instance = new Lib(); instance._id = 30; //不能改变 console.log(instance._id); // 1 console.log(instance.version); // '0.0.1' console.log(instance.delay); // 3000 console.log(instance.getState()); // <- 'idle' instance.waitForNoReason(function(done) { console.log(instance.getState()); // 'executing' done(); console.log(instance.getState()); // 'done' }); console.log(instance.getState()); // 'waiting' //1 //0.0.1 //3000 //idle //waiting //executing //done
#
var Cat = (function() { var sw = 0, count = 0; function o(name, weight) { if (!name || !weight) { throw 'error'; } count++; console.warn(count); this.name = name; w = weight; sw += w; Object.defineProperty(this, "weight", { set: function(newValue) { //设置属性触发 sw += newValue - w; w = newValue; }, get: function() { return w; }, enumerable: true, configurable: true }); } //console.info(sw, count);这里读取不到属性 o.averageWeight = function() { console.info(sw, count); return sw / count; } //用了prototype会被外部检测到详情。这里相当于一个对象属性 return o; }()); fluffy = new Cat('fluffy', 15); console.log(fluffy.name); console.log(fluffy.weight); //console.log(fluffy.averageWeight()); console.log(fluffy instanceof Cat); console.log(fluffy.averageWeight); console.log(typeof Cat.averageWeight); console.log(Cat.averageWeight()); garfield = new Cat('garfield', 25); console.log(garfield.name); console.log(garfield.weight); //console.log(garfield.averageWeight()); console.log(Cat.averageWeight()); garfield.weight = 35; console.warn(garfield.name); console.log(garfield.weight); //console.log(garfield.averageWeight()); console.log(Cat.averageWeight());
#保存局部变量
<body> <ul id='test'> <li>这是第一条</li> <li>这是第二条</li> <li>这是第三条</li> <li>这是第四条</li> </ul> <script> var list = document.getElementById("test").getElementsByTagName('li'); for (var i = 0; i < list.length; i++) { list[i].addEventListener('click', (function(a) { return function() { console.log(a); } })(i)) } </script> </body>