###1. 执行上下文
-
范围:一段script 或者一个函数
-
全局:变量定义,函数声明 (一段script)
-
函数:变量定义,函数声明,this,arguments (函数)
console.log(a) // undefined var a=100; fn('zs')//zs,name function fn(name){ age =20; console.log(name,age) var age; }
###2. this
-
this在执行时确认,定义时无法确认
-
作为构造函数执行
-
作为对象属性执行
-
作为普通函数执行
-
call,apply,bind
function Foo(name){ this.name=name; } var f = new Foo('zs') var a={ name:'A', fn:function(){ console.log(this.name) } } a.fn()// this===a a.fn.call({name:"B"})// this==={name:"B} var fn1 = a.fn; fn1() //this===window function fn2(name) { alert(name) console.log(this) } fn2.call({x:100},'zs') // name:zs this:{x:100} 第一个参数为this,第二个参数为传入的参数 // bind 函数表达式 var fn3=function(name,age){ alert(name); console.log(this); // this:{y:200} }.bind({y:200}) fn3('zs',20)
###3.作用域
-
没有块级作用域,只用函数和全局作用域
-
一个函数的作用域是在函数定义的时候确定的,不是在执行的时候确定的
// 无块级作用域 if(true){ var name = "zs" } console.log(name) //函数和全局作用域 var a = 100; function fn(){ var a= 200; console.log('fn',a) } console.log('global',a) // 100 fn() // 200
###4.作用域链
-
自由变量
-
作用域链,自由变量的查找
-
闭包的两个场景
var a =100; function fn(){ var b=200; // 当前作用域没有定义的变量,即自由变量 console.log(a) console.log(b) } fn() function F1(){ var b=200; function F2(){ var c=300; console.log(a) console.log(b) console.log(c) } F2() } F1()
###5.闭包
-
封装变量,收敛权限
-
函数作为返回值
-
函数作为参数传递
function F1() { var a =100; // 返回一个函数(函数作为返回值) return function(){ console.log(a) // 自由变量,父作用域中寻找 } } var f1 = new F1(); var a=200; f1()// 100 // F1()(); // 100 function F2(fn) { var a=200; fn() } F2(f1) // 100
-
创建10个a标签,点击弹出对应的序号
//错误写法 var i, a for (i = 0; i < 10; i++) { a = document.createElement('a'); a.innerHTML = i + '<br>' a.addEventListener('click', function (e) { e.preventDefault() alert(i) // 自由变量 }) document.documentElement.appendChild(a) } //正确写法 var i for (i = 0; i < 10; i++) { (function (i) { // 传递i,作为函数内部变量 a = document.createElement('a'); a.innerHTML = i + '<br>' a.addEventListener('click', function (e) { e.preventDefault() alert(i) // 自由变量 }) document.documentElement.appendChild(a) })(i) } // 判断是否第一次登陆 function isFirstLoad(){ var _list =[] return function (id){ if(_list.indexOf(id)>=0){ return false; }else{ _list.push(id) return true } } } //使用 var firstLoad= isFirstLoad(); firstLoad(10)//true firstLoad(10)//false firstLoad(20)//true