预解释
在JS中如果,定义了一个变量同时赋值了,但是在定义之前使用的时候值是undefined,这情况我们称之为预解释,也称之为变量提升。
在当前的作用域中,JS代码执行之前,浏览器首先会默认的把所有的var和function进行提前的声明或者定义。预解释只发生在当前的作用域下。
在全局作用域中用var声明和不用var声明的区别:
用var 声明 : 可以进行预解释 不会报错 相当于给全局作用域增加了一个全局变量,也给window增加了一个属性名,对应的有属性值;
不用var 声明 : 不能进行预解释 会报错(is not defined) 相当于给window增加了一个属性名,对应的有属性值。
预解释是一种毫无节操的机制。
a) 在预解释的时候,不管if语句的条件是否成立,都要把带var的提前声明。
console.log('num' in window) //true
if(!('num' in window)){
var num = 12;
}
console.log(num) //undefined
b) 在预解释的时候,只预解释“ = ”左边的,右边的是值,不参与预解释。
匿名函数之函数表达式:把函数定义的部分当做一个值赋值给一个变量/元素的事件:
console.log(fn); //undefined
fn(); //fn is not a function
var fn = function(){
console.log('ok')
}
c) 自执行函数定义的function在全局作用域下不进行预解释,当代码执行到这个位置的时候定义和执行一起完成了。
d) 函数体中 return 下面的代码虽然不再执行了,但是需要进行预解释;return 后面跟着的都是返回值,所以不进行预解释。
function fn(){
console.log(num); //undefined
return function(){
num++;
}
var num = 10;
}
fn()
e) 在预解释的时候,如果名字已经声明过了,不需要重新声明,但是需要重新赋值,在js中,如果变量的名字和函数的名字重复了也算冲突。
fn(); //2
function fn(){console.log(1)};
fn(); //2
var fn = 10;
fn(); //fn is not a function
function fn(){console.log(2)}
fn();
函数和函数的名字重复,不管调用的顺序在哪里,都以后面声明的为准,
函数和变量的名字重复,不管二者的顺序前后,都以变量的值为准;
变量和变量的名字重复,以后面的值为准