var items = document.querySelector('li') //items是一個類數(shù)組對象
for(var i = 0; i<items.length; i++) {
items[i].onclick = function() {
console.log(i)
}
}
首先,我們要理解變量的生命周期歪泳,舉個例子
function f1() {
var a = 1
return undefined
}
f1() //這一行執(zhí)行萝勤,a就誕生了
//執(zhí)行完了之后,a就死亡
如果變量被引用著呐伞,那么就不能死敌卓,也就是說不能被回收,比如
function f1() {
var a = 1
wondow.xxx = a //a被外部引用伶氢,所以a不能死
return undefined
}
f1()
如果指定新的值趟径,那么a才會死亡
function f1() {
var a = 1
wondow.xxx = a
return undefined
}
f1()
window.xxx = {name: 'b'} //這個時候被重新賦值了
就近原則
var a
function f1() {
var a
function f2() {
var a
a = 1
}
}
作用域只看父級
var a
function f1() {
var a
function f2() {
var a
f3()
a = 1
}
}
function f3() {
a = 2
}
這個例子當(dāng)中,f3()中的a指的就是最外部的a癣防,不管f3有沒有執(zhí)行蜗巧,只需要看函數(shù)與函數(shù)之間的父子關(guān)系。
立即執(zhí)行函數(shù)的意義
為什么會有立即執(zhí)行函數(shù)蕾盯? 是因為為了不產(chǎn)生全局變量钟哥,防止全局污染
一般比較推薦的寫法
!function() {
var a = 1
console.log(a)
}()
function sss(p1, p2) {
}
//基本等價于
function sss() {
var p1 = arguments[0]
var p2 = arguments[1]
}
arguments對應(yīng)于傳遞給函數(shù)的參數(shù)的類數(shù)組對象。
舉個例子
!function(a) {
a = 1
console.log(a)
}()
//相當(dāng)于
!function() {
var a = arguments[0] //沒有傳參硫豆,undefined,函數(shù)里面的a不是指全局的a
a = 1
console.log(a)
}(/*沒有參數(shù)*/)
所以像下面這樣:
var a = 100;
!function(a) {
a = 1
console.log(a) //輸出1
}(/*沒有傳參*/)
console.log(a) // 輸出100
變量提升
在執(zhí)行代碼之前渺尘,把所有的聲明提升到作用域的頂部,只要提升變量说敏,面試題就是小case
function a() {}
var a = 100
console.log(a) //輸出100
//可以這樣看鸥跟,變量提升
var a
function a() {}
a = 100
console.log(a) //輸出100
例子
var a = 100
f1()
function f1() {
var b = 2
if(b === 1) {
var a
}
a = 99
}
//變量提升的寫法是這個樣子的
var a
function f1() {
var b
b = 2
var a
if(b === 1) {
}
a = 99
}
a = 100
f1()
時機(異步)
btn.onclick = function() {
console.log('A')
}
console.log('B')
//B一定會比A先執(zhí)行
var items
var i
items = document.querySelectorAll('li')
for(i = 0; i<items.length; i++) {
items[i].onclick = function() {
console.log(i) //C
}
}
console.log(i) //D //D比C先執(zhí)行
如果希望輸出不同的數(shù)字,可以這樣:在函數(shù)當(dāng)中創(chuàng)建一個新的作用域盔沫,跟外面一點關(guān)系都沒有医咨,就像這個樣子
var items
var i
items = document.querySelectorAll('li')
for(i = 0; i<items.length; i++) {
var temp = function(j) {
console.log(j)
}
temp(i)
items[i].onclick = function() {
console.log(i)
}
}
console.log(j) //這樣就可以了
繼續(xù)演化
var items
var i
items = document.querySelectorAll('li')
for(i = 0; i<items.length; i++) {
!function(j) {
console.log(j)
items[j].onclick = function() {
console.log(j)
}
}(i)
}
var items
var i
items = document.querySelectorAll('li')
for(i = 0; i<items.length; i++) {
function temp(j) {
return function() {
console.log(j)
}
}
var fn = temp(i)
items[i].onclick = fn
}
var items
var i
items = document.querySelectorAll('li')
for(i = 0; i<items.length; i++) {
items[i].onclick = function(i) {
return function() {
console.log(i)
}
}(i)
}
閉包的作用
暴露局部變量,把局部變量通過函數(shù)暴露給外部