1、作用域问题
-
全局作用域
var x = 0; var fn = function(){ var x = 2 } alert(x) //值为0
alert中的x拿到的是外层的x=0,无法取到函数局部作用域中的x=2
-
局部作用域
var x=0 var fn = function () { x = 2 } alert(x) //值为2
函数内部的变量x=2没有声明,声明提升,会在函数外部(函数的头上,也就是var-x=0的下面)声明这个x变量,因此x=2覆盖x=0
-
再来看一个例子
var x=2, y=3 fuction fn(i) { x = x+1 y = y+1 i = i+10 } alert(x) //3 alert(y) //4 alert(i) // i is not defined
x,y都有在全局作用域声明,i没有,所以在全局中不能调用到i
2、函数覆盖问题
-
var x = 0 // 匿名函数 var fn = function(){ x = 1 } alert(x) //1 fuction fn() { x = 2 } alert(x) //1
为什么两个结果都为1呢,因为上面的函数覆盖了下面的
如果不想函数覆盖,应该怎么做呢
-
var x = 0 fuction fn() { x = 2 } alert(x) //2 var fn = function () { x = 1 } alert(x) //1
没错,就是先写命名函数,再写匿名函数
所以,我们以后在项目中函数太多,可以写成匿名函数的形式来避免刚写的函数就被覆盖的情况
3、变量和函数的提升问题
1、函数未定义
console.log(x) //undefine
2、函数已定义
console.log(x) //undefine
var x = "123"
console.log(x) //123
没有函数,不会进行变量声明提升,代码只会从上到下执行
3、内部变量重复定义
var name = "Jack"
(fucntion () {
console.log(name) //undefined
var name = "Tom"
console.log(name) //Tom
})
第一个undefined,本来可以访问到外部的name,但是在函数内部重新声明了,name变量提升,就会出现undefined
这里典型的使用了函数声明提前,函数体内的块级作用域覆盖住了外部name的全局作用域,然后由于函数声明提升,相当于在函数体内先var-name,在console.log(name),所以undefined
因此,建议所有的变量,都放在头部,使用声明并且赋值这样的形式
4、函数定义提升
funcName() //我是funcNme
varName() //报错
function fn1() {
console.log("我是ffuncName")
}
var fn2 = function () {
console.log("我是varName")
}
函数fn1已经进行声明提升,fn2用变量来接收的函数不会进行函数声明提升
5、命名函数表达式
funcName() //报错 funcName is not defined
varName()
var varName = function funcName() {
console.log("猜猜我是谁")
}
同样的道理,全局变量不会进行声明提升
6、函数覆盖问题
var i = 1, j = k = 0
function add(n) {
return n += 1
}
console.log( add(i) ) //4
function add(n) {
return n += 3
}
在js函数中,是没有函数重载的.出现两个同名的函数,就会出现函数覆盖,第二个add函数,覆盖第一个add函数,然后,由于函数声明提前,就会直接将函数覆盖