简单了解JavaScript作用域


Posted in Javascript onJuly 31, 2020

作用域通常是指在指定的时间内,变量存在于一段代码中。缺乏对作用域的理解可能会导致令人沮丧的调试体验。作用域的概念是关于我们的代码中可以访问到哪些确定的函数或变量,代码的上下文和执行环境。

在 JavaScript 中,有两种类型的作用域:全局和局部作用域。

全局作用域

第一种作用域是全局作用域。它很容易定义。如果一个变量或函数是_全局的_,那么在程序中的任何地方都可以访问到它们。在浏览器中,全局作用域是 window对象。如果在函数外面声明一个变量,那么这个变量就存在全局对象中。例如:

var x = 9;

一旦该变量被定义,则可以被引用为 window.x,因为它存在于全局对象中,我们可以简单的引用它为 x。

局部作用域

JavaScript 也可以在每个函数体中创建局部作用域。例如:

function myFunc() {
  var x = 5;
}

myFunc();

console.log( x ); // ReferenceError: x is not defined

由于 x 是在 myFunc() 中初始化,所以它只能在 myFunc() 中被访问,如果我们试图在 myFunc() 外面访问 x,则会得到一个引用错误。

注意

如果你忘记使用 var 关键字声明变量,那么这个变量会自动变成全局变量。所以这段代码可以运行:

function myFunc() {
  x = 5;
}

myFunc();

console.log( x ); // 5

这是一个坏主意。全局变量的值可以被程序的任何部分或者其他脚本更改。这是不期望发生的,因为它会导致无法预料的副作用。

立即调用表达式(IIFE)提供了一个避免全局变量的方式。你会看到许多如 jQuery 的 JavaScript 库经常使用这种方式:

(function() {
  var jQuery = { /* All my methods go here. */ };
  window.jQuery = jQuery;
})();

将一切包含在一个函数中并立即调用这个函数,这意味着函数中的所有变量都被绑定在_局部作用域_中。在函数结尾部分,你可以通过将 jQuery 对象绑定在全局对象 window 上,将一些方法和属性公开出来。了解更多关于立即调用函数表达式,请查看 Ben Alman 的文章 Immediately-Invoked Function Expression。

因为局部作用域通过函数而工作,任何在另一个函数中定义的函数都可以访问外部函数里的变量:

function outer() {
  var x = 5;

  function inner() {
    console.log( x );
  }

  inner(); // 5
}

但是 .outer() 函数不能访问 .inner() 函数中定义的任何变量。

function outer() {
  var x = 5;

  function inner() {
    console.log( x );
    var y = 10;
  }

  inner(); // 5

  console.log( y ); // ReferenceError: y is not defined
}

另外,在一个函数中没有使用 var 关键字定义的变量不是这个函数的局部变量 - JavaScript 会向上遍历作用域链(最后会到 window 对象)寻找之前定义的这个变量。如果这个变量没有定义,则会在全局中定义该变量,这样会导致意外的结果。

// Functions have access to variables defined in the same scope.

var foo = "hello";

var sayHello = function() {
  console.log( foo );
};

sayHello(); // "hello"

console.log( foo ); // "hello"

相同名称的变量可以在不同作用域中保存不同的值:

var foo = "world";

var sayHello = function() {
  var foo = "hello";
  console.log( foo );
};

sayHello(); // "hello"

console.log( foo ); // "world"

当在一个函数中引用一个外部作用域定义的变量,函数可以访问在该函数定义之后发生改变的变量值。

var myFunction = function() {
  var foo = "hello";
  var myFn = function() {
    console.log( foo );
  };
  foo = "world";
  return myFn;
};

var f = myFunction();

f(); // "world"

这是一个更复杂的作用域例子:

(function() {

  var baz = 1;

  var bim = function() {
    console.log( baz );
  };

  bar = function() {
    console.log( baz );
  };

})();

在这个实例中,运行:

console.log( baz ); // baz is not defined outside of the function

将会得到一个 ReferenceError。baz 仅仅是在函数中定义,并且没有暴露在全局作用域中。

bar(); // 1

.bar() 是在匿名函数中定义的, 但是它没有使用 var 关键字定义,这意味着它没有绑定到局部作用域,而是在全局作用域创建。另外,它可以访问 baz 变量,因为 .bar() 是在与 baz 相同的作用域定义的,所以它可以访问变量 baz,即使函数外部的其他代码不可以。

bim(); // ReferenceError: bim is not defined

.bim() 只在函数中定义的,所以它作为局部变量而不存在于全局对象中。

