全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

JavaScript变量作用域_动力节点Java学院整理

在JavaScript中,用var申明的变量实际上是有作用域的。

如果一个变量在函数体内部申明,则该变量的作用域为整个函数体,在函数体外不可引用该变量:

'use strict';

function foo() {
  var x = 1;
  x = x + 1;
}

x = x + 2; // ReferenceError! 无法在函数体外引用变量x

如果两个不同的函数各自申明了同一个变量,那么该变量只在各自的函数体内起作用。换句话说,不同函数内部的同名变量互相独立,互不影响:

'use strict';

function foo() {
  var x = 1;
  x = x + 1;
}

function bar() {
  var x = 'A';
  x = x + 'B';
}

由于JavaScript的函数可以嵌套,此时,内部函数可以访问外部函数定义的变量,反过来则不行:

'use strict';

function foo() {
  var x = 1;
  function bar() {
    var y = x + 1; // bar可以访问foo的变量x!
  }
  var z = y + 1; // ReferenceError! foo不可以访问bar的变量y!
}

如果内部函数和外部函数的变量名重名怎么办?

'use strict';

function foo() {
  var x = 1;
  function bar() {
    var x = 'A';
    alert('x in bar() = ' + x); // 'A'
  }
  alert('x in foo() = ' + x); // 1
  bar();
}

这说明JavaScript的函数在查找变量时从自身函数定义开始,从“内”向“外”查找。如果内部函数定义了与外部函数重名的变量,则内部函数的变量将“屏蔽”外部函数的变量。

变量提升

JavaScript的函数定义有个特点,它会先扫描整个函数体的语句,把所有申明的变量“提升”到函数顶部:

'use strict';

function foo() {
  var x = 'Hello, ' + y;
  alert(x);
  var y = 'Bob';
}

foo();

虽然是strict模式,但语句var x = 'Hello, ' + y;并不报错,原因是变量y在稍后申明了。但是alert显示Hello, undefined,说明变量y的值为undefined。这正是因为JavaScript引擎自动提升了变量y的声明,但不会提升变量y的赋值。

对于上述foo()函数,JavaScript引擎看到的代码相当于:

function foo() {
  var y; // 提升变量y的申明
  var x = 'Hello, ' + y;
  alert(x);
  y = 'Bob';
}

由于JavaScript的这一怪异的“特性”,我们在函数内部定义变量时,请严格遵守“在函数内部首先申明所有变量”这一规则。最常见的做法是用一个var申明函数内部用到的所有变量:

function foo() {
  var
    x = 1, // x初始化为1
    y = x + 1, // y初始化为2
    z, i; // z和i为undefined
  // 其他语句:
  for (i=0; i<100; i++) {
    ...
  }
}

全局作用域

不在任何函数内定义的变量就具有全局作用域。实际上,JavaScript默认有一个全局对象window,全局作用域的变量实际上被绑定到window的一个属性:

'use strict';

var course = 'Learn JavaScript';
alert(course); // 'Learn JavaScript'
alert(window.course); // 'Learn JavaScript'

因此,直接访问全局变量course和访问window.course是完全一样的。

你可能猜到了,由于函数定义有两种方式,以变量方式var foo = function () {}定义的函数实际上也是一个全局变量,因此,顶层函数的定义也被视为一个全局变量,并绑定到window对象:

'use strict';

function foo() {
  alert('foo');
}

foo(); // 直接调用foo()
window.foo(); // 通过window.foo()调用

进一步大胆地猜测,我们每次直接调用的alert()函数其实也是window的一个变量:

'use strict';

window.alert('调用window.alert()');
// 把alert保存到另一个变量:
var old_alert = window.alert;
// 给alert赋一个新函数:
window.alert = function () {}

// 恢复alert:
window.alert = old_alert;
alert('又可以用alert()了!');

这说明JavaScript实际上只有一个全局作用域。任何变量(函数也视为变量),如果没有在当前函数作用域中找到,就会继续往上查找,最后如果在全局作用域中也没有找到,则报ReferenceError错误。

名字空间

全局变量会绑定到window上,不同的JavaScript文件如果使用了相同的全局变量,或者定义了相同名字的顶层函数,都会造成命名冲突,并且很难被发现。

减少冲突的一个方法是把自己的所有变量和函数全部绑定到一个全局变量中。例如:

// 唯一的全局变量MYAPP:
var MYAPP = {};

// 其他变量:
MYAPP.name = 'myapp';
MYAPP.version = 1.0;

// 其他函数:
MYAPP.foo = function () {
  return 'foo';
};

把自己的代码全部放入唯一的名字空间MYAPP中,会大大减少全局变量冲突的可能。

许多著名的JavaScript库都是这么干的:jQuery,YUI,underscore等等。

局部作用域

