变量提升的理解js语言的执行规则:先定义,后执行变量定义、函数声明就属于定义代码的范畴(注意“函数声明”和“函数表达式”的区别)说明this几种不同的使用场景this 要在执行时才能确认值,定义时无法确认var a = { name: ‘A’, fn: function () { console.log(this.name); }};a.fn(); // this === aa.fn.call({name: ‘B’}); // this === {name: ‘B’}var fn1 = a.fn;fn1(); // this === window全局环境下的thisfunction fn() { console.log(this); // this === window}fn();对象方法中的thisvar obj = { name: ‘A’, printName: function () { console.log(this.name); // this === obj }};obj.printName();构造函数中的thisfunction Foo(name) { this.name = name; // this === f}var f = new Foo(‘can’);事件函数中的thisdocument.getElementById(‘div1’).onclick = function () { console.log(this); // this === <div id=“div1”>div1</div> 触发当前事件的Element对象};call apply bind 中的thisfunction fn1(name, age) { console.log(name, age); console.log(this); // this === {x:100}}fn1.call({x: 100}, ‘can’, 22);fn1.apply({x: 100}, [‘can’, 22]);var fn2 = function (name, age) { console.log(name, age); console.log(this); // this === {y:200}}.bind({y: 200});fn2(‘can’, 22);创建10个a标签,点击的时候弹出来对应的序号for (var i = 0; i < 10; i++) { (function (i) { // 函数作用域 var a = document.createElement(‘a’); a.innerHTML = i + ‘<br>’; a.addEventListener(‘click’, function (e) { e.preventDefault(); alert(i); // i 是自由变量,去父作用域寻找 }); document.body.appendChild(a); })(i);}作用域ES5中,无块级作用域if (true) { var name = ‘can’;}console.log(name); // ‘can’函数和全局作用域var b = 1;function fn3() { var b = 2; console.log(‘fn’, b); // 2}console.log(‘global’, b); // 1fn3();自由变量var a = 100;function fn4() { var b = 200; // 当前作用域没有定义的变量,即“自由变量” console.log(a); // 100 a 是自由变量,去父作用域寻找 console.log(b); // 200}fn4();一个函数的父级作用域,是它定义时的父级作用域,而不是执行时作用域链,即自由变量的查找var a = 100;function fn5() { var b = 200; function fn6() { var c = 300; console.log(a); // 100 a 是自由变量,去父作用域寻找 console.log(b); // 200 b 是自由变量,去父作用域寻找 console.log(c); // 300 } fn6();}fn5();闭包的使用场景1.函数作为返回值function fn1() { var a = 100; // 返回一个函数(函数作为返回值) return function () { console.log(a); // a是自由变量,去父作用域寻找 }}// f1 得到一个函数var f1 = fn1();var a = 200;f1(); // 1002.函数作为参数传递function fn1() { var a = 100; // 返回一个函数(函数作为返回值) return function () { console.log(a); // a是自由变量,去父作用域寻找 }}// f1 得到一个函数var f1 = fn1();function fn2(fn) { var a = 200; fn();}fn2(f1); // 100实际开发中闭包的应用闭包实际应用中主要用于封装变量,收敛权限function isFirstLoad() { var list = []; return function (id) { if (list.indexOf(id) > -1) { return false; } else { list.push(id); return true; } }}// 在 isFirstLoad 函数外面,不可能修改到 list 的值var firstLoad = isFirstLoad();firstLoad(10); // truefirstLoad(10); // falsefirstLoad(20); // true