JS变量作用域
JS变量作用域
- JS严格模式以及非严格模式
- 非严格模式
- 严格模式
- 变量提升
- 全局作用域
- 名字空间
- 块级变量
JS严格模式以及非严格模式
非严格模式
在开头没有使用’use strict’;,如果声明变量的时候没有使用var的时候,javascript是将该变量作为全局变量的呦,其他与严格模式类似。
严格模式
在开头加上
'use strict';
便是严格模式,严格模式即声明变量的时候要带上var,不然会报错
'use strict';
//变量在函数中作用域就在该函数中,在外部引用会报错
function foo() {
var x = 1;
x = x + 1;
}
function bar() {
var x = 'A';
x = x + 'B';
}
'use strict';
//内部可以引用外部的,外部的不可以引用内部的变量
//如果外部与内部变量重名,引用会采取就近原则,如果找不到就外找,直到找到全局变量
//如果还找不到,只能返回undifined罗
function foo() {
var x = 1;
function bar() {
var y = x + 1; // bar可以访问foo的变量x!
}
var z = y + 1; // ReferenceError! foo不可以访问bar的变量y!
}
变量提升
JavaScript的函数定义有个特点,它会先扫描整个函数体的语句,把所有申明的变量“提升”到函数顶部:
'use strict';
//内部可以引用外部的,外部的不可以引用内部的变量
//如果外部与内部变量重名,引用会采取就近原则,如果找不到就外找,直到找到全局变量
//如果还找不到,只能返回undifined罗
function foo() {
var x = 'Hello, ' + y;
console.log(x);
var y = 'Bob';
}
//此时x的值为Hello,undifined
//因为JS会先扫描变量,然后在进行赋值
//此时y虽然已经声明,但是没有赋值,所以是默认的undifined
foo();
由于JavaScript的这一怪异的“特性”,我们在函数内部定义变量时,请严格遵守“在函数内部首先申明所有变量”这一规则。
全局作用域
不在任何函数内定义的变量就具有全局作用域。实际上,JavaScript默认有一个全局对象window,全局作用域的变量实际上被绑定到window的一个属性。
直接访问全局变量course和访问window.course是完全一样的。
由于函数定义有两种方式,以变量方式var foo = function () {}定义的函数实际上也是一个全局变量,因此,顶层函数的定义也被视为一个全局变量,并绑定到window对象。
名字空间
全局变量会绑定到window上,不同的JavaScript文件如果使用了相同的全局变量,或者定义了相同名字的顶层函数,都会造成命名冲突,并且很难被发现。
减少冲突的一个方法是把自己的所有变量和函数全部绑定到一个全局变量中。
也就是使用像Java的包减少命名的冲突。
'use strict';
// 唯一的全局变量package :
//只要该变量不重名即可,便于管理
var package = {
};
// 其他变量:
package.name = 'myapp';
package.version = 1.0;
// 其他函数:
package.foo = function () {
return 'foo';
};
块级变量
为了解决块级作用域,ES6引入了新的关键字let,用let替代var可以申明一个块级作用域的变量
'use strict';
function foo() {
var sum = 0;
for (let i=0; i<100; i++) {
sum += i;
}
// SyntaxError:
i += 1;
}
ES6标准引入了新的关键字const来定义常量,const与let都具有块级作用域
'use strict';
const PI = 3.14;
PI = 3; // 某些浏览器不报错,但是无效果!
PI; // 3.14
还没有评论,来说两句吧...