由于JavaScript的变量作用域实际上是函数内部,我们在for循环等语句块中是无法定义具有局部作用域的变量的:

'use strict';

function foo() {
  for (var i=0; i<100; i++) {
    //
  }
  i += 100; // 仍然可以引用变量i
}

为了解决块级作用域,ES6引入了新的关键字let,用let替代var可以申明一个块级作用域的变量:

'use strict';

function foo() {
  var sum = 0;
  for (let i=0; i<100; i++) {
    sum += i;
  }
  i += 1; // SyntaxError
}

常量

由于varlet申明的是变量,如果要申明一个常量,在ES6之前是不行的,我们通常用全部大写的变量来表示“这是一个常量,不要修改它的值”:

var PI = 3.14;

ES6标准引入了新的关键字const来定义常量,const与let都具有块级作用域:

'use strict';

const PI = 3.14;
PI = 3; // 某些浏览器不报错,但是无效果!
PI; // 3.14


# js变量作用域  # JavaScript变量作用域  # JavaScript中变量的作用域详解  # JS中作用域以及变量范围分析  # javascript 的变量、作用域和内存问题  # js 作用域和变量详解  # 一起来了解JavaScript的变量作用域  # 全局变量  # 绑定  # 自己的  # 这一  # 体外  # 报错  # 的是  # 体内  # 都是  # 是一个  # 直接调用  # 就会  # 有个  # 是有  # 很难  # 不可以  # 这是一个  # 引入了  # 如果没有  # 只有一个 


相关文章: 建站之星如何配置系统实现高效建站?  网站设计制作书签怎么做,怎样将网页添加到书签/主页书签/桌面?  黑客如何通过漏洞一步步攻陷网站服务器?  盐城做公司网站,江苏电子版退休证办理流程?  企业网站制作公司网页,推荐几家专业的天津网站制作公司?  c# 在高并发下使用反射发射(Reflection.Emit)的性能  大学网站设计制作软件有哪些,如何将网站制作成自己app?  ,购物网站怎么盈利呢?  网站制作说明怎么写,简述网页设计的流程并说明原因?  建站之星体验版:智能建站系统+响应式设计,多端适配快速建站  网站海报制作教学视频教程,有什么免费的高清可商用图片网站,用于海报设计?  如何通过VPS搭建网站快速盈利?  IOS倒计时设置UIButton标题title的抖动问题  建站之星导航配置指南:自助建站与SEO优化全解析  如何用5美元大硬盘VPS安全高效搭建个人网站?  c++怎么编写动态链接库dll_c++ __declspec(dllexport)导出与调用【方法】  建站之星安全性能如何?防护体系能否抵御黑客入侵?  如何通过西部建站助手安装IIS服务器?  php条件判断怎么写_ifelse和switchcase的使用区别【对比】  行程制作网站有哪些,第三方机票电子行程单怎么开?  东莞市网站制作公司有哪些,东莞找工作用什么网站好?  c# 在高并发场景下,委托和接口调用的性能对比  中山网站制作网页,中山新生登记系统登记流程?  SAX解析器是什么,它与DOM在处理大型XML文件时有何不同?  代刷网站制作软件,别人代刷火车票靠谱吗?  北京制作网站的公司,北京铁路集团官方网站?  如何优化Golang Web性能_Golang HTTP服务器性能提升方法  Android自定义listview布局实现上拉加载下拉刷新功能  如何用wdcp快速搭建高效网站?  猪八戒网站制作视频,开发一个猪八戒网站,大约需要多少?或者自己请程序员,需要什么程序员,多少程序员能完成?  做企业网站制作流程,企业网站制作基本流程有哪些?  如何在搬瓦工VPS快速搭建网站?  湖南网站制作公司,湖南上善若水科技有限公司做什么的?  建站主机选购指南:核心配置优化与品牌推荐方案  商务网站制作工程师,从哪几个方面把握电子商务网站主页和页面的特色设计?  专业的网站制作设计是什么,如何制作一个企业网站,建设网站的基本步骤有哪些?  如何基于云服务器快速搭建个人网站?  公司网站制作需要多少钱,找人做公司网站需要多少钱?  香港服务器如何优化才能显著提升网站加载速度?  高性价比服务器租赁——企业级配置与24小时运维服务  武汉网站如何制作,黄黄高铁武穴北站途经哪些村庄?  网站制作员失业,怎样查看自己网站的注册者?  如何快速查询域名建站关键信息?  ,交易猫的商品怎么发布到网站上去?  高防服务器如何保障网站安全无虞?  高端建站如何打造兼具美学与转化的品牌官网?  潮流网站制作头像软件下载,适合母子的网名有哪些?  深圳网站制作公司好吗,在深圳找工作哪个网站最好啊?  建站之星导航如何优化提升用户体验?  网站制作免费,什么网站能看正片电影? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。