以上就是简单了解JavaScript作用域的详细内容,更多关于JavaScript作用域的资料请关注三水点靠木其它相关文章!

Javascript 相关文章推荐
用javascript实现在小方框中浏览大图的代码
Aug 14 Javascript
js弹出层之1:JQuery.Boxy (二)
Oct 06 Javascript
一步一步封装自己的HtmlHelper组件BootstrapHelper(三)
Sep 14 Javascript
AngularJS 所有版本下载地址
Sep 14 Javascript
详解如何构建Angular项目目录结构
Jul 13 Javascript
vue计算属性及使用详解
Apr 02 Javascript
jQuery实现的自定义轮播图功能详解
Dec 28 jQuery
新手入门带你学习JavaScript引擎运行原理
Jun 24 Javascript
javascript设计模式 ? 职责链模式原理与用法实例分析
Apr 16 Javascript
在vue项目中引用Antv G2,以饼图为例讲解
Oct 28 Javascript
解决iview table组件里的 固定列 表格不自适应的问题
Nov 13 Javascript
jquery实现鼠标悬浮弹出气泡提示框
Dec 23 jQuery
基于vue--key值的特殊用处详解
Jul 31 #Javascript
javascript开发实现贪吃蛇游戏
Jul 31 #Javascript
vue 解决无法对未定义的值,空值或基元值设置反应属性报错问题
Jul 31 #Javascript
vscode中Vue别名路径提示的实现
Jul 31 #Javascript
Vue记住滚动条和实现下拉加载的完美方法
Jul 31 #Javascript
vue中渲染对象中属性时显示未定义的解决
Jul 31 #Javascript
JS可断点续传文件上传实现代码解析
Jul 30 #Javascript
You might like
PHP内核探索:变量存储与类型使用说明
2014/01/30 PHP
CI框架源码解读之利用Hook.php文件完成功能扩展的方法
2016/05/18 PHP
Centos 6.5系统下编译安装PHP 7.0.13的方法
2016/12/19 PHP
PHP笛卡尔积实现算法示例
2018/07/30 PHP
js采用map取到id集合组并且实现点击一行选中一行
2013/12/16 Javascript
JavaScript的21条基本知识点
2014/03/04 Javascript
node.js中的buffer.Buffer.byteLength方法使用说明
2014/12/10 Javascript
jquery实现动画菜单的左右滚动、渐变及图形背景滚动等效果
2015/08/25 Javascript
jQuery实现元素拖拽并cookie保存顺序的方法
2016/02/20 Javascript
js获取时间精确到秒(年月日)
2016/03/16 Javascript
vue使用xe-utils函数库的具体方法
2018/03/06 Javascript
js canvas画布实现高斯模糊效果
2018/11/27 Javascript
详解nodejs 开发企业微信第三方应用入门教程
2019/03/12 NodeJs
layui实现form表单同时提交数据和文件的代码
2019/10/25 Javascript
vue实现图片上传功能
2020/05/28 Javascript
在Python下使用Txt2Html实现网页过滤代理的教程
2015/04/11 Python
Python编程中用close()方法关闭文件的教程
2015/05/24 Python
python实现搜索指定目录下文件及文件内搜索指定关键词的方法
2015/06/28 Python
Python对象转JSON字符串的方法
2016/04/27 Python
利用matplotlib+numpy绘制多种绘图的方法实例
2017/05/03 Python
用生成器来改写直接返回列表的函数方法
2017/05/25 Python
Python爬虫实现百度图片自动下载
2018/02/04 Python
python实现远程通过网络邮件控制计算机重启或关机
2018/02/22 Python
梅尔倒谱系数(MFCC)实现
2019/06/19 Python
python程序 线程队列queue使用方法解析
2019/09/23 Python
使用Python爬虫库requests发送表单数据和JSON数据
2020/01/25 Python
Python3中小括号()、中括号[]、花括号{}的区别详解
2020/11/15 Python
python re.match()用法相关示例
2021/01/27 Python
世界最大的私人旅行指南出版商:孤独星球
2016/08/23 全球购物
Tiqets英国:智能手机上的文化和娱乐门票
2019/07/10 全球购物
高中毕业生个人自我鉴定
2013/11/24 职场文书
公司委托书格式范文
2014/04/04 职场文书
幽默自我介绍演讲稿
2014/08/21 职场文书
投资合作意向书范本
2015/05/08 职场文书
工资证明格式模板
2015/06/12 职场文书
2015年全民创业工作总结
2015/07/23 职场文书