例说javascript作用域

我们来看下面的几个小例子

1 首先来个最简单的:

var a = 1;
function test1(){
  console.log(a);
}
test1();   //=>1

这个程序输出1肯定没什么问题了,函数局部作用域内没有局部变量a,因此沿着作用域链向上查找,找到了全局变量a,于是输出。

2 接下来添加个局部变量:

var a = 1;
function test1(){
  var a = 2;
  console.log(a);
}
test1();   //=>2

这段程序输出2,因为沿着作用域链向上查找时,首先找到的是局部变量a是2,于是将2输出.

3 继续变形

var a = 1;
function test1(){
  console.log(a);
  var a = 2;
  console.log(a);
}
test1();   //=>undefined 2

这时第一个console.log(a)输出undefined,第二个输出2,第二个其实不难理解,但是有可能有人不能理解第一个为什么会输出undefined。其实主要是变量声明提升(javascript引擎在执行时,会把所有的变量的声明都提升到当前作用域的最前端)的问题,即上面的代码相当于

var a = 1;
function test1(){
  var a;
  console.log(a);
  a = 2;
  console.log(a);
}
test1();

这时,当第一次要输出a时,程序会首先在局部作用域中查找a,在这个函数中,程序找到了变量a,故不会继续沿着作用域链向上查找,但是这里的a只声明了并没有进行初始化,故默认为undefined。

4 接下来,看一下下面的代码会输出什么

var a = 1;
function test2(){
  console.log(a);
}
function test1() {
  var a = 2;
  test2();
}
test1();

输出的是1 ,为什么呢,我们要清楚,在test1中,我们只是让test2函数执行了,而test2仍在全局环境中,并不是test1的局部环境,故test2根本不会访问到位于test1局部环境中的a。

5 对4中的代码进行修改,我们来看一下将test2定义在test1中的情况

var a = 1;
function test1() {
  var a = 2;
  function test2(){
    console.log(a);
  }
  test2();
}
test1();

这样一来,test2在test1的局部环境中,a自然就会输出2。

6 接下来我们来看看对象中的方法

var a = 1;
var b = {
    a: 	2,
    show:function(){
	console.log(a);
   }
}
b.show();  //=>1

单纯的这样看这段代码为什么会输出1可能会不太明显,但是如果稍微转换一下,就很好明白了。

var b = {
    a: 	2,
    show:function(){
	console.log(a);
   }
}

其实是相当于

var b = {};
b.a = 2;
b.show = function(){
  console.log(a);
}

这样很明显就看出a应该是全局环境中的a了.

7 与上面例子类似的,看下面的代码:

var a = 1;
var b = {
    a: 	2,
    show:function(){
	console.log(this.a);
   }
}
b.show();  //=>2

上面是经常使用的,定义对象的方式,使用了this关键字,将a与当前的执行对象绑定,输出的是当前执行对象的a属性,故输出2.

8 再继续对上面的例子进行变形

var a = 1;
var b = {
    a: 	2,
    show:function(){
	console.log(this.a);
   }
}
var c = b.show;
c();  //=> 1

这里是个比较容易出问题的地方,需要注意的是,this指向的是执行时的当前对象,在上个例子中,直接调用b.show(),show方法的执行环境是b,故输出的是b.a,但是在这个例子中,c指向的是function(){console.log(this.a)},相当于你在全局环境中定义c

var c = function(){
  console.log(this.a);
}

这里c的执行环境是全局环境,故应输出window.a


注:本文无意误导大家,如有错误欢迎指出!

转载于:https://my.oschina.net/u/555820/blog/522164

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值