谈JS中的作用域链与原型链(1)
学习前端也有一段时间了,觉得自己可以与大家分享一些我当初遇到疑惑的东西,希望能给对此问题有疑惑的朋友带来一点帮助。
先来普及一下JS的概念(不要嫌我啰嗦,可能一些朋友开始学习JS是跟着视频和写好的代码学的,应该有一部分对它的结构或者说它的历史还不太了解),JavaScript由三种东西组成,一个叫ECMAScript,一个叫DOM,还有一个叫BOM,我们现在说的JS其实是它的核心——ECMAScript,简称ES。如今市面上的浏览器大部分是运行的ES5,但有一些也支持ES6,某些技术大牛都是用ES6编程然后转ES5,工具是Babel。但我们现在首要学习的还是ES5,只有深入理解了ES5才能做好其他事情。
言归正传,今天我们谈的是ES5里面的作用域链和原型链,当时我学习这一章的时候也是比较害怕的,因为以前学习生物的时候啊,什么DNA链啊生物链啊,就感觉特复杂,对链这个玩意有种“一朝被蛇咬十年怕井绳”的感觉。后来在不断地学习与编码过程中呢,我逐步的理解了这一些东西,也感谢一些前辈们的文献与代码。
说到底作用域链,顾名思义,它是与作用域在一起的,何为作用域,我们知道JS里的function,它是用来声明一个函数的,每一个函数运行的时候会拥有一个自己的执行环境,每个执行环境都能拥有一个位置来存储这个环境里面定义的变量和函数,当这个执行环境的所有代码执行完了之后,该环境被销毁,保存在其中的所有变量和函数定义也被销毁掉了,我们可以把这一个执行环境称为一个作用域。(这里值得一提的是ES5没有块级作用域的概念,只有函数里面的东西运行完会被销毁,不在函数里的东西,比如for(var i=0;i<10,i++)这个i不在函数里,而是在一个全局的循环中,它就是一个全局变量。这些问题一些大公司正在协商解决,ES6里大体上已经优化的很好了)
说完了作用域,我们就可以来讲讲作用域链了,作用域链是单向的。全局window是最大的作用域,全局里声明的函数是次一级的作用域,这样的函数里面可以访问到全局里的各种变量和函数,但在全局中访问不到这个函数里面的函数和变量;这样次一级里面的函数是再次一级,它同样也是可以访问上一级和全局的函数与变量,而上级访问不到这个里面的东西,这样一层一层的递进,就成了一条链子,也就是作用域链;
我们看一串代码:
<!DOCTYPE html>
<html> <head>
<meta charset="UTF-8">
<title></title>
</head> <body>
<script type="text/javascript">
var idol = "J.J"; function writeIdol() {
console.log("我的偶像是" + idol); //J.J(可以访问11行全局的idol)
idol = "eason"; //修改了11行idol的值
function askAnotherIdol() {
var anotherIdol = "echo";
console.log("我的偶像是" + idol); //15行“eason”
console.log("其他的偶像有" + anotherIdol) //17行“echo”
}
askAnotherIdol();
console.log("我的偶像是" + idol); //这个时候得到的是15行“eason”
console.log("其他的偶像有" + anotherIdol) //得不到了,因为作用域链是单向的
}
writeIdol();
//执行顺序为:writeIdol函数执行==>输出idol(“J.J”)==>修改idol为"eason"==>执行askAnotherIdol函数
//==>在函数内部声明新变量anotherIdol值为"echo",输出全局idol(已修改“eason”)==>输出其他的偶像有“echo”
//==>输出全局idol(已修改“eason”)==>输出anotherIdol(anotherIdol is not defined,因为作用域链的单向)
</script>
</body> </html>
作用域链可以通过这个例子来理解,通俗点,大鱼吃小鱼,小鱼吃虾米——大鱼可以吃小鱼,小鱼却吃不了大鱼。我们可以把全局当成虾米,最里面的函数当大鱼就好啦,虽然理解起来有点奇怪,如果没有自己的理解方式,这样套用一下也是可以的嘛。
作者也是第一次写博客,如果写的不太好或者有疑惑的,欢迎大家提出建议和问题,因为要吃饭啦,本篇就先写个我对作用域链的理解吧,原型链在下一篇好好写写。
谈JS中的作用域链与原型链(1)的更多相关文章
- js 中对象--对象结构(原型链基础解析)
对于本篇对于如何自定义对象.和对象相关的属性操作不了解的话,可以查我对这两篇博客.了解这两篇可以更容易理解本篇文章 用构造函数创建了一个对象 obj对象的本身创建了两个属性 x=1 ,y=2 ...
- js中继承的实现,原型链的知识点归纳,借用构造函数,组合继承(伪经典继承)
博客搬迁,给你带来的不便,敬请谅解! http://www.suanliutudousi.com/2017/10/31/js%e4%b8%ad%e7%bb%a7%e6%89%bf%e7%9a%84%e ...
- JS的作用域链与原型链
来一波,好记性不如烂笔头. 这两条链子可是很重要的. 作用域链 当执行一段JS代码(全局代码或函数)时,JS引擎会创建为其创建一个作用域又称为执行上下文(Execution Context),在页面加 ...
- js通过沿着作用域链还是原型链查找变量
这是一道非常典型的JS闭包问题,结果和具体的解析请看这里. 对于其中的`函数作用域链的问题`博主似乎没有解释清楚,有一些疑问:js中的变量到底是沿着作用域链还是原型链查找呢? 首先,要分清作用域链与原 ...
- js语言评价--js 基于哈希表、原型链、作用域、属性类型可配置的多范式编程语言
js 基于哈希表.原型链.作用域.属性类型可配置的多范式编程语言 值类型.引用类型.直接赋值: 原型是以对象形式存在的类型信息. ECMA-262把对象定义为:无序属性的集合,其属性可以包含基本值,对 ...
- javascript作用域链与原型链有联系吗?
一般来说,作用域链是针对变量的,js里面大的范围上来说,只有两种作用域,全局作用域和函数内部作用域,如果函数1里面又定义了函数2(一般都是匿名函数), 那么就有了这么一个作用域链全局作用域==> ...
- 浅谈JS中的闭包
浅谈JS中的闭包 在介绍闭包之前,我先介绍点JS的基础知识,下面的基础知识会充分的帮助你理解闭包.那么接下来先看下变量的作用域. 变量的作用域 变量共有两种,一种为全局变量,一种为局部变量.那么全局变 ...
- 浅谈JS中的!=、== 、!==、===的用法和区别 JS中Null与Undefined的区别 读取XML文件 获取路径的方式 C#中Cookie,Session,Application的用法与区别? c#反射 抽象工厂
浅谈JS中的!=.== .!==.===的用法和区别 var num = 1; var str = '1'; var test = 1; test == num //tr ...
- JS中的作用域及闭包
1.JS中的作用域 在 es6 出现之前JS中只有全局作用域和函数作用域,没有块级作用域,即 JS 在函数体内有自己的作用域,但是如果不是在函数体的话就全部都是全局作用域.比如在 if.for 等有 ...
随机推荐
- angularjs ajax传参
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <script sr ...
- IM 融云 之 开发基础概念
基础概念 - 开发篇 App Key / Secret App Key / Secret 相当于您的 App 在融云的账号和密码.是融云 SDK 连接服务器所必须的标识,每一个 App 对应一套 Ap ...
- UVa 10700 - Camel trading
题目大意:给一个不含括号.只有+和*运算的表达式,数字的范围在1到20之间,算出计算结果的可能最大值和最小值. 贪心,如果加法优先级比乘法高,那么得出的结果为最大值.(a+b)*c = a*c + b ...
- OSG和osgearth显示中文(转载)
osgEarth支持中文过程详解 OSG和osgearth显示中文 一.知识储备 要想很好的理解和解决这个问题,首先要了解什么是多字节和宽字节.说实话我之前也知道这两个字节到底有什么区别,只是简单 ...
- Java经典案例之-判断兔子的数量(斐波那契数列)
/** * 描述:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第四个月后每个月又生一对兔子, * 假如兔子都不死,问每个兔子总数为多少? * 分析:根据题目条件可以推断 * 兔子的规律 ...
- 几种常用的控件(下拉框 可选框 起止日期 在HTML页面直接读取当前时间)
下拉框 <div class="form-group"> <label class="col-xs-3 c ...
- 解决mysql 1864 主从错误
从字面意思看了一下是因为slave_pending_jobs_size_max默认值为16777216(16MB),但是slave接收到的slave_pending_jobs_size_max为 ...
- endnote 使用方法
选择需要的期刊格式,复制到收藏夹. 下载安装插件. 鼠标放在需要插入引用的地方. 关键词搜索文献,记得在这之前要把需要的文献保存至endnote online.然后insert就行了.初次安装可能会有 ...
- MySQL 替换部分电话号码为000
要做敏感信息剔除,要求又不能全换成同一个号码影响测试,想了几个方法,最终采用替换部分电话号码为000来做到敏感信息覆盖. mysql>update phone setb=replace(b,su ...
- JSP EL表达式 获得 request的GET/POST方法
JSP EL表达式 获得 request的GET/POST方法: 不在requestScopse中: <p>得到request的方法</p> <p>pageCont ...