文档章节

例说javascript作用域

 永不停息的小河
发布于 2015/10/26 15:56
字数 904
阅读 35
收藏 0

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

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


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

© 著作权归作者所有

粉丝 0
博文 6
码字总数 3461
作品 0
沈阳
私信 提问
JavaScript之例题中彻底理解this

本文共 2025 字,看完只需 8 分钟 概述 前面的文章讲解了 JavaScript 中的执行上下文,作用域,变量对象,this 的相关原理,但是我后来在网上看到一些例题的时候,依然没能全做对,说明自己有...

前端老手
09/23
13
0
《你不知道的js(上卷)》笔记1(基础知识和闭包)

大部分接触js应该都是先用了再学,其实大部分学习大部分语言都应该采取这种方式。因为只看不练,还能入门,而如果先看的话,估计很容易就学不下去了。所以呀,要想欺骗别人,首先得欺骗自己(...

陨石坠灭
06/01
0
0
JavaScript中的this指针 理论化this指针的定义

JavaScript现在应用之广泛,远超其他任何语言,只要是一个合格的网站应用,基本上多多少少都会有JS的存在。在JavaScript中,this的指向被不少Coder所不解,但其实JS中的this理解起来也是相当...

superwebmaster
2018/05/29
0
0
JavaScript函数式编程之深入理解纯函数

纯函数是函数式编程的基础,需要重点理解。 纯函数的概念: 纯函数是这样一种函数,即相同的输入,永远会得到相同的输出,而且没有任何可观察的副作用。 在说明纯函数的概念之前,先讲两个其...

砖用冰西瓜
2018/06/08
0
0
JavaScript的变量声明提升

说变量声明提升之前,先抛出一个疑问:JavaScript是解释型语言,还是编译型语言? 对于这个问题,几乎所有初学者都坚定不移的给了我答案:“JavaScript是解释型语言”,但是随着你对JavaScr...

小蝉_蝉
2018/08/17
0
0

没有更多内容

加载失败,请刷新页面

加载更多

OSChina 周六乱弹 —— 如果是个帅小伙你愿意和他出去吗

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 小小编辑推荐:《Ghost 》游戏《死亡搁浅》原声 《Ghost 》游戏(《死亡搁浅》原声) - Au/Ra / Alan Walker 手机党少年们想听歌,请使劲儿戳...

小小编辑
今天
117
5
java通过ServerSocket与Socket实现通信

首先说一下ServerSocket与Socket. 1.ServerSocket ServerSocket是用来监听客户端Socket连接的类,如果没有连接会一直处于等待状态. ServetSocket有三个构造方法: (1) ServerSocket(int port);...

Blueeeeeee
今天
6
0
用 Sphinx 搭建博客时,如何自定义插件?

之前有不少同学看过我的个人博客(http://python-online.cn),也根据我写的教程完成了自己个人站点的搭建。 点此:使用 Python 30分钟 教你快速搭建一个博客 为防有的同学不清楚 Sphinx ,这...

王炳明
昨天
5
0
黑客之道-40本书籍助你快速入门黑客技术免费下载

场景 黑客是一个中文词语,皆源自英文hacker,随着灰鸽子的出现,灰鸽子成为了很多假借黑客名义控制他人电脑的黑客技术,于是出现了“骇客”与"黑客"分家。2012年电影频道节目中心出品的电影...

badaoliumang
昨天
16
0
很遗憾,没有一篇文章能讲清楚线程的生命周期!

(手机横屏看源码更方便) 注:java源码分析部分如无特殊说明均基于 java8 版本。 简介 大家都知道线程是有生命周期,但是彤哥可以认真负责地告诉你网上几乎没有一篇文章讲得是完全正确的。 ...

彤哥读源码
昨天
19
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部