详解JS 作用域与作用域链
作用域和作用域链方面的知识是JS的重点,去面试十个有八个都会问你这块的知识,所以说这块是特别特别的重要,下面我们好好理解一下作用域和作用域链到底是个什么:
先上一段代码:
var a = 'jack';
function fn() {var a = 'frank';
}
console.log(a);
我们在函数里定义了一个a变量,在函数外也定义了一个a变量,那最后输出的应该是哪一个a的值呢?
这个时候就有了作用域这个概念了,简单地说作用域就是限制某个变量只能在某个区域内有效。
作用域有全局作用域和局部作用域之分,变量同样如此,在上例中,第一个a很显然是一个全局变量,函数内的a显然是局部变量。全局变量拥有全局作用域而局部变量拥有局部作用域。这道题里console.log是在全局里调用a,那么毋庸置疑最后输出的一定是'jack'。
这个时候我把函数代码块改为if代码块,看看最后应该输出什么呢
var a = 'jack';
if(true) {var a = 'frank';
}
console.log(a);
最后的结果a输出的是'frank'。
实际上这里有一个大坑,千万不要以为大括号封起来就一定是封闭环境,if里面的语句执行完后就会自动销毁了,但是在javascript里if内部定义的变量就会变为当前执行环境的变量。当前执行环境在最外围,所以if里面的a就变为全局变量了
我们再来看下面这段代码分别应该输出什么呢?
for(var i = 0;i<3;i++) {break;
}
console.log(i);
k = 5;
while(k>1) {k--;var d = 10;
}
console.log(k);
console.log(d);
除了if代码块还有我们常见的for循环,while循环也是相似的结果,我们不要被括号给迷惑了,在括号内定义的变量不一定就是局部作用域,因此这里的i,k,d变量都是全局变量,这是输出结果:
下面结合es6新增的块级作用域做一个总的概括:
- 在ES6中只要{ }没有和函数结合在一起,那么应该就是“块级作用域”。
- 在块级作用域中,var定义的变量是全局变量,let定义的变量是局部变量。
- 而在局部作用域也就是函数作用域中,无论是用var定义的变量还是用let定义的变量都是局部变量。
- 无论是在块级作用域还是局部作用域,省略变量前面的var或者let都会变成一个全局变量。
现在我们再回到前面的例子,这一次增加了全局变量b,在函数内增加了两个console.log输出语句,最后再调用这个函数,但是在函数里并没有定义变量b,那最后会是什么结果呢
var a = 'jack';
var b = 'andy';
function fn() {var a = 'frank';console.log(a);console.log(b);
}
fn();
console.log(a);
输出结果:
第二个console.log为什么会输出全局变量andy呢?
这个时候就有了作用域链的概念了,简单的说作用域表示区域,作用域链表示次序
现在我们把眼光放在函数fn里,第一行定义了a是局部变量,第二行输出这个a,但是整个代码里定义了两个a,那么就需要刚刚说到的作用域链来决定到底先用哪个变量。
javascript会先看函数内有没有这个变量a,如果没有再去函数的外围看有没有这个变量,这里作用域链就帮我们安排好了这个次序。
所以,函数内定义了变量a为'frank',那么第二行就会输出'frank',第三行要输出变量b,我们先看函数内有没有这个变量,发现没有,再去外围发现有全局变量b,那么输出的就是这个值,我们再来看最后一个console.log(a),因为他在全局范围内,所以只能访问全局变量a。
也就是说:作用域链只能向上查找,最终找到全局。不能同级(局部)或者向下查找
我们再看这一段代码:
var a = 'jack';
function fn() {console.log(a);var a = 'andy';console.log(a);
}
fn();
我们思考一下会输出什么呢?
输出结果:
稍微有点js经验的同学应该都会答对,因为有变量提升,变量a在第一行就被声明了,只不过没有被赋值。下面修改一下代码,大家再看看会输出什么:
var a = 'jack';
function fn() {console.log(a);var a = 'andy';console.log(ss());function ss() {return a;}
}
fn();
我们在fn函数内又添加了一个函数ss,并且在这个函数的顶部就调用了这个函数。不仅函数内声明的变量会被提升,函数内的函数也会被提升,而且函数的提升会比变量更优先
那么,在javascript中这段代码实际上是这样被执行的:
var a = 'jack';
function fn() {function ss() {return a;}var a;console.log(a);a = 'andy';console.log(ss());
}
fn();
先把函数声明提升到首行,再声明变量a,然后输出a,a没有被赋值,所以是undefined,然后a被赋值为'andy',最后调用函数ss,返回的就是andy。
详解JS 作用域与作用域链相关推荐
- 详解JS原型与原型链
目录 1.构造函数原型prototype 2.对象原型__proto__ 3.constructor构造函数 4.原型链 5.原型对象中的this指向 6.扩展内置对象(原型对象的应用) 在ES6之前 ...
- 详解JS原型链与继承
详解JS原型链与继承 JavaScript 目录 摘自JavaScript高级程序设计: 概念 确定原型和实例的关系 原型链的问题 借用构造函数 组合继承 原型继承 寄生式继承 寄生组合式继承 new ...
- 详解js中的继承(一)
详解js中的继承(一) 前言 准备知识 1.构造函数,实例 2.原型对象 3.构造函数,原型对象和实例的关系 继承 原型链 小结 前言 通过[某种方式]让一个对象可以访问到另一个对象中的属性和方法,我 ...
- 详解JS中的Object
详解 JS 中的 Object 从本质上看,Object 是一个构造函数,用于创建对象. 一.Object 构造函数的属性 在 Object 中声明的属性只有两个: Object.length -- ...
- python获取mysql中的数据供js调用_详解js文件通过python访问数据库方法
我来教你 js文件怎么通过python访问数据库,希望能够为你带来帮助. 1.如果是要提交表单内容给 服务器的 python 处理,那么只需要在表单 里面的 action 填写服务端的处理路由就可以了 ...
- socket服务器断开消息,详解JS WebSocket断开原因和心跳机制
1.断开原因 WebSocket断开的原因有很多,最好在WebSocket断开时,将错误打印出来. ws.onclose = function (e) { console.log('websocket ...
- php js实现流程图,详解js中构造流程图的核心技术JsPlumb(2)_javascript技巧
前言:上篇详解js中构造流程图的核心技术JsPlumb介绍了下JsPlumb在浏览器里面画流程图的效果展示,以及简单的JsPlumb代码示例.这篇还是接着来看看各个效果的代码说明. 一.设置连线的样式 ...
- 详解js对称加密和非对称加密
详解js对称加密和非对称加密 https保证数据在传输过程中不被窃取和篡改,从而保证传输安全 1.加密 对称加密:产生一个密钥,可以用其加密,可以用其加密,也可以用其加解密. 这个密钥可以是任何东西, ...
- 详解 js 函数中的 arguments
详解 js 函数中的 arguments 1.什么 arguments 简单来说:arguments 是一个对应于传递给函数的参数的类数组对象 arguments 对象是所有(非箭头)函数中都可用的局 ...
- linux 弹出窗口,实现弹出窗口的window.open用法详解(js代码)
实现弹出窗口的window.open用法详解(js代码) [1.最基本的弹出窗口代码] 其实代码非常简单: 因为这是一段javascripts代码,所以它们应该放在 cript">标签 ...
最新文章
- Python使用tpot获取最优模型并抽取最优模型模型参数
- 【响应式Web前端设计】new Option()函数的作用(三区联动)
- Eigen 学习笔记
- C# WebApi+Task+WebSocket实战项目演练(四)
- Streamy 使用RDBMS
- .net中的mapinfo开发:准备(一)
- NOT IN、JOIN、IS NULL、NOT EXISTS效率对比
- AliOS Things v1.1.2新特性
- android 桌面视频播放器,ZY-Player ,一款跨平台桌面端视频资源播放器
- 设计模式--代理模式--Java实现
- 程序包sun.misc不存在
- Cocos2dx 下面,对 音乐 和音效简单封装
- AI 时代,程序员从小白到小牛的发展攻略丨今晚直播送机械键盘!
- 三大抽样分布——卡方分布、t分布、F分布
- 卷积神经网络(CNN)实现手写体识别
- python聊天室_python聊天室
- 计算机系云,计算机与信息技术学院
- Learning Convolutional Neural Network for Graphs
- GPIB编程控件指令
- 研究生入门,如何高效阅读论文