理解js中的自由变量以及作用域的进阶
如果你不知道什么是作用域,建议你先看什么是作用域链,什么是原型链。这篇文章,因为这些内容都是有关联性的。
什么是自由变量?
如我在全局中定义了一个变量a,然后我在函数中使用了这个a,这个a就可以称之为自由变量,可以这样理解,凡是跨了自己的作用域的变量都叫自由变量。
var a = "追梦子";
function b(){
console.log(a); //追梦子
}
b();
上面的这段代码中的变量a就是一个自由变量,因为在函数b执行到console.log(a)的时候,发现在函数中找不到变量a,于是就往上一层中找,最后找到了全局变量a。
作用域的进阶
在我讲作用域链的时候说过如果有一个全局变量a,以及函数中也有一个变量a,那么只会作用函数中的那个变量a,都是有一种情况就显得比较复杂一些,我们一起来看看这段代码。
var aa = 22;
function a(){
console.log(aa);
}
function b(fn){
var aa = 11;
fn();
}
b(a); //
最后打印的不是11而是22,为什么会这样呢?在我解释之前我建议你事先看一下js中的执行上下文,菜鸟入门基础。这一文,如果不了解js的执行顺序就比较难以理解,另外如果你看了我这几天的文章应该有种感觉,就是内容的关联性都特别强,这也是为什么很多js新手朋友不能够理解的地方。
我们接着说为什么打印的是22,一起来分析一下这段代码。
假如我们的代码是这样的
var aa = 22;
function a(){
console.log(aa);
}
打印出的是22,我想大家应该没有意见,但是有一点我一定要提,那就是在创建这个函数的时候,这个函数的作用域就已经决定了,而是不是在调用的时候,这句话至管重要。
有了这句话的基础是不是理解上面的那段代码就变得不值一提了?
为了照护新手朋友我还是分析一下过程吧。
首先我们创建了一个全局变量aa
var aa = 22;
接着我们创建了一个函数a
function a(){
console.log(aa);
}
这时js解析这个函数的时候,就已经决定了这个函数a的作用域,既如果在函数a中找不到变量aa那就会到全局变量中找,如果找到了就返回这个aa,如果找不到就报错。
接着我们又创建了一个函数b
function b(fn){
var aa = 11;
fn();
}
在函数b中我们定义了又重新定义了这个变量aa,虽然我们这个时候重新定义了变量aa,但是因为函数a的作用域在创建的时候已经决定了,所以在函数b中创建的那个变量aa以及和函数a里面的那个变量aa没有关系了。
function b(fn){
var aa = 11;
fn();
}
b(a);
我们把函数a传到了函数b中,并且当做函数b的形参,接着我们执行了这个被传进去的函数a,最后打印出来的就是22。
在创建这个函数的时候,这个函数的作用域就已经决定了,而是不是在调用的时候。
理解js中的自由变量以及作用域的进阶的更多相关文章
- 深入理解Js中的this
深入理解Js中的this JavaScript作用域为静态作用域static scope,但是在Js中的this却是一个例外,this的指向问题就类似于动态作用域,其并不关心函数和作用域是如何声明以及 ...
- 图文结合深入理解 JS 中的 this 值
图文结合深入理解 JS 中的 this 值 在 JS 中最常见的莫过于函数了,在函数(方法)中 this 的出现频率特别高,那么 this 到底是什么呢,今天就和大家一起学习总结一下 JS 中的 th ...
- 深度理解js中var let const 区别
首先要理解js中作用域的概念 作用域:指的是一个变量的作用范围 1.全局作用域 直接写在script中的js代码,在js中,万物皆对象,都在全局作用域,全局作用域在页面打开时创建,在全局作用域中有一个 ...
- 如何理解js中的this和实际应用中需要避开哪些坑
this是什么 this就是函数内部的关键字 看下面例子理解js中的this // 例子1 function fnOne () { console.log(this) } 'use strict' f ...
- 怎么理解js中的事件委托
怎么理解js中的事件委托 时间 2015-01-15 00:59:59 SegmentFault 原文 http://segmentfault.com/blog/sunchengli/119000 ...
- 深入理解javascript中执行环境(作用域)与作用域链
深入理解javascript中执行环境(作用域)与作用域链 相信很多初学者对与javascript中的执行环境与作用域链不能很好的理解,这里,我会按照自己的理解同大家一起分享. 一般情况下,我们把执行 ...
- js中的块级作用域
概述 函数是js中最常见的作用域单元, 声明在一个函数内部的变量或函数会在所处的作用域中隐藏起来, 这是有意为之的非常好的设计原则. 但是随着js的发展, 我们有了某个代码块(通常指{..}内部)隐藏 ...
- 如何更好的理解js中的this,分享2段有意思的代码
关于js中this的浅析,大家可以点击[彻底理解js中this的指向,不必硬背]这篇博客了解. 今天遇到2段比较有意思的代码. ----------------第一段----------------- ...
- 深入理解JS中的对象(二):new 的工作原理
目录 序言 不同返回值的构造函数 深入 new 调用函数原理 总结 参考 1.序言 在 深入理解JS中的对象(一):原型.原型链和构造函数 中,我们分析了JS中是否一切皆对象以及对象的原型.原型链和构 ...
随机推荐
- iOS -iPhone5、iPhone5s、iPhone6、iPhone6Plus 屏幕适配
现在由于苹果公司出了6和6Plus,让写苹果程序的哥们为了做兼容很头疼.用StoryBoard固然方便,但是后期做兼容要花费太多的时间和精力.使用AutoLayout虽然会在不同尺寸的屏幕下自动布局, ...
- 随堂笔记之正则与HTML5新元素
在进入主题前,先插个网站https://www.processon.com/ ProcessOn是一个在线协作绘图平台,为用户提供最强大.易用的作图工具! 它可以很方便的在线简单绘制一些东西,让自己去 ...
- UHF桌面式发卡器
UHF桌面式发卡器: http://www.rr-rfid.com/index.php/pro_view/95 本文用菊子曰发布
- C# 热敏打印机 Socket 网络链接 打印 图片
C# 热敏打印机 Socket 网络链接 打印 图片 (一) http://www.cnblogs.com/rinack/p/4838211.html C# 热敏打印机 Socket 网络链接 打印 ...
- const成员函数
尽管函数名和参数列表都相同,void foo( ) const成员函数是可以与void foo( )并存的,可以形成重载! 我们假设调用语句为obj.foo(),如果obj为non-const对象,则 ...
- Delphi -- Compiler helper for initializing/finalizing variable
it CompilerhelperForInitializingFinalizingVariable; interface { Compiler helper for initializing/fin ...
- SourceTree - 正在检查源... When cloning a repository, "Checking Source" spins forever
I am trying to clone a repository, my OpenSSH is set up correctly and I can do everything fine in Gi ...
- spring官方案例程序
https://github.com/spring-projects/spring-data-book https://github.com/spring-projects 包含其他相关的应用程序
- AngularJS中实现日志服务
本篇体验使用AngularJS自定义一个记录日志的服务. 在AngularJS中,服务的一些写法是这样的: var app = angular.module('app',[]); app.provid ...
- AsyncTask实现断点续传
之前公司里面项目的下载模块都是使用xUtils提供的,最近看了下xUtils的源码,它里面也是使用AsyncTask来执行异步任务的,它的下载也包含了断点续传的功能.这里我自己也使用AsyncTask ...