参考 https://www.cnblogs.com/betarabbit/archive/2012/01/28/2330446.html
js的作用域
简单的理解是他是一种函数级作用域,即创建函数时,就会新开辟一个新的作用域。
var foo = 100;
function bar(){
console.log(foo); //undefined
if (!foo) {
var foo = 200;
console.log(foo); // 200
}
}
console.log(foo) // 100;
可以理解上面的一段代码中,函数bar
中的变量foo
与第一行代码的foo
只是名称相同,却不是同一个变量,他们处在不同的作用域里。简化一下 ,相当于以下代码
function bar(){...}
var foo;
foo = 100
这样简化下,不难理解console.log()
里打印出的数值。
JS中进入一个作用域有以下几种方法:
- 语言自身定义(language-defined):所有作用域都默认包含
this,arguments
- 函数形参(formal parameters): 函数的形参会进入到函数的作用域中
- 函数声明(function declaration): 函数声明
- 变量声明 (variable declaration)变量声明
P注意!函数声明和变量声明略有不同!以上声明的优先级逐渐降低。高优先级的会覆盖低优先级的!但仅仅是提升部分的优先级,后面的复制还是按照顺序赋值的!这里加了一些自己的代码试验。
JS解释器总是会把函数声明、变量声明提升到其所在的作用域的顶端,函数声明与变量声明不同的是,函数的声明和内容都会被提升,而变量仅仅声明被提升到顶端,内容(赋值)却没有被提升。
sayHi();
sayHello();
var name = 'Lily'
function sayHi(){
if(!name){
var name = 'LiLi'
}
console.log(name+' Hi')
return;
}
var sayHello = function(){
console.log('Lily'+' Hi')
return;
var content = ' Hello'
}
以上可以改写成如下代码,等价:
function sayHi(){
var name;
if(!name){
name = 'LiLi'
}
console.log(name+' Hi')
return;
}; //函数的声明和内容都被提升
var sayHello; //变量仅声明被提升
var name; //变量仅声明被提升
sayHi(); // LiLi Hi
sayHello(); // sayHello is not a function
name = 'Lily'
sayHello = function(){
console.log('Lily'+' Hi')
var content //无论生效与否都会被提升
return;
content = ' Hello'
}