var items = document.querySelector('li') //items是一个类数组对象
for(var i = 0; i<items.length; i++) {
items[i].onclick = function() {
console.log(i)
}
}
首先,我们要理解变量的生命周期,举个例子
function f1() {
var a = 1
return undefined
}
f1() //这一行执行,a就诞生了
//执行完了之后,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
}
这个例子当中,f3()中的a指的就是最外部的a,不管f3有没有执行,只需要看函数与函数之间的父子关系。
立即执行函数的意义
为什么会有立即执行函数? 是因为为了不产生全局变量,防止全局污染
一般比较推荐的写法
!function() {
var a = 1
console.log(a)
}()
function sss(p1, p2) {
}
//基本等价于
function sss() {
var p1 = arguments[0]
var p2 = arguments[1]
}
arguments对应于传递给函数的参数的类数组对象。
举个例子
!function(a) {
a = 1
console.log(a)
}()
//相当于
!function() {
var a = arguments[0] //没有传参,undefined,函数里面的a不是指全局的a
a = 1
console.log(a)
}(/*没有参数*/)
所以像下面这样:
var a = 100;
!function(a) {
a = 1
console.log(a) //输出1
}(/*没有传参*/)
console.log(a) // 输出100
变量提升
在执行代码之前,把所有的声明提升到作用域的顶部,只要提升变量,面试题就是小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先执行
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先执行
如果希望输出不同的数字,可以这样:在函数当中创建一个新的作用域,跟外面一点关系都没有,就像这个样子
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) //这样就可以了
继续演化
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)
}
闭包的作用
暴露局部变量,把局部变量通过函数暴露给外部