1.做用域闭包
执行上下文 (变量提早、函数声明提早、肯定this值、arguments)app
范围:一段<script>或者一个函数(都会生成一个执行上下文) 全局(一段<script>):变量定义、函数声明 函数:变量定义、函数声明、this、arguments(参数集合)
变量提早代码解析:函数
consol.log(a) //undefined var a = 100 (执行过程:(1)变量定义提早 var a = undefined (2)consol.log(a) //undefined (3)a = 100 //赋值 )
函数声明提早代码解析:this
函数声明:function fn(){} 函数表达式:var fn = function(){} fn() function fn(){} (执行过程:(1)function fn(){} (2)fn() ) fn() var fn = function(){} (执行过程:(1)var fn = undefined (2)fn() (3)fn = function(){} )
this (执行时才能确认,定义时没法确认)code
this执行场景: (1)做为构造函数执行 function Foo(name){ // this = {} this.name = name // returen this } var fn = new Foo("lala") (2)做为对象属性执行 var obj = { name:"lala", printName: function(){ console.log(this.name) } } obj.printName();// 对象属性执行,this就是对象obj (3)做为普通函数执行 function fn(){ console.log(this) // window } (4)call、apply、bind function fn(name,age){ alert(name) console.log(this) //{x:100} } fn.call({x:100},"lala",13) //{x:100}当this fn.apply({x:100},["lala",13]) var fn = function fn(name,age){ alert(name) console.log(this) // }.bind({x:100}) //函数表达式.bind fn("lala",13)
做用域 JS没有块级做用域,只有函数和全局做用域对象
(1)无块级做用域 if(true){ var a = 10 } console.log(name) //name (2)函数做用域和全局做用域 var a = 10 //全局做用域(均可以访问获取) function fn(){ var a = 20 console.log(a) // 20 函数做用域(从外面得不到,也改不了) } console.log(a) //10 fn()
2.做用域链ip
自由变量:当前做用域没有定义的变量 函数父级做用域:函数定义时的做用域(函数在哪定义,父级做用域在哪) var a = 10 function fn1(){ var b = 20 function fn2(){ var c = 30 console.log(a) //10 a是自由变量 console.log(b) //20 b是自由变量 console.log(c) } fn2() } fn1() 做用域链:自由变量不断向父级做用域中寻找,造成链式
3.闭包
应用场景:(1)函数做为返回值作用域
function fn(){ var a = 10 return function(){ console.log(a) //10 } } var f1 = fn() var a = 20 f1()
(2)函数做为参数传递(函数传递到另外一个函数中执行)开发
function fn(){ var a = 10 return function(){ console.log(a) //10 } } var f1 = fn() function f2(f){ var a = 20 f() } f2(f1)
相关问题:io
1.理解变量提高 变量定义、函数声明被提高(到包含他们做用域的最顶端) 2.建立10个a标签,点击时弹出对应的序号 var i for(i = 0; i < 10; i++){ (function(i){ var a = document.creatElement("a") a.innerHtml = i a.addEventListerner("click",function(e){ e.preventDefault() alert(i) }) document.body.appendChild(a) })() } 3.实际开发中闭包的应用:封装变量,收敛权限 function isFirst(num){ var _list = [] // _list 下划线表示私有的 return function(){ if(_list.indexOf(num)){ return false }else{ _list.push(num) return true } } } var first = isFirst() first(10) // true first(10) // false first(20) // true