1.作用域
實行上下文 (變量提早、函數聲明提早、肯定this值、arguments)
局限:一段<script>或許一個函數(都邑天生一個實行上下文)
全局(一段<script>):變量定義、函數聲明
函數:變量定義、函數聲明、this、arguments(參數鳩合)
變量提早代碼剖析:
consol.log(a) //undefined
var a = 100
(實行歷程:(1)變量定義提早 var a = undefined
(2)consol.log(a) //undefined
(3)a = 100 //賦值
)
函數聲明提早代碼剖析:
函數聲明: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 (實行時才確認,定義時沒法確認)
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.作用域鏈
自在變量:當前作用域沒有定義的變量
函數父級作用域:函數定義時的作用域(函數在哪定義,父級作用域在哪)
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)
相干題目:
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