Javascript-我对作用链、闭包、原型及原型链的理解
Javascript-基础概念总结(2)
最近学习一些javascript基础知识,也解决了很多之前的疑惑,记得第一次被问及怎样理解闭包时,我的回答是:就是类似于封装吧!现在想想是有多白痴,学习技术是需要逻辑性很强的,技术注重用事实和数据说话,每一点都需要理解透彻,在技术上没有猜测,没有套路,以后自己在回答技术性的问题时,应做到知道就是知道,不理解或不太明白的,就诚实对待,这样有助于自己积累知识,了解自己的不足,从而提升自己。讲了那么多题外话,是为了让自己认识到应真诚的对待学习。下面是一些我的知识总结:
【作用域】
javascript中的作用域可以理解为一个语句执行的环境大小,有全局的作用域,函数作用域和eval作用域。在JS中没有块级作用域。
讲到作用域,不得不讲执行环境,执行环境在JS中是最为重要的概念。执行环境定义了变量或函数有权访问的其他数据,决定了他们各自的行为。每个执行环境都有一个与之关联的变量对象,环境中定义的所有变量和函数都保存在这个对象中。在web浏览器中全局环境被认为是window对象,某个执行环境中的所有代码执行完毕后就被该环境销毁,保存在其中的所有变量和函数定义也随即销毁。
每个函数都有自己的执行环境。当执行流进入一个函数时,函数的环境就会被推入一个环境栈中。而在函数执行之后,栈将其环境弹出,把控制权返回给之前的执行环境。
当代码在一个环境中执行时,会创建变量对象的一个作用域链。作用域链的用途是保证对执行环境有权访问的所有变量和函数的有序访问。作用域链的前端始终是当前执行的代码所在环境的变量对象。作用域链中的下一个变量对象来自包含(外部)环境,在下一个变量对象则来自于在下一个包含环境,这样一直延续到全局执行环境,全局执行环境的变量对象始终都是作用域链中的最后一个对象。
需注意的是:在局部作用域中定义的变量可以在全局环境和局部环境中交互使用。内部环境可以通过作用域链访问所有的外部环境,但外部环境不可以访问内部环境中的任何变量和函数。每个环境都可以向上搜索作用域链,以查询变量和函数名,但任何环境都不可以通过向下搜索作用域链而进入另一个执行环境。
作用域链本质上是一个指向变量对象的指针列表,他只引用但不包含变量对象。
【闭包】
闭包是指有权访问另一个函数作用域中的变量的函数,这里要把它与匿名函数区分开(匿名函数:创建一个函数并将它赋值给一个变量,这种情况下创建的函数叫匿名函数,匿名函数的name属性是空字符串),创建闭包的常见方式就是在一个函数内部创建另一个函数。闭包保存的是整个变量的对象。
闭包的作用:在函数执行过程中,为读取和写入变量的值,就需要在作用域链中查找变量,这时灵活方便的闭包就派上用场,我们知道当一个函数被调用时就会创建一个执行环境及相应的作用域链,那么闭包就会沿着作用域链获取到开发者想要的变量及元素。
注:在维基百科中是这样定义闭包的:闭包(也称词法闭包或函数闭包)是指一个函数或函数的引用,与一个引用环境绑定在一起。这个引用环境是一个存储该函数每个非局部变量(也叫自由变量)的表。——闭包不同于一般的函数,它允许一个函数在立即词法作用域外调用时,仍可访问非本地变量。
闭包灵活方便,也可以实现封装,这样就只能通过对象的特定方法才能访问到其属性。但是,不合理的使用闭包会造成空间的浪费,内存的泄露和性能消耗。
【原型和原型链】
讲到原型链,不得不讲讲用于创建对象的原型模式:我们创建每一个函数都有一个prototype(原型)属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由特定的所有实例共享的属性和方法。从字面意思理解,那么prototype就是通过调用构造函数而创建的那个对象实例的原型对象。使用原型对象的好处是可以让所有对象实例共享它所包含的属性和方法。我们可以通过对象实例访问保存在原型中的值,但却不能通过对象实例重写原型中的值。如果我们在实例中添加了一个与原型实例中同名的属性,那么我们在实例中创建该属性,该属性将会屏蔽原型中的属性。
无论什么时候,只要创建一个新函数,就会根据一组特定的规则为函数创建一个prototype(原型)属性,这个属性指向函数的原型对象。
原型链:用于实现JS中的实现继承。(许多语言都支持两种方式的继承:接口继承和实现继承。接口继承只继承方法签名,而实现继承则继承实际的方法。由于函数没有签名,在ECMAScriot中只能实现实现继承。
原型链作为实现继承的主要方法,其基本思想是利用原型让一个引用类型继承另一个引用继承的属性和方法。了解一下构造函数、原型和实例的关系:每个构造函数都是一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针。假如我们让原型对象等于另一个类型的实例,那么此时的原型对象将包含一个指向另一个原型的指针,相应的另一个原型中包含着一个指向另一个构造函数的指针。如此层层递进,就构成了实例与原型的链条。这就是原型链的概念。
当函数调用时,需查找和获取的变量和元素都会通过原型链机制一层层的往上搜索在原型对象或继承来的对象中获得。
当函数被创建,就有了作用域,当被调用时,就有了作用域链,当被继承时就有了原型链,当需要获取作用域链或原型链上的变量或值时,就有了闭包。
Javascript-我对作用链、闭包、原型及原型链的理解的更多相关文章
- js原型、原型链、作用链、闭包全解
https://www.2cto.com/kf/201711/698876.html [对象.变量] 一个对象就是一个类,可以理解为一个物体的标准化定义.它不是一个具体的实物,只是一个标准.而通过对象 ...
- JavaScript学习总结(五)原型和原型链详解
转自:http://segmentfault.com/a/1190000000662547 私有变量和函数 在函数内部定义的变量和函数,如果不对外提供接口,外部是无法访问到的,也就是该函数的私有的变量 ...
- 【javascript基础】4、原型与原型链
前言 荒废了好几天,在宿舍闷了几天了,一直想着回家放松,什么也没搞,论文就让老师催吧.不过,闲的没事干的感觉真是不好,还是看看书,写写博客吧,今天和大家说说函数的原型. 原型是什么 第一次看到这个的时 ...
- javascript 原型 和 原型链
最近几天,好些新同事来问原型,原型链啥的.本身作为菜鸟的我好像也没有好好整理过这个,这里写写自己的理解. 原型 大家都知道,JavaScript 不包含传统的类继承模型,而是使用 prototype ...
- javascript 之原型、原型链-14
原型 原型是一个对象,每个函数对象(在javascript 之对象中说过函数也是对象 )都有一个属性(prototype)指向这个对象--原型对象,这个对象的作用是让所有对象实例共享原型对象中的属性. ...
- JavaScript原型与原型链
一.数据类型 JavaScript的数据类型可以分为基本数据类型和引用数据类型. 基本数据类型(6种) String Number Boolean null undefined Symbol(ES6) ...
- JavaScript prototype原型和原型链详解
用过JavaScript的同学们肯定都对prototype如雷贯耳,但是这究竟是个什么东西却让初学者莫衷一是,只知道函数都会有一个prototype属性,可以为其添加函数供实例访问,其它的就不清楚了, ...
- js-高级(原型与原型链、作用域与作用域链、闭包)
## 原型与原型链 * 所有函数都有一个特别的属性: * `prototype` : 显式原型属性 * 所有实例对象都有一个特别的属性: * `__proto__` : 隐式原型属性 * 显式 ...
- 深入学习javaScript闭包(闭包的原理,闭包的作用,闭包与内存管理)
前言 虽然JavaScript是一门完整的面向对象的编程语言,但这门语言同时也拥有许多函数式语言的特性. 函数式语言的鼻祖是LISP,JavaScript在设计之初参考了LISP两大方言之一的Sche ...
随机推荐
- 协程 Gevent
# 协程应用:爬虫 from gevent import monkey;monkey.patch_all() import gevent import requests import time def ...
- pgAgent设定定时备份
PostgreSQL定时自动备份 简介 PostgreSQL数据库中未提供数据库的定时备份功能,所以需要结合备份和定时job功能来共同实现. 这里我选取了2种定时job方式,crontab是Linux ...
- boost之网络通信
ip::tcp的内部类型socket,acceptor以及resolver是TCP通信中最核心的类. 1.同步客户端代码: #include <iostream> #include < ...
- Ip-san 配置过程
1:SAN的定义 SAN是storage area network(存储区域网络)的简写,早期的san采用的是光纤通道技术,后期当iscsi协议出现以后,为了区分两者,就划分了IP SAN和FC SA ...
- python并发编程之多进程1--(互斥锁与进程间的通信)
一.互斥锁 进程之间数据隔离,但是共享一套文件系统,因而可以通过文件来实现进程直接的通信,但问题是必须自己加锁处理. 注意:加锁的目的是为了保证多个进程修改同一块数据时,同一时间只能有一个修改,即串行 ...
- [笔记]Go语言在Linux环境下输出彩色字符
Go语言要打印彩色字符与Linux终端输出彩色字符类似,以黑色背景高亮绿色字体为例: fmt.Printf("\n %c[1;40;32m%s%c[0m\n\n", 0x1B, & ...
- Openstak(M版)控制节点安装
#############修改hosts文件 # controller10.0.0.11 controller# compute110.0.0.31 compute1# block110.0.0.41 ...
- CKEditor & CKFinder集成
CKEditor集成 CKEditor(原名FckEditor): 著名的HTML编辑器(可在线编辑HTML) 配置: ①将CKEditor中的(adapters images lang plugin ...
- BCM 交换机开发
转:http://blog.chinaunix.net/uid-23782786-id-3839602.html 前言: 最近搞这玩样,真是折腾,网上的资料都是片段,而且很少.折腾了4. ...
- Linux挂载Windows共享目录
在windows中设置共享目录并添加权限用户 把Window系统的文件共享挂载到linux centos 目录下的方法步骤: 1.先在windows下面共享需要挂载的目录. 2.确保linux与win ...