javascript进阶系列专题:作用域与作用域链

 

 字面意思,作用域是指变量和函数的作用范围,换言之,作用域决定了变量和函数的可见性和有效时间。javascript作用域是用函数来区分,与其他语言的大括号不同。
for (var i=0; i<5; i++){
    var mystring = "平底斜";
    console.log(i); 
}
alert(mystring);//弹出"平底斜"

    这段代码在javascript中运行正常,在其他语言中就会报错。这是因为javascript的作用域是基于函数,而不是大括号。

    作用域分为全局作用域和局部作用域。

    有三种情况会出现全局作用域:

    1、最外层定义的变量和函数

var mystring = "平底斜";
function fun(){
    alert("Hello World");
}

    变量mystring和函数fun()拥有全局作用域,在任何位置都可以直接调用。

    2、未定义的变量

复制代码
function fun(){
    var   a=b=0;
    mystring = "平底斜";
    console.log(mystring);
}
fun();
alert(b);
复制代码

    变量mystring没有使用var进行变量声明,所以即使在函数内部也是全局变量。容易忽略的是变量b,看上去使用var进行了声明,实际上只对变量a进行了声明,等同于

function fun(){
    var a=(b=0); //自右向左赋值
    mystring = "平底斜";
    console.log(mystring);
}

    一个JS文件中应该尽可能少的出现全局变量,最佳实践是使用var进行变量声明,并且在声明的同时进行赋值。

function fun(){
    var a=0, b=1, c=2; //等同于var a=0; var b=1; var c=2;
}
fun(); alert(c); //脚本报错,因为c是局部变量

    3、全局对象window

var mystring = "平底斜";
console.log(mystring); console.log(window.mystring); console.log(window["mystring"]); console.log(this.mystring); console.log(this["mystring"]);//此处this就是window,针对this以后会专题讲解

    全局变量都可以看做window的属性,使用方法就如以上代码:可以用"."也可以用"[]"甚至可以省略window

    局部变量只有一种情况:在函数内部声明的变量拥有局部作用域

function fun(){
    var mystring="平底斜"; //局部变量
    console.log(mystring);
}
fun();
console.log(mystring); //脚本报错

    冷知识:

    全局变量中,使用var声明与不使用var是有区别的,var声明的变量无法删除,未声明的变量可以删除。

var mystring="平底斜";
newstring = "博客园";
delete mystring;
delete newstring;
console.log(mystring);  //"平底斜"
console.log(newstring); //脚本报错

    作用域链由内向外查找变量,在内部找到变量便停止查找,否则往上一层作用域查找,直到最外层都没有找到变量则返回undefined

var myscope = "平底斜";
function fun(){
    var myscope = "博客园";
    console.log(myscope); //"博客园"
}
fun();

    上面这段代码,就是因为作用域链有内向外,先在函数内部查找myscope,找到了就直接返回该变量值,并停止查找。

    易错点:

复制代码
var myscope = "平底斜";
function fun(){
    console.log(myscope); //脚本报错
    var myscope = "博客园";
    console.log(myscope); //"博客园"
}
fun();
复制代码

    声明变量会在当前作用域中置顶,又叫变量提升或者声明置顶。以上代码等同于:

复制代码
var myscope = "平底斜";
function fun(){
    var myscope;
    console.log(myscope); //脚本报错
    myscope = "博客园";
    console.log(myscope); //"博客园"
}
fun();
复制代码

    需要注意的是变量提升是在函数定义时发生,并不是在函数调用时:

复制代码
var myscope = "平底斜";
function fun1(){  
    console.log(myscope);
}
function fun2(){ 
var myscope = "博客园";
fun1();
}
fun2(); //"平底斜"
复制代码

     如上,fun2()调用fun1()时,是先在fun1()中搜索myscope,找不到时再到父级作用域中查找。作用域的嵌套关系是在定义时产生,而不是在调用的时候。

转载于:https://www.cnblogs.com/coolfireW/articles/5078061.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值