谈谈我对JavaScript原型和闭包系列理解(随手笔记6)

相关阅读:谈谈我对JavaScript原型和闭包系列理解(随手笔记8)   谈谈我对JavaScript原型和闭包系列理解(随手笔记9)

什么是闭包

闭包是什么?闭包是Closure,这是静态语言所不具有的一个新特性。但是闭包也不是什么复杂到不可理解的东西,简而言之,闭包就是:

• 闭包就是函数的局部变量集合,只是这些局部变量在函数返回后会继续存在。

• 闭包就是就是函数的“堆栈”在函数返回后并不释放,我们也可以理解为这些函数堆栈并不在栈上分配而是在堆上分配

• 当在一个函数内定义另外一个函数就会产生闭包

什么是原型?

原型是一个对象,其他对象可以通过它实现属性继承。

任何一个对象都可以成为原型么?

哪些对象有原型

所有的对象在默认的情况下都有一个原型,因为原型本身也是对象,所以每个原型自身又有一个原型(只有一种例外,默认的对象原型在原型链的顶端).

执行上下文

每次当控制器转到ECMAScript可执行代码的时候,即会进入到一个执行上下文。

执行上下文(简称-EC)是一个抽象概念,ECMA-262标准用这个概念同可执行代码(executable code)概念进行区分。

标准规范没有从技术实现的角度准确定义EC的类型和结构;这应该是具体实现ECMAScript引擎时要考虑的问题。

活动的执行上下文在逻辑上组成一个堆栈。堆栈底部永远都是全局上下文(global context),堆栈顶部是当前(活动的)执行上下文。堆栈在EC类型的变量(various kingds of EC)被推入或弹出的同时被修改。

--------------------------------------------------------------------------------

情况一: 在一段js代码拿过来真正一句一句运行之前,浏览器已经做了一些“准备工作”,其中就包括对变量的声明,而不是赋值。变量赋值时在赋值语句执行的时候进行的。

情况二: 在“准备工作”阶段,this是直接赋值的。

代码如下:

console.log(this) //Window

情况三: 函数: 函数表达式和函数声明

 console.log(f1); //function f1() {}
function f1() {} //函数声明
console.log(f2); //undefined
var f2 = function() {}; //函数表达式 

“准备工作”总结:

•变量、函数表达式————变量声明,默认赋值为undefined

•this————赋值

•函数声明————赋值

这三种数据的准备情况我们称之为“执行上下文”或者“执行上下文环境”。

--------------------------------------------------------------------------------

javascript在执行一个代码段之前,都会进行这些“准备工作”来生成执行上下文。这个“代码段”分为三种情况--全局代码、函数代码、Eval代码。

 //全局代码段
<script type="text/javascript">
 //代码段...
</script>
//函数代码段
function fn(x) {
 console.log(x + 5);
}
var fn = new Function("x", "console.log(x + 5)");
//Eval代码段
eval('var x = 10');
(function foo() {
 eval('var y = 20');
})();
alert(x); //10
alert(y); //"y" is not defined
//因为eval涉及到安全问题(脚本注入),所以尽量不用。 

--------------------------------------------------------------------------------

在函数中,除了“准备工作”的几种情况,还会有其他数据

 function fn(x) {
 console.log(arguments); //[10]
 conosole.log(x); //10
}
fn(10); 

以上代码展示了在函数体的语句执行之前,arguments变量和函数参数都已经被赋值。

函数每被调用一次,都会产生一个新的上下文执行环境。因为不同调用那个就可能产生不同的参数。

函数在定义的时候(不是调用)就已经确定了函数体内部自由变量的作用域。

 var a = 10;
function fn() {
 console.log(a); //a是自由变量
}     //函数创建时,就确定了a要取值的作用域
function bar(f) {
 var a = 20;
 f(); //打印"10",而不是"20"
}
bar(fn); 

总结:

全局代码的上下文环境数据内容为:

