JavaScript概念总结:作用域、闭包、对象与原型链
1 JavaScript变量作用域
1.1 函数作用域
没有块作用域:即作用域不是以{}包围的,其作用域完成由函数来决定,因而if /for等语句中的花括号不是独立的作用域。
如前述,JS的在函数中定义的局部变量只对这个函数内部可见,称之谓函数作用域。
嵌套作用域变量搜索规则:当在函数中引用一个变量时,JS会搜索当前函数作用域,如果没有找到则搜索其上层作用域,一直到全局作用域。
[javascript] view plaincopyprint?
- var value = 'global';
- var f1 = function(){
- console.log(v1); //global
- };
- f1();
- var f2 = function(){
- var v1 ='local';
- console.log(v1); //local
- };
- f2();
词法作用域规则:函数的嵌套关系是定义时决定的,而非调用时决定的,即词法作用域,即嵌套关系是由词法分析时确定的,而运行时决定。
[javascript] view plaincopyprint?
- var v1 = 'global';
- var f1 = function(){
- console.log(v1);
- }
- f1(); //global
- var f2 = function(){
- var v1 = 'local';
- f1();
- };
- f2(); //global
对于这两个规则的相互作用,函数内无论什么位置定义的局部变量,在进入函数时都是已经定义的,但未初始化,即为undefined,直到运行到变量被赋值时才被初始化,因此若访问了未初始化的变量,我们会得到undefined的说明。
[javascript] view plaincopyprint?
- var v1 = 'global';
- var f = function(){
- console.log(v1); //undefined
- var v1 = 'local';
- };
1.2 全局作用域
全局作用域的变量是全局对象的属性,不论在什么函数中都可以直接访问,而不需要通过全局对象,但加上全局对象,可以提供搜索效率。
满足下列条件的变量属于全局作用域:
在最外层定义的变量
全局对象的属性
任何地方隐匿定义的变量。
2 闭包
2.1 装饰的定义
[javascript] view plaincopyprint?
- function f1(){
- //context define
- function f2(){
- //func define
- };
- return f2;
- };
- f2(); //获得f1中的context
在类似C/C++这种的非函数式编程语言中,我们也可以定义函数指针并返回,但外层函数在执行结束后为内层函数定义的上下文信息会被销毁,而在闭包中,则保存了返回的函数,还包含返回函数的上下文信息。(由词法作用域所支持)而且在返回闭包之后,上下文信息即被单独创建出来,从而可以生成多个互相独立的闭包实例。
2.2 闭包的用途
闭包有两个用途,一是方便实现嵌套的回调函数,二是隐藏对象的细节。
对于前者,NodeJS的编程风格已经可以说明问题,对二后者,对于函数内部的局部变量外部是不可见的,但可以提供访问函数来访问和修改相应的局部变量,从而实现OO封装的意图。
3 对象
在基于类型的语言中,对象是由类实例化,而JS是基于原型的系统,对象是由原型复制生成的。
3.1 对象的创建与访问
JavaScript中的Object实际上就是一个由属性组成的关联数组,属性由名称和值组成。可以由new Object()或{}来创建对象。对于创建简单对象,可以使用对象初始化器来创建对象,即由{}字面值来创建对象,对象的属性名可以为加''的字符串,也可不加引号。这对JS来说没有区别,访问对象的属性时,可以使用句点也可使用关联数组['name'],后者的好处是当我们不知道对象属性名时,可以由变量来作为关联数组的索引。
3.2 构造函数
我们也可以通过自定义构造函数来生成对象,从而能实例化更多的对象。构造函数也是函数,我们需要用大写的函数名即可。在函数中可以定义成员变量,成员函数等。
3.3 上下文对象
在JS中,上下文对象即this指针,即被调用函数所处的环境。其作用是在函数内部引用到调用它的对象本身。this的出现会之前介绍的静态作用域产生影响,加入了动态的内容。
由例子可以看到,我们可以通过不同的变量引用函数,不同之处调用上下文。
传递与绑定上下文
JavaScript的函数可以通过Call和Apply来动态绑定到特定的上下文。
如果想永久的绑定上下文,可以使用bind函数,需要注意的是同一函数上的多次bind是没有效果的。
[javascript] view plaincopyprint?
- var person = function(){
- name:'noname',
- getName:function(){console.log(this.name); }
- };
- var bill = {name:'Bill'};
- person.getName(); //noname
- bill.getName = person.getName;
- bill.getName(); //Bill
- name = 'JavaScript';
- func = person.getName;
- func(); //JavaScript
3.4 原型
创建对象时,我们应该在构造函数内定义一般成员,而是其原型定义成员函数。
下面我们会主要介绍原型链
JS中有两个特殊的对象:Object与Function,它们都是构造函数,用于生成对象。
Object.prototype是所有对象的祖先,Function.prototype是所有函数的原型,包括构造函数。
可以将JS的对象分为三类:用户创建对象,构造函数对象,原型对象。
所有对象中都有一个__proto__属性,其指向此对象的原型。
构造函数对象有prototype,指向其原型对象,通过此构造函数创建对象时,新创建对象的__proto__属性将会指向构造函数的prototype属性。
原型对象有一个constructor属性,指向它对应的构造函数。
function Foo() {}
var obj = new Object();
var foo = new Foo();

