JavaScript中的变量作用域是什么?它们内部的作用域是否与外部的作用域相同?JS的作用域很重要吗?如果变量是全局定义的,这些变量都存在哪里了?
作用域在JavaScript中是比较重要的内容,这不像其它语言,JS没有块作用域,如下:
var name = "JavaScript"; // name属性在全局作用域下
for(var i = 0;i < name.length;i++){ // i属性同样在全局作用域下
console.log(name[i]);
}
for循环语句块不是一个作用域,在里面定义或声明的变量在语句块外都可以访问的,其它while语句等也是类型。
JavaScript只有三种作用域:全局作用域、函数作用域、eval作用域,常见的是全局作用域和函数作用域,关于作用域的概念可以参考JavaScript执行上下文的运行原理,作用域实际上是在创建执行上下文的时候创建的,执行上下文会创建一个作用域链,所在的执行环境访问变量是在作用域链中查找相应的变量的。
下面是理解JavaScript作用域的例子:
1、全局作用域变量
var value = "React";
function run(){
console.log(value); // 先查找run中的作用域没有value,于是到全局作用域中找到
}
2、函数本地作用域
var name = "Vue";
function speak(){
var name = "React";
console.log(name); // 输出React,先在当前作用域中查找name,找到则不再查找全局
}
3、函数作用域和全局作用域
var value = "JavaScript";
function run(){
if(false){
var value = "TypeScript";
}
console.log(value); // 输出undefined
}
run();
为什么输出undefined呢?这个同样和JavaScript的执行上下文有关,创建执行上下文的时候,vaule属性会预先在VO变量对象中赋值为undefined,尽管if语句块不会执行,但是在变量对象中还是存在value,所以在run内部访问value的时候会首先在当前作用域中查找,找到value则不再去全局作用域查找value。
4、闭包作用域
var name = "java";
function lang(){
var name = "javascript";
return function(){
console.log(name); // 输出javascript,lang上下文内存为释放,一直驻留在内存中
};
}
function run(){
var name = "python";
var fn = lang();
fn();
}
run();
这个例子同样和执行上下文有关,返回一个函数会造成函数的执行上下文驻留在内存中,以后调用该函数都是访问其上下文中的变量,与外部变量无关。
5、作用域和原型链
function User(){
this.name = "JS";
}
User.prototype.name = "PS";
var user = new User();
console.log(user.name); // 输出JS
user对象自己拥有一个name属性,调用的时候优先使用,而User的原型对象上的name属性不会被访问到。
评论前必须登录!
注册