•普通变量(包括函数表达式),如:var a = 10 | ===> 声明(默认赋值undefined)

•函数声明,如function fn() {} | ===> 赋值

•this | ===> 赋值

函数体

•参数 | ===> 赋值

•arguments | ===> 赋值

•自由变量的取值作用域 | ====> 赋值

通俗的定义:

在执行代码之前,把将要用到的所有变量都事先拿出来,有的直接赋值了,有的先用undefined占个位。

以上内容是小编给大家分享的JavaScript原型和闭包系列理解(随手笔记6)的全部叙述,希望大家喜欢。

(0)

相关推荐

  • 谈谈我对JavaScript原型和闭包系列理解(随手笔记8)

    在上篇文章给大家介绍了<谈谈我对JavaScript原型和闭包系列理解(随手笔记6)>, 谈谈我对JavaScript原型和闭包系列理解(随手笔记9)    可以点击了解详情. 执行上下文栈 执行全局代码时,会产生一个执行上下文环境,每次调用函数都又会产生执行上下文环境.当函数调用完成时,这个上下文环境以及其中的数据都会被消除,再重新回到全局上下文环境.处于活动状态的执行上下文环境只有一个. 压栈出栈过程----执行上下文栈: var a = 10, //1. 进入全局上下文环境 fn, ba

  • 谈谈我对JavaScript原型和闭包系列理解(随手笔记9)

    相关阅读:谈谈我对JavaScript原型和闭包系列理解(随手笔记6)   谈谈我对JavaScript原型和闭包系列理解(随手笔记8) 作用域 引用<JavaScript语言精粹和编程实践>上对作用域的定义: 变量作用域又叫变量的可见性.变量作用域完成对信息的隐蔽,也就是处理"割据"问题. js中是没有块级作用域的(ES6中有一个let,可以在{},if,for里面声明,同时作用域限定在块级.let声明的变量不存在变量提升!这里不谈论这个,因为我也是偶然看到.). 我们在

  • 学习javascript的闭包,原型,和匿名函数之旅

    本文通过示例给大家介绍javascript的闭包,原型,和匿名函数,具体详情请看下文. 一 .>关于闭包 理解闭包 需要的知识 1.变量的作用域 例1: var n =99; //建立函数外的全局变量 function readA(){ alert(n); //读取全局变量 } readA(); //执行此函数 例2: function readB(){ var c = 9; function readC(){ console.log(c); //ok c可见 } return readC; }

  • JavaScript的模块化:封装(闭包),继承(原型) 介绍

    虽然 JavaScript 天生就是一副随随便便的样子,但是随着浏览器能够完成的事情越来越多,这门语言也也越来越经常地摆出正襟危坐的架势.在复杂的逻辑下, JavaScript 需要被模块化,模块需要封装起来,只留下供外界调用的接口.闭包是 JavaScript 中实现模块封装的关键,也是很多初学者难以理解的要点.最初,我也陷入迷惑之中.现在,我自信对这个概念已经有了比较深入的理解.为了便于理解,文中试图封装一个比较简单的对象. 我们试图在页面上维护一个计数器对象 ticker ,这个对象维护一

  • 谈谈我对JavaScript原型和闭包系列理解(随手笔记6)

    相关阅读:谈谈我对JavaScript原型和闭包系列理解(随手笔记8)   谈谈我对JavaScript原型和闭包系列理解(随手笔记9) 什么是闭包 闭包是什么?闭包是Closure,这是静态语言所不具有的一个新特性.但是闭包也不是什么复杂到不可理解的东西,简而言之,闭包就是: • 闭包就是函数的局部变量集合,只是这些局部变量在函数返回后会继续存在. • 闭包就是就是函数的"堆栈"在函数返回后并不释放,我们也可以理解为这些函数堆栈并不在栈上分配而是在堆上分配 • 当在一个函数内定义另外

  • JavaScript作用域、闭包、对象与原型链概念及用法实例总结

    本文实例讲述了JavaScript作用域.闭包.对象与原型链概念及用法.分享给大家供大家参考,具体如下: 1 JavaScript变量作用域 1.1 函数作用域 没有块作用域:即作用域不是以{}包围的,其作用域完成由函数来决定,因而if /for等语句中的花括号不是独立的作用域. 如前述,JS的在函数中定义的局部变量只对这个函数内部可见,称之谓函数作用域. 嵌套作用域变量搜索规则:当在函数中引用一个变量时,JS会搜索当前函数作用域,如果没有找到则搜索其上层作用域,一直到全局作用域. var va

  • JavaScript原型继承和原型链原理详解

    这篇文章主要介绍了JavaScript原型继承和原型链原理详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 在讨论原型继承之前,先回顾一下关于创建自定义类型的方式,这里推荐将构造函数和原型模式组合使用,通过构造函数来定义实例自己的属性,再通过原型来定义公共的方法和属性. 这样一来,每个实例都有自己的实例属性副本,又能共享同一个方法,这样的好处就是可以极大的节省内存空间.同时还可以向构造函数传递参数,十分的方便. 这里还要再讲一下两种特色的构造

  • 一篇文章让你搞懂JavaScript 原型和原型链

    本文由葡萄城技术团队原创并首发 转载请注明出处:葡萄城官网 与多数面向对象的开发语言有所不同,虽然JavaScript没有引入类似类的概念(ES6已经引入了class语法糖),但它仍然能够大量的使用对象,那么如何将所有对象联系起来就成了问题.于是就有了本文中我们要讲到的原型和原型链的概念. 原型和原型链作为深入学习JavaScript最重要的概念之一,如果掌握它了后,弄清楚例如:JavaScript的继承,new关键字的原来.封装及优化等概念将变得不在话下,那么下面我们开始关于原型和原型链的介绍

  • 学习JavaScript中的闭包closure应该注意什么

    目录 闭包简述 1.闭包使得内部函数可以访问外部函数的属性(变量或方法) 2.闭包的广阔应用场景 3.用闭包模拟私有方法 4.从性能角度考虑,非必要不使用闭包 闭包简述 Mozilla 上这样解释闭包:一个函数和对其周围状态(lexical environment,词法环境) 的引用捆绑在一起(或者说函数被引用包围),这样的组合就是闭包(closure). 也就是说,闭包让你可以在一个内层函数中访问到其外层函数的作用域.在 JavaScript 中, 每当创建一个函数, 闭包就会在函数创建的同时

  • javascript原型继承工作原理和实例详解

    先为大家分享JS原型继承实例,供大家参考,具体内容如下 一.JS原型继承 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>JS原型继承</title> </head> <body> <!--原型继承--> <script type="text/javascript"> //cl

  • javascript原型模式用法实例详解

    本文实例讲述了javascript原型模式用法.分享给大家供大家参考.具体分析如下: 一般在了解了工厂模式和构造函数模式的弊端之后,就知道为什么需要原型模式了   原型模式i的定义:每个函数都有一个prototype(原型)属性,这个属性是一个对象,它的用途是包含可以由特定类型的所有实例共享的属性和方法.比如在构造函数模型中sayInformation()方法,如果声明两个实例就要构造两次sayInformation方法,但是声明两次是没有必要的,这就是为什么有原型模式的出现(尼玛,网上那些博客

  • JavaScript中的闭包(Closure)详细介绍

    闭包是JavaScript中一个重要的特性,其最大的作用在于保存函数运行过程中的信息.在JavaScript中,闭包的诸多特性源自函数调用过程中的作用域链上. 函数调用对象与变量的作用域链 对于JavaScript中的每一次函数调用,JavaScript都会创建一个局部对象以储存在该函数中定义的局部变量:如果在该函数内部还有一个嵌套定义的函数(nested function),那么JavaScript会在已经定义的局部对象之上再定义一个嵌套局部对象.对于一个函数,其内部有多少层的嵌套函数定义,也

随机推荐