JavaScript概念总结:作用域、闭包、对象与原型链的更多相关文章
- 1--面试总结-js深入理解,对象,原型链,构造函数,执行上下文堆栈,执行上下文,变量对象,活动对象,作用域链,闭包,This
参考一手资料:http://dmitrysoshnikov.com/ecmascript/javascript-the-core/中文翻译版本:https://zhuanlan.zhihu.com/p ...
- javascript原型对象与原型链
在javascript中,当系统加载构造函授后 ,会自动在内存中增加一个对象,这个对象就是原型对象.构造函数和原型对象在内存中表现为相互独立,但两者之间还存在联系,构造函数的prototype是原型对 ...
- 三张图较为好理解JavaScript的原型对象与原型链
最近从网上看到别人详细得讲解了js的原型对象和原型链,看完感觉是看得最清晰的一个,于是,摘录到自己博客里 对于新人来说,JavaScript的原型是一个很让人头疼的事情,一来prototype容易与_ ...
- 【javascript】对原型对象、原型链的理解
原型对象,原型链这些知识属于基础类知识.但是平时开发过程中也很少用到. 看网上的意思,原型链用于es5开发场景下的继承.es6有了类语法糖之后,就自带继承了. 通过理解,个人画了一张原型链解构的关系图 ...
- JavaScript 构造函数 prototype属性和_proto_和原型链 constructor属性 apply(),call()和bind() 关键字this
1.构造函数: 通常构造函数首字母需要大写,主要是为了区别ECMAScript的其它函数.(高程三 P145) 构造函数与其他函数的唯一区别,就在于调用它们的方式不同.只要通过new来调用,任何函数都 ...
- 玩转JavaScript OOP[3]——彻底理解继承和原型链
概述 上一篇我们介绍了通过构造函数和原型可以实现JavaScript中的“类”,由于构造函数和函数的原型都是对象,所以JavaScript的“类”本质上也是对象.这一篇我们将介绍JavaScript中 ...
- 深入理解JS对象和原型链
函数在整个js中是最复杂也是最重要的知识 一个函数中存在多面性: 1.它本身就是一个普通的函数,执行的时候形成的私有作用域(闭包),形参赋值,预解释,代码执行,执行完 成后栈内存销毁/不销毁. 2.& ...
- jacascript 构造函数、原型对象和原型链
前言:这是笔者学习之后自己的理解与整理.如果有错误或者疑问的地方,请大家指正,我会持续更新! 先梳理一下定义: 我们通常认为 object 是普通对象,function 是函数对象: Function ...
- <JavaScript>constructor、prototype、__proto__和原型链
在看了网上很多相关的文章,很多都是懵逼看完,并不是说各位前辈们写得不好,而是说实在不容易在一两次阅读中理解透.我在阅读了一些文章后,自己整理总结和绘制了一些相关的图,个人认为会更容易接受和理解,所以分 ...
- 第198天:js---内置对象的原型链和其他知识
一.内置对象的原型链 1.Object原型 function test() {} alert(test.toString()); //新增属性 Object.prototype.mytest = fu ...
随机推荐
- Spring Boot 配置文件 – 在坑中实践
摘要: 原创出处 www.bysocket.com 「泥瓦匠BYSocket 」欢迎转载,保留摘要,谢谢! 『 仓廪实而知礼节,衣食足而知荣辱 - 管仲 』 本文提纲 一.自动配置 二.自定义 ...
- CentOS下安装JDK的三种方法
方法一:手动解压JDK的压缩包,然后设置环境变量 1.在/usr/目录下创建java目录 [root@localhost ~]# mkdir/usr/java[root@localhost ~]# c ...
- Vue 自定义图片懒加载指令v-lazyload
Vue是可以自定义指令的,最近学习过程中遇见了一个需要图片懒加载的功能,最后参考了别人的代码和思路自己重新写了一遍.以下将详细介绍如何实现自定义指令v-lazyload. 先看如何使用这个指令: &l ...
- [ext4]13 空间管理 - Prealloc分配机制
作者:Younger Liu, 本作品采用知识共享署名-非商业性使用-相同方式共享 3.0 未本地化版本许可协议进行许可. 在ext4系统中,对于小文件和大文件的空间申请请求,都有不同的分配策略 ...
- Attribute注解
class Program { static void Main(string[] args) { //Attribute注解,Attribute是附加到方法.属性.类等上面的特殊的标签,在类Type ...
- Python:字符串的分片与索引、字符串的方法
这是关于Python的第3篇文章,主要介绍下字符串的分片与索引.字符串的方法. 字符串的分片与索引: 字符串可以用过string[X]来分片与索引.分片,简言之,就是从字符串总拿出一部分,储存在另一个 ...
- 【lucene系列学习二】Lucene实现高亮显示关键词
首先,导入下图所示库 然后,import org.apache.lucene.search.highlight.*; 下面,我们新建一个实现高亮显示功能的函数 public static String ...
- leetcode contest 20
Q1: 520. Detect Capital Given a word, you need to judge whether the usage of capitals in it is right ...
- servlet的过滤器的doFilter()
doFilter中的chain.doFilter(res,req);//Filter 只是链式处理,请求依然转发到目的地址 意思就说过滤器只是一个关口,如果符合条件的请求会被过滤器拦截下来,然后进行处 ...
- C语言习题1.分别统计一下其中字母,数字,其他字符的个数。将统计的字母,数字,其他字符的个数以柱状图的形式打印
从键盘上输入字符,(1)分别统计一下其中字母,数字,其他字符的个数, (2)将统计的字母,数字,其他字符的个数以柱状图的形式打印.例如 5 ***** ***** 3 ***** **** ...