Javascript Closures
如何写JS库,JS库写法
如何写JS库,JS库写法前⾔:现在javascript库特别多,其写法各式各样,总结⼏种我们经常见到的,作为⾃⼰知识的积累。
⽽⽬前版本的 JavaScript 并未提供⼀种原⽣的、语⾔级别的模块化组织模式,⽽是将模块化的⽅法交由开发者来实现。
因此,出现了很多种 JavaScript 模块化的实现⽅式,以 AMD 为例,该规范使⽤ define 函数来定义模块。
define(factory(){//模块化});模块模式:模块模式使⽤了 JavaScript 的⼀个特性,即闭包(Closures)。
现今流⾏的⼀些 JS 库中经常见到以下形式的代码:;(function (参数) {// 模块代码// return something;})(参数);上⾯的代码定义了⼀个匿名函数,并⽴即调⽤⾃⼰。
也有⼀些开发者在函数表达式前⾯加上⼀个惊叹号(!)或分号(;),⽽不是⽤括号包起来。
!function (参数) {// 代码// return something}(参数);还有些⼈喜欢⽤括号将整个 IIFE 围起来,这样就变成了以下的形式:(function (参数) {// 代码// return something}(参数));参数输⼊:JavaScript 有⼀个特性叫做隐式全局变量(implied globals),当使⽤⼀个变量名时,JavaScript 解释器将反向遍历作⽤域链来查找变量的声明,如果没有找到,就假定该变量是全局变量。
这种特性使得我们可以在闭包⾥随处引⽤全局变量,⽐如 jQuery 或 window。
然⽽,这是⼀种不好的⽅式。
考虑模块的独⽴性和封装,对其它对象的引⽤应该通过参数来引⼊。
如果模块内需要使⽤其它全局对象,应该将这些对象作为参数来显式引⽤它们,⽽⾮在模块内直接引⽤这些对象的名字。
以 jQuery 为例,若在参数中没有输⼊ jQuery 对象就在模块内直接引⽤ $ 这个对象,是有出错的可能的。
js close方法
js close方法
JS中的close方法是用来关闭当前浏览器窗口或者标签页的。
它通常是在用户完成某项操作后自动触发,以便关闭当前窗口或者标签页,从而提高用户体验。
close方法可以通过以下方式来调用:
window.close(); // 关闭当前窗口或标签页
注意:close方法只能关闭由JavaScript打开的窗口或者标签页,如果是由用户自行打开的窗口或者标签页,close方法将会被浏览器忽略。
此外,close方法也有一些限制,比如:
- close方法只能被同一域名下的页面调用;
- close方法不能被Chrome和Firefox等浏览器禁用;
- close方法不能在IE中被使用,因为IE不允许将其视为安全操作。
在实际项目中,我们应该根据具体的需求来决定是否使用close 方法,以及如何使用。
如果需要在JS中调用close方法,建议在打
开新窗口或者标签页时加上特定的标识,以便在需要关闭时进行判断。
- 1 -。
JavaScript实现的展开与收起
JavaScript实现的展开与收起在网页开发中,经常会遇到需要展开和收起内容的需求,比如文字过长时,只显示一部分内容,点击按钮后展开全部内容;或者是显示的内容过多,点击按钮后收起部分内容。
这种功能可以通过JavaScript来实现,下面我将为大家介绍一种实现方法。
首先,我们需要在HTML中创建一个用于展示内容的容器,并为其设置一定的高度,以便初始状态下只显示一部分内容。
比如:```html<div id="content" style="height: 200px; overflow: hidden;"><!--这里是需要展示的内容--></div>```其中,`content`是容器的id,`height`属性设置了容器的高度,`overflow: hidden;`则表示超出容器高度的内容将被隐藏。
接下来,我们创建两个按钮,一个用于展开内容,一个用于收起内容。
比如:```html<button id="expandBtn">展开</button><button id="collapseBtn">收起</button>```然后,在JavaScript中获取这两个按钮的元素,并为它们分别绑定点击事件。
比如:```javascriptvar expandBtn = document.getElementById('expandBtn');var collapseBtn = document.getElementById('collapseBtn');expandBtn.addEventListener('click', expandContent);collapseBtn.addEventListener('click', collapseContent);```在这里,`expandBtn`和`collapseBtn`分别代表展开和收起按钮的元素,`addEventListener`方法可以为元素绑定事件。
js中closest用法
js中closest用法
closest方法是JavaScript中的一种DOM方法,它能够查找与当前元素最接近的指定选择器的祖先元素。
在使用closest方法时,需要传入一个选择器字符串作为参数。
该方法会向上查找当前元素的祖先元素,直到找到第一个与指定选择器匹配的元素为止,然后返回该元素。
例如,假设存在如下HTML结构:
```
<div class='parent'>
<div class='child'>
<span class='target'></span>
</div>
</div>
```
如果想要获取到最近的class为'parent'的祖先元素,可以使用以下代码:
```
const targetElement = document.querySelector('.target'); const closestParent = targetElement.closest('.parent'); ```
这样,closestParent变量就会保存class为'parent'的div元素。
如果当前元素没有与指定选择器匹配的祖先元素,则closest方
法返回null。
除了传入单个选择器字符串,closest方法也可以传入一个多个选择器组成的数组。
此时,方法会查找符合数组中第一个选择器的祖先元素,如果没有找到,则继续查找符合数组中第二个选择器的祖先元素,以此类推。
前端内存泄漏的情景及解决方案
前端内存泄漏的情景及解决⽅案什么是内存泄露?已经不再使⽤的内存未能被程序释放,叫内存泄露(memory leak)。
内存泄露会带来什么样的后果?内存泄露会因为减少可⽤内存数量从⽽降低计算机性能,严重的可能导致设备停⽌正常⼯作,或者应⽤程序崩溃。
什么情况下出现内存泄漏?⾸先了解⼀下垃圾回收:垃圾回收(英语:Garbage Collection,缩写为GC)在计算器科学中是⼀种⾃动的机制。
当⼀个计算机上的动态存储器不再需要时,就应该予以释放,以让出存储器,这种存储器资源管理,称为垃圾回收。
当⼀块内存不再⽤到,但是垃圾回收机制⼜⽆法释放这块内存的时候,就导致内存泄漏。
出现内存泄露的的⼏种常见情况:1、全局变量由于JavaScript对未声明变量的处理⽅式是在全局对象上创建该变量的引⽤。
如果在浏览器中,全局对象就是window对象。
变量在窗⼝关闭或重新刷新页⾯之前都不会被释放,如果未声明的变量缓存⼤量的数据,就会导致内存泄露。
(1). 未声明变量:a = '我是未声明的变量a,我缓存了数据,如果数据⾜够⼤的话,就会内存泄漏'(2). 通过this也会创建全局变量,当在全局作⽤域中调⽤⼀个函数,这个函数内部⽤this.var的⽅式创建了⼀个变量,此时this指向的是全局对象(window),⽽不是'undefined'如:function leak() {this.variable = "potential accidental global"}leak()2、闭包(closures): js函数内可以直接读取全局变量,但是函数外不能读取函数内的局部变量。
这时候在函数f1内再声明⼀个函数f2调⽤局部变量,然后返回函数f2,在f1的外部声明⼀个变量result赋值为f1,再调⽤result,就是⼀个闭包的例⼦。
function f1(){ var n = 999; function f2(){ alert(n); } return f2; } var result = f1(); result(); // 999闭包可以读取函数内部的变量,然后让这些变量始终保存在内存中。
JavaScript节流函数Throttle详解
JavaScript节流函数Throttle详解在浏览器 DOM 事件⾥⾯,有⼀些事件会随着⽤户的操作不间断触发。
⽐如:重新调整浏览器窗⼝⼤⼩(resize),浏览器页⾯滚动(scroll),⿏标移动(mousemove)。
也就是说⽤户在触发这些浏览器操作的时候,如果脚本⾥⾯绑定了对应的事件处理⽅法,这个⽅法就不停的触发。
这并不是我们想要的,因为有的时候如果事件处理⽅法⽐较庞⼤,DOM 操作⽐如复杂,还不断的触发此类事件就会造成性能上的损失,导致⽤户体验下降(UI 反映慢、浏览器卡死等)。
所以通常来讲我们会给相应事件添加延迟执⾏的逻辑。
通常来说我们⽤下⾯的代码来实现这个功能:var COUNT = 0;function testFn() { console.log(COUNT++); }// 浏览器resize的时候// 1. 清除之前的计时器// 2. 添加⼀个计时器让真正的函数testFn延后100毫秒触发window.onresize = function () {var timer = null;clearTimeout(timer);timer = setTimeout(function() {testFn();}, 100);};细⼼的同学会发现上⾯的代码其实是错误的,这是新⼿会犯的⼀个问题:setTimeout 函数返回值应该保存在⼀个相对全局变量⾥⾯,否则每次 resize 的时候都会产⽣⼀个新的计时器,这样就达不到我们发的效果了于是我们修改了代码:var timer = null;window.onresize = function () {clearTimeout(timer);timer = setTimeout(function() {testFn();}, 100);};这时候代码就正常了,但是⼜多了⼀个新问题 —— 产⽣了⼀个全局变量 timer。
这是我们不想见到的,如果这个页⾯还有别的功能也叫 timer 不同的代码之前就是产⽣冲突。
Closure
简介 Closure 所谓“闭包”,指的是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。闭包是 ECMAScript (JavaScript)最强大的特性之一,但用好闭包的前提是必须理解闭包。闭包的创建相对容易,人们甚至会在不经意间创建闭包,但这些无意创建的闭包却存在潜在的危害,尤其是在比较常见的浏览器环境下。如果想要扬长避短地使用闭包这一特性,则必须了解它们的工作机制。而闭包工作机制的实现很大程度上有赖于标识符(或者说对象属性)解析过程中作用域的角色。 关于闭包,最简单的描述就是 ECMAScript 允许使用内部函数--即函数定义和函数表达式位于另一个函数的函数体内。而且,这些内部函数可以访问它们所在的外部函数中声明的所有局部变量、参数和声明的其他内部函数。当其中一个这样的内部函数在包含它们的外部函数之外被调用时,就会形成闭包。也就是说,内部函数会在外部函数返回后被执行。而当这个内部函数执行时,它仍然必需访问其外部函数的局部变量、参数以及其他内部函数。这些局部变量、参数和函数声明(最初时)的值是外部函数返回时的值,但也会受到内部函数的影响。 遗憾的是,要适当地理解闭包就必须理解闭包背后运行的机制,以及许多相关的技术细节。虽然本文的前半部分并没有涉及 ECMA 262 规范指定的某些算法,但仍然有许多无法回避或简化的内容。对于个别熟悉对象属性名解析的人来说,可以跳过相关的内容,但是除非你对闭包也非常熟悉,否则最好是不要跳过下面几节。 对象属性名解析ECMAScript 认可两类对象:原生(Native)对象和宿主(Host)对象,其中宿主对象包含一个被称为内置对象的原生对象的子类(ECMA 262 3rd Ed Section 4.3)。原生对象属于语言,而宿主对象由环境提供,比如说可能是文档对象、DOM 等类
自调用函数
自调用函数自调用函数(Self-InvokingFunction)是JavaScript中一个非常强大的特性,它可以让我们创建一个函数,在被调用时将自己调用(自我调用)。
这种特殊的函数,也被称之为“闭包”(Closure),它可以帮助我们避免全局变量的衍生弊端,从而保护我们的程序免受外部变量的污染,提高程序的安全性和可维护性。
自调用函数的形式是一个函数包裹在括号内,并以小括号结尾。
这些小括号之内是函数参数,它把函数参数传入函数中,函数体接受参数并执行相应操作。
由于函数在被定义时就执行了,它们通常被称之为“立即执行函数”(Immediately-Invoked Function Expression,简称IIFE)。
自调用函数的一个优势是可以创建一个函数的“私有作用域”(Private Scope),从而有效地隔离全局变量。
它可以帮助程序员有效避免变量污染,防止全局变量被不同模块间误用,从而提高程序的可维护性。
此外,自调用函数还可以为变量提供更安全的保护,因为变量绑定到函数中,仅在函数作用域中有效,不会被外部模块访问。
例如,使用以下代码:(function () {var userName = John}());可以创建一个函数,它在执行时自调用,并在函数中声明一个变量“userName”,只在函数中有效,不会影响到全局变量。
另一方面,自调用函数也可以帮助我们封装一些全局函数或对象,从而使程序更加模块化,便于维护和扩展。
例如,如果我们想要封装一组函数,比如“Validate”、“Calculate”等,可以使用:var MyNamespace = (function () {// Validation functionsfunction isNumber(num) { ... }function isString(str) { ... }// Calculation functionsfunction add(a, b) { ... }function subtract(a, b) { ... }return {isNumber: isNumber,isString: isString,add: add,subtract: subtract};}());在这种情况下,MyNamespace是一个闭包,里面包含了一组有用的函数,而这些函数也可以在其他地方(尤其是不同的模块)被调用,而不会影响全局变量。
js终止方法的方法
js终止方法的方法在JavaScript中,有几种方法可以终止一个正在运行的方法。
1. 使用return: 这是最常见的方法。
如果你在方法中使用了return关键字,那么该方法将立即停止执行并返回指定的值。
```javascriptfunction myMethod() {('开始执行');return; // 终止方法('这行代码不会被执行');}```2. 抛出异常: 如果方法中抛出了异常,那么该方法将立即停止执行,并将控制权交给最近的异常处理器。
```javascriptfunction myMethod() {('开始执行');throw new Error('异常终止'); // 通过抛出异常终止方法('这行代码不会被执行');}```3. 使用break或continue: 这两个语句通常用于循环中,但也可以用于方法中。
使用break将立即终止包含它的最内层循环或switch语句,而continue将跳过当前循环的剩余部分并进入下一次循环。
```javascriptfunction myMethod() {for (let i = 0; i < 10; i++) {(i);if (i === 5) {break; // 终止循环,从而终止方法}}}```4. 使用`return`代替`break`或`continue`: 在某些情况下,你可能希望在方法中使用return来模拟break或continue的行为。
例如,如果你在递归函数中需要提前终止递归,可以使用return。
请注意,这些方法都会立即终止正在执行的方法,并将控制权返回给调用者。
在某些情况下,你可能需要仔细考虑是否应该使用这些方法,因为它们可能会中断程序的正常流程。
Groovy与Java语法比较
一、Groovy与Java的相同处1)在Groovy可以用def定义无类型的变量(定义变量方面def与JavaScript中的var相似),和返回值为无类型的方法,而在Java中没有defGroovy:Class Man={def name=”zhangsan”def introduce(){return “I am ”//return可以省略}}2)Java中的for循环for(int i=0;i<len;i++){}在Groovy中还可以写成for(I in0..len-1){}或者for(I in 0..<len){…}3)Java中的方法返回写为return;或者return obj;在Groovy的方法中return是可选的。
JA V A:Groovy:Public String sayHello(){ public String sayHello(){return “Hello,张三return “Hello,zhangsan”;//或者写成“Hello,zhangsan”} }4)Groovy中的注释比Java多了首行注释#!,其他与Java相同5)Groovy中的switch语句与Java中相同,不过支持更多类型了,比如String6)Java中的String常量表示为“Hello,zhangsan”,在Groovy中单引号双引号都可以表示。
7)对象创建在Java中写成Thought t=new Thought();在Groovy中也可以这样写,不过多了种写法:def t=new Thought();8)静态方法调用在Java和Groovy中相同,即ClassName.staticMethodName();9)实现接口和继承父类方面Groovy也与Java完全相同,即实现接口classClassName implements InterfaceName {…}继承父类:class ClassName extends SuperClass {…}10)定义接口方面Groovy与Java完全相同,即interface InterfaceName{…} //在Groovy中默认为public的11)类变量即static变量,Groovy与Java相同,static String name=”张三”,在Groovy中也可以写成static name=”张三”12)在varargs方法方面,Groovy比Java多一种表达方式,如下所示:Java:public void varargsMethod(Type…args){//do something}Groovy://与Java中的写法相同//Groovy还可以用[]代替…反应varargs的本质def varargsMethod(Type…args){ def varargsMethod(Type[] args){//do something //do something} }13)引用当前对象,Groovy和Java相同,在Java中用this表示,在Groovy中也可以用this表示,而且在Groovy中,this可以出现在stati c范围中,指向所在类的类对象,本例中,this等同于ThisInStaticScope.class(Java写法)或ThisStaticScope(Groovy写法)14)子类中调用父类方法,Groovy和Java也相同,在Java中super.methodName(),在Groovy中super.methodName()15)命名空间的定义,Groovy和Java相同,在Java中package edu.ecust.bluesun;在Groovy中package edu.ecust.bluesun(分号可省略)16)在导入类方面,Groovy和Java相同,在Java中importedu.ecust.bluesun.GroovyTest;在Groovy中import edu.ecust.bluesun.GroovyTest17)在异常处理方面,Groovy与Java相同,除了不强制程序员捕获检查异常(checked exception)外,并且在方法声明时,也可以不写throws语句。
js includes和including的用法
js includes和including的用法**JavaScript中的includes和includesLike用法****一、includes方法**在JavaScript中,`includes`是一个常用的方法,用于检查一个字符串是否包含特定的字符或子字符串。
其基本语法如下:```javascriptstring.includes(search, start = 0, end = string.length)```* `string`是要搜索的字符串。
* `search`是要查找的子字符串或字符。
* `start`是搜索的起始位置(默认为0)。
* `end`是搜索的结束位置(默认为字符串的长度)。
如果找到了子字符串或字符,`includes`方法将返回一个布尔值,表示是否包含。
如果没有找到,它将返回`false`。
例如:```javascriptlet str = "Hello, world!";console.log(str.includes("world")); // 输出:true```值得注意的是,`includes`方法区分大小写。
如果你想要执行不区分大小写的搜索,你需要将所有字符串和子字符串都转换为同一种大小写(如全大写或全小写)。
**二、includesLike方法**这种“like”的形式可能会造成混淆,因为这在中文语境下意味着类似于某种匹配,但在编程中通常用于表示类似(但不完全匹配)的情况。
然而,在JavaScript中,我们通常使用正则表达式来处理这种需求。
如果你需要检查一个字符串是否包含某个模式,例如一个数字或字母的序列,你应该使用正则表达式。
例如:```javascriptlet str = "abc123def456";let pattern = /[0-9]+/; // 匹配一个或多个数字的序列console.log(str.match(pattern)); // 输出:[ '123', '456' ] ```在上面的例子中,我们使用了正则表达式的`match`方法来找出字符串中所有匹配的模式。
js close方法
js close方法JavaScript中的close方法是用于关闭当前窗口的功能,它属于Window对象的一个方法。
在本文中,我们将深入探讨close方法的作用、用法、注意事项等方面的内容。
作用:close方法的作用是关闭当前浏览器窗口。
如果窗口是通过JavaScript代码打开的,那么只有这个窗口可以被关闭,而不能关闭其他窗口。
但是,如果窗口是通过<a>链接的方式打开的,那么这个方法会关闭整个浏览器窗口。
用法:在JavaScript中调用close方法,只需要像下面这样写即可:window.close();或者直接在窗口对象上调用close方法,像下面这样写:window.opener=null;window.open('','_self');window.close( );注意事项:1. 在某些浏览器中(如Chrome浏览器),这个方法是不能直接在脚本中调用的,因为它会被防止弹窗窗口的机制拦截。
2. 在一些较老的浏览器(如IE6)中,这个方法也是不能直接在脚本中调用的。
只有在通过JavaScript代码打开的窗口上才可以使用这个方法。
3. 如果浏览器启动了弹出窗口的防护程序,这个方法会被拦截,无法关闭窗口。
4. 在通过JavaScript代码打开的窗口上调用close方法,在关闭时可能会弹出提示框询问是否关闭窗口,这取决于浏览器的设置。
总结:JavaScript的close方法是用于关闭当前浏览器窗口的方法,它可以直接在窗口对象上调用,也可以通过window对象调用。
但是,由于浏览器的安全机制,这个方法会被拦截,因此有时候需要通过一些技巧来调用这个方法。
除此之外,close方法的使用还需要考虑浏览器的设置和版本等因素,因此在编写代码时需要多加注意。
js的匿名函数
js的匿名函数匿名函数1、定义匿名函数就是没有名字的函数了,也叫闭包函数(closures),允许临时创建⼀个没有指定名称的函数。
最经常⽤作回调函数(callback)参数的值。
2、创建⽅式⼀般有名字的函数的创建⽅式是:function 函数名(参数列表){函数体;}如果是创建匿名函数,那就应该是:function(){函数体;}很明显能看出区别就是,匿名函数没有名字。
因为是匿名函数,所以⼀般也不会有参数传给他。
3、匿名函数的作⽤为什么要创建匿名函数呢?在什么情况下会使⽤到匿名函数。
匿名函数主要有两种常⽤的场景,⼀是回调函数,⼆是直接执⾏函数。
回调函数,像ajax的异步操作,就需要回调函数。
这⾥就不详解。
关于直接执⾏函数,看⼀个例⼦就明⽩了:<script language="javascript">var a = "a";(function(){var a="b";alert(a);})();alert(a);</script>在上⾯这段代码中,会顺序输出两个alert框。
第⼀个alert框内容为b,第⼆个为a。
⼤家看到什么好处了吗?对的,使⽤函数直接执⾏可以限定变量的作⽤域,使不同脚本的相同变量可以得以共存。
4、和匿名函数相关的概念下⾯,我们先初步了解⼀下和匿名函数相关的概念。
函数声明(function 语句),要使⽤⼀个函数,我们就得⾸先声明它的存在。
⽽我们最常⽤的⽅式就是使⽤function 语句来定义⼀个函数,如:function abc(){// code to process}当然,你的函数也可以是带参数的,甚⾄是带返回值的。
function abc(x,y){return x+y;}但是,⽆论你怎么去定义你的函数,JS 解释器都会把它翻译成⼀个Function 对象。
例如,你在定义上⾯的其中⼀个例⼦的函数号,再输⼊如下代码:alert(typeof abc);// "function"你的浏览器就会弹出提⽰框,提⽰你abc 是⼀个Function 对象。
react-hooks官方文档笔记
react-hooks官⽅⽂档笔记1、useStateimport { useState } from 'react';function Example () { const [count, setCount] = useState(0); return (<div> <span>{count}</span> <button onClick={ () => { setCount(count+1) } }>增加次数</button> </div>);}2、useEffectEffects without cleanupimport { useEffect } from 'react;useEffect(() => { document.title = 'try to underStand what is effects';});What does useEffect do?By using this Hook, you tell React that your component needs to do something after render.React will remember the function you passed (we’ll refer to it as our “effect”), and call it later after performing the DOM updates. In this effect, we set the document title, but we could also perform data fetching or call some other imperative API.// Data fetching, setting up a subscription, and manually changing the DOM in React components are all examples of side effects. // useEffect is similar to componentDidMount and componentDidUpdateWhy is useEffect called inside a component?Placing useEffect inside the component lets us access the count state variable (or any props) right from the effect.We don’t need a special API to read it — it’s already in the function scope.Hooks embrace JavaScript closures and avoid introducing React-specific APIs where JavaScript already provides a solution.Does useEffect run after every render?Yes!By default, it runs both after the first render andafter every update.Instead of thinking in terms of “mounting” and “updating”,you might find it easier to think that effects happen “after render”.React guarantees the DOM has been updated by the time it runs the effects.Experienced JavaScript developers might notice thatthe function passed to useEffect is going to be different on every render. This is intentional. In fact, this is what lets us read the count value from inside the effect without worrying about it getting stale.Every time we re-render, we schedule a different effect, replacing the previous one.In a way, this makes the effects behave more like a part of the render result — each effect “belongs” to a particular render.Effects with cleanupIn a React class, you would typically set up a subscription in componentDidMount, and clean it up in componentWillUnmount.Notice how componentDidMount and componentWillUnmount need to mirror each other.Lifecycle methods force us to split this logic even though conceptually code in both of them is related to the same effect.useEffect(() => { function setFriendStatus (status) { } chatApi.subscibeToFriendStatus(id,setFriendStatus); return function cleanUp () { chatApi.unSubscibeFromFriendStatus(id,setFriendStatus); } // We don’t have to return a named function from the effect. We called it cleanup here to clarify its purpose, but you could return an arrow function or call it something different.});You might be thinking that we’d need a separate effect to perform the cleanup.But code for adding and removing a subscription is so tightly related that useEffect is designed to keep it together.If your effect returns a function, React will run it when it is time to clean up:Why did we return a function from our effect?This is the optional cleanup mechanism for effects.Every effect may return a function that cleans up after it.This lets us keep the logic for adding and removing subscriptions close to each other.They’re part of the same effect!When exactly does React clean up an effect?React performs the cleanup when the component unmounts.However, as we learned earlier, effects run for every render and not just once.This is why React also cleans up effects from the previous render before running the effects next time.Tip: Optimizing Performance by Skipping EffectsuseEffect(() => { document.title = `You clicked ${count} times`; }, [count]); // Only re-run the effect if count changes3、Rules of HooksOnly Call Hooks at the Top LevelDon’t call Hooks inside loops, conditions, or nested functions.Instead, always use Hooks at the top level of your React function.By following this rule, you ensure that Hooks are called in the same order each time a component renders. That’s what allows React to correctly preserve the state of Hooks between multiple useState and useEffect calls.Only Call Hooks from React FunctionsDon’t call Hooks from regular JavaScript functions. Instead, you can:Call Hooks from React function components.Call Hooks from custom Hooks。
includes方法的返回值
includes方法的返回值一、概述在J av aS cr ip t中,`i nc lu de s()`方法用于判断一个字符串是否包含指定的子字符串。
该方法返回一个布尔值,表示是否找到了指定的子字符串。
本文将详细介绍`in cl ud es()`方法,并提供一些使用示例。
二、语法`i nc lu de s()`方法的语法如下:```j av as cr ip ts t r.in cl ud es(s ear c hS tr in g[,p os iti o n])```-`st r`:要在其中搜索的原始字符串。
-`se ar ch St ri ng`:要搜索的子字符串。
-`po si ti on`(可选):开始搜索的位置,默认为0。
三、返回值`i nc lu de s()`方法根据搜索结果返回布尔值,可能的返回值如下:-如果`st r`包含`s ea r ch St ri ng`,返回`tr ue`。
-如果`st r`不包含`s e ar ch St ri ng`,返回`f al se`。
四、使用示例以下示例将演示`inc l ud es()`方法的多种使用方式:示例1:基本用法```j av as cr ip tc o ns ts tr='He ll o,W o rl d!';c o ns ol e.lo g(st r.i n cl ud es('He ll o'));//t ru ec o ns ol e.lo g(st r.i n cl ud es('wo rl d'));//f al se(注意大小写)```示例2:指定开始搜索的位置```j av as cr ip tc o ns ts tr='He ll o,W o rl d!';c o ns ol e.lo g(st r.i n cl ud es('He ll o',1));//f al se(从位置1开始搜索,找不到)c o ns ol e.lo g(st r.i n cl ud es('Wo rl d',7));//t ru e(从位置7开始搜索,找到了)```示例3:结合条件判断```j av as cr ip tc o ns tf ru it s=['app l e','ba na na','or a ng e'];c o ns ti np ut='ba nan a';i f(f ru it s.in cl ude s(i np ut)){c o ns ol e.lo g('水果列表中包含'+in pu t);}e ls e{c o ns ol e.lo g('水果列表中不包含'+in p ut);}```示例4:处理空字符串```j av as cr ip tc o ns ts tr='';c o ns ol e.lo g(st r.i n cl ud es(''));//t r ue(空字符串始终被认为是包含的)c o ns ol e.lo g(st r.i n cl ud es('a'));//f al se(空字符串不包含任何字符)```五、注意事项-`in cl ud es()`方法区分大小写,因此要注意所搜索的字符串的大小写。
js ensure的用法
jsensure的用法好的,以下是一篇符合您要求的文档:一、概述JavaScript中的ensure方法用于确保对象或数组中存在某个特定的属性或元素,如果存在则返回该属性或元素,如果不存在则抛出异常。
该方法在处理数据时非常有用,可以避免因数据缺失而导致的错误。
二、语法ensure方法的语法如下:ensure(obj,propertyName,[defaultValue])其中,obj是要检查的对象或数组;propertyName是要确保存在的属性名或元素索引;defaultValue是可选参数,表示如果obj中不存在propertyName时返回的默认值。
三、用法示例以下是一个使用ensure方法的示例:```javascriptletobj={name:"John",age:25};//确保obj存在"age"属性,并返回其值letage=ensure(obj,"age");console.log(age);//输出:25//确保obj存在"country"属性,并返回其默认值"USA"(如果obj中不存在"country"属性)letcountry=ensure(obj,"country","USA");console.log(country);//输出:"USA"```在上面的示例中,我们首先创建了一个对象obj,其中包含了一个名为"age"的属性。
然后我们使用ensure方法确保obj存在"country"属性,并返回其默认值"USA"。
如果obj中不存在"country"属性,ensure方法将抛出一个异常。
四、注意事项在使用ensure方法时,需要注意以下几点:1.ensure方法只能确保对象或数组中存在特定的属性或元素,而不能修改对象的属性或元素。
第5章 Google地图API开发指南
第5章Google地图API开发指南Google Maps JavaScript API允许把Google地图嵌入到自己的网页内。
要使用这个API,首先需要申请一个API key(/apis/maps/signup.html)。
收到5.1地图基础5.1.1Google Maps上的Hello World例子任何Google地图API应用程序中的基础元素都是地图本身。
重点讨论GMap2基础对象的用法和地图操作的基础。
学习这个API最简单的方法就是看一个简单的例子。
下面的网页显示一个500x300的Maps API key申请的授权码,否则看不到效果。
也需要注意五点:1)使用script标签包含地图API JavaScript。
2)创建名为"map_canvas"的div元素存放地图。
3)编写JavaScript函数创建“map”对象。
4) 将地图中的中心设置为给定的地理点。
5) 从body标签的onLoad事件初始化地图对象。
下面说明了这些步骤。
1.加载Google地图API/maps?file=api&v=2&key=abcdefg用Google地图API所需所有符号和定义的JavaScript文件的位置。
页面必须包含指向此网址的script标签,使用注册获取API时收到的密钥。
此示例中,该密钥为“abcdefg”。
浏览器的文档对象模型(DOM)中获取此元素的引用执行此操作。
上述示例中,定义名为"map_canvas"的div,并使用样式属性设置其尺寸。
地图会自动使用容器尺寸调整自身的尺寸,除非使用构造函数中的GMapOptions为地图明确指定尺寸。
建此类的多个实例,每个对象将在页面上定义一个不同的地图。
)使用JavaScript new操作符创建此类的一个新实例。
当创建新的地图实例时,在页面中指定一个DOM节点(通常是div元素)作为地图的容器。
你应该知道的25道Javascript面试题
你应该知道的25道Javascript⾯试题题⽬来⾃。
闲来⽆事,正好切⼀下。
⼀What is a potential pitfall with using typeof bar === "object" to determine if bar is an object? How can this pitfall be avoided?⽼⽣常谈的问题,⽤typeof是否能准确判断⼀个对象变量,答案是否定的,null的结果也是 object,Array的结果也是 object,有时候我们需要的是 "纯粹" 的 object 对象。
如何规避这个问题?var obj = {};// 1console.log((obj !== null) && (typeof obj === "object") && (toString.call(obj) !== "[object Array]"));// 2console.log(Object.prototype.toString.call(obj) === "[object Object]");⼆What will the code below output to the console and why?(function(){var a = b = 3;})();console.log("a defined? " + (typeof a !== 'undefined'));console.log("b defined? " + (typeof b !== 'undefined'));这题不难,IIFE 中的赋值过程其实是(赋值过程从右到左):(function(){b = 3;var a = b;})();接下去就不难了,a 是局部变量,b 是全局变量。
javascript英文单词总结
最常用的部分.(一个点)可能通俗的理解为从属关系。
比如:你.身体.胳膊.手.手指头。
这里的.就表示了一系列的从属关系。
()括号:加在一个方法名后面表示让这个方法运行。
括号本身也有运行的意思,比如:(4,3,5,7),这个就会返回一个7.var:JS中定义变是的关键字,如果定义变量时不使var关键字,则此变量为全局变量。
window是指浏览器对象,是JS编程中的顶级作用域,JS中的一切方法和属性,都是这个对象的后代document文档或文档对象,通俗的讲就是:凡是我们能看的见编码,就属于文档。
是window的子对象document.getElementById()通过id来获取一个HTML元素,以便我们用JS来控制操作。
比如:document.getElementById(‘div1′).style.color=’red’;获取id为div1的那个HTML 元素使它的文字颜色为红(.style.color);如果网页中(应该叫文档中)没有id是div1的元素,则得到一个null(空)document.getElementsByTagName()在整个网页内通过标签名(tagName)获得一组HTML元素的集合对象。
比如:document.getElementsByTagName(‘div’);就是在整个网页(文档)范围内获取所有的div元素,如果网页内没有div元素,返回一个空集合对象。
document.getElementsByTagName(‘div’).item(3);从得到的一组div中取得第四个div元素。
(3是索引值,从0开始,所以索引值为3就是第四个元素了)document. get ElementsByTagName(‘div’).length。
获取到的这一组div的个数(length是长度、个数的意思)body:指的是网页中body标记这个对象。
要写成document.body才可使用。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
ECMAScript recognises two categories of object, "Native Object" and "Host Object" with asub-category of native objects called "Built-in Object" (ECMA 262 3rd Ed Section 4.3). Native objects belong to the language and host objects are provided by the environment, and may be, for example, document objects, DOM nodes and the like.Native objects are loose and dynamic bags of named properties (some implementations are not that dynamic when it comes to the built in object sub-category, though usually that doesn't matter). The defined named properties of an object will hold a value, which may be a reference to another Object (functions are also Objects in this sense) or a primitive value: String, Number, Boolean, Null or Undefined. The Undefined primitive type is a bit odd inthat it is possible to assign a value of Undefined to a property of an object but doing so does not remove that property from the object; it remains a defined named property, it just holds the value undefined.The following is a simplified description of how property values are read and set on objects with the internal details brushed over to the greatest extent possible.Assignment of ValuesNamed properties of objects can be created, or values set on existing named properties, by assigning a value to that named property. So given:-var objectRef = new Object(); //create a generic javascript object.A property with the name "testNumber" can be created as:-objectRef.testNumber = 5;/* - or:- */objectRef["testNumber"] = 5;The object had no "testNumber" property prior to the assignment but one is created when the assignment is made. Any subsequent assignment does not need to create the property, it just re-sets its value:-objectRef.testNumber = 8;/* - or:- */objectRef["testNumber"] = 8;Javascript objects have prototypes that can themselves be objects, as will be described shortly, and that prototype may have named properties. But this has no role in assignment.If a value is assigned and the actual object does not have a property with the corresponding name a property of that name is created and the value is assigned to it. If it has the property then its value is re-set.Reading of ValuesIt is in reading values from object properties that prototypes come into play. If an object has a property with the property name used in the property accessor then the value of that property is returned:-/* Assign a value to a named property. If the object does not have aproperty with the corresponding name prior to the assignment itwill have one after it:-*/objectRef.testNumber = 8;/* Read the value back from the property:- */var val = objectRef.testNumber;/* and - val - now holds the value 8 that was just assigned to thenamed property of the object. */But all objects may have prototypes, and prototypes are objects so they, in turn, may have prototypes, which may have prototypes, and so on forming what is called the prototype chain. The prototype chain ends when one of the objects in the chain has a null prototype. The default prototype for the Object constructor has a null prototype so:-var objectRef = new Object(); //create a generic javascript object.Creates an object with the prototype Object.prototype that itself has a null prototype. So the prototype chain for objectRef contains only one object: Object.prototype. However:-/* A "constructor" function for creating objects of a -MyObject1 - type.*/function MyObject1(formalParameter){/* Give the constructed object a property called - testNumber - andassign it the value passed to the constructor as its firstargument:-*/this.testNumber = formalParameter;}/* A "constructor" function for creating objects of a -MyObject2 - type:-*/function MyObject2(formalParameter){/* Give the constructed object a property called - testString -and assign it the value passed to the constructor as its firstargument:-*/this.testString = formalParameter;}/* The next operation replaces the default prototype associated withall MyObject2 instances with an instance of MyObject1, passing theargument - 8 - to the MyObject1 constructor so that its -testNumber - property will be set to that value:-*/MyObject2.prototype = new MyObject1( 8 );/* Finally, create an instance of - MyObject2 - and assign a referenceto that object to the variable - objectRef - passing a string as thefirst argument for the constructor:-*/var objectRef = new MyObject2( "String_Value" );The instance of MyObject2 referred to by the objectRef variable has a prototype chain. Thefirst object in that chain is the instance of MyObject1 that was created and assigned to the prototype property of the MyObject2 constructor. The instance of MyObject1 has a prototype, the object that was assigned to the function MyObject1's prototype property by the implementation. That object has a prototype, the default Object prototype that corresponds with the object referred to by Object.prototype. Object.prototype has a null prototype so the prototype chain comes to an end at this point.When a property accessor attempts to read a named property form the object referred to by the variable objectRef the whole prototype chain can enter into the process. In the simple case:-var val = objectRef.testString;- the instance of MyObject2 referred to by objectRef has a property with the name "testString" so it is the value of that property, set to "String_Value", that is assigned to the variable val. However:-var val = objectRef.testNumber;- cannot read a named property form the instance of MyObject2 itself as it has no such property but the variable val is set to the value of 8 rather than undefined because having failed to find a corresponding named property on the object itself the interpreter then examines the object that is its prototype. Its prototype is the instance of MyObject1 and it was created with a property named "testNumber" with the value 8 assigned to that property, so the property accessor evaluates as the value 8. Neither MyObject1 or MyObject2 have defined a toString method, but if a property accessor attempts to read the value of a toString property from objectRef:-var val = objectRef.toString;- the val variable is assigned a reference to a function. That function is the toString property of Object.prototype and is returned because the process of examining the prototype of objectRef, when objectRef turns out not to have a "toString" property, is acting on an object, so when that prototype is found to lack the property its prototype is examined in turn. Its prototype is Object.prototype, which does have a toString method so it is a reference to that function object that is returned.Finally:-var val = objectRef.madeUpProperty;- returns undefined, because as the process of working up the prototype chain finds no properties on any of the object with the name "madeUpPeoperty" it eventually gets to the prototype of Object.prototype, which is null, and the process ends returning undefined.The reading of named properties returns the first value found, on the object or then fromits prototype chain. The assigning of a value to a named property on an object will create a property on the object itself if no corresponding property already exists.This means that if a value was assigned as objectRef.testNumber = 3 a "testNumber" propertywill be created on the instance of MyObject2 itself, and any subsequent attempts to read that value will retrieve that value as set on the object. The prototype chain no longer needs to be examined to resolve the property accessor, but the instance of MyObject1 with the value of 8 assigned to its "testNumber" property is unaltered. The assignment to the objectRef object masks the corresponding property in its prototype chain.Note: ECMAScript defines an internal [[prototype]] property of the internal Object type. This property is not directly accessible with scripts, but it is the chain of objects referred to with the internal [[prototype]] property that is used in property accessor resolution; the object's prototype chain. A public prototype property exists to allow the assignment, definition and manipulation of prototypes in association with the internal [[prototype]] property. The details of the relationship between to two are described in ECMA 262 (3rd edition) and are beyond the scope of this discussion.Identifier Resolution, Execution Contexts and scope chains The Execution ContextAn execution context is an abstract concept used by the ECMSScript specification (ECMA 2623rd edition) to define the behaviour required of ECMAScript implementations. The specification does not say anything about how execution contexts should be implemented but execution contexts have associated attributes that refer to specification defined structures so they might be conceived (and even implemented) as objects with properties, though not public properties.All javascript code is executed in an execution context. Global code (code executed inline,normally as a JS file, or HTML page, loads) gets executed in global execution context, andeach invocation of a function (possibly as a constructor) has an associated executioncontext. Code executed with the eval function also gets a distinct execution context but as eval is never normally used by javascript programmers it will not be discussed here. The specified details of execution contexts are to be found in section 10.2 of ECMA 262 (3rdedition).When a javascript function is called it enters an execution context, if another function iscalled (or the same function recursively) a new execution context is created and executionenters that context for the duration of the function call. Returning to the originalexecution context when that called function returns. Thus running javascript code forms astack of execution contexts.When an execution context is created a number of things happen in a defined order. First, inthe execution context of a function, an "Activation" object is created. The activationobject is another specification mechanism. It can be considered as an object because it endsup having accessible named properties, but it is not a normal object as it has no prototype(at least not a defined prototype) and it cannot be directly referenced by javascript code. The next step in the creation of the execution context for a function call is the creation of an arguments object, which is an array-like object with integer indexed members corresponding with the arguments passed to the function call, in order. It also has length and callee properties (which are not relevant to this discussion, see the spec for details).A property of the Activation object is created with the name "arguments" and a reference tothe arguments object is assigned to that property.Next the execution context is assigned a scope. A scope consists of a list (or chain) ofobjects. Each function object has an internal [[scope]] property (which we will go into moredetail about shortly) that also consists of a list (or chain) of objects. The scope that isassigned to the execution context of a function call consists of the list referred to by the [[scope]] property of the corresponding function object with the Activation object added at the front of the chain (or the top of the list).Then the process of "variable instantiation" takes place using an object that ECMA 262refers to as the "Variable" object. However, the Activation object is used as the Variableobject (note this, it is important: they are the same object). Named properties of theVariable object are created for each of the function's formal parameters, and if argumentsto the function call correspond with those parameters the values of those arguments areassigned to the properties (otherwise the assigned value is undefined). Inner functiondefinitions are used to create function objects which are assigned to properties of theVariable object with names that correspond to the function name used in the functiondeclaration. The last stage of variable instantiation is to create named properties of theVariable object that correspond with all the local variables declared within the function. The properties created on the Variable object that correspond with declared local variables are initially assigned undefined values during variable instantiation, the actualinitialisation of local variables does not happen until the evaluation of the correspondingassignment expressions during the execution of the function body code.It is the fact that the Activation object, with its arguments property, and the Variableobject, with named properties corresponding with function local variables, are the sameobject, that allows the identifier arguments to be treated as if it was a function localvariable.Finally a value is assigned for use with the this keyword. If the value assigned refers toan object then property accessors prefixed with the this keyword reference properties ofthat object. If the value assigned (internally) is null then the this keyword will refer tothe global object.The global execution context gets some slightly different handling as it does not havearguments so it does not need a defined Activation object to refer to them. The globalexecution context does need a scope and its scope chain consists of exactly one object, theglobal object. The global execution context does go through variable instantiation, its inner functions are the normal top level function declarations that make up the bulk of javascript code. The global object is used as the Variable object, which is why globally declared functions become properties of the global object. As do globally declared variables.The global execution context also uses a reference to the global object for the this object. scope chains and [[scope]]The scope chain of the execution context for a function call is constructed by adding the execution context's Activation/Variable object to the front of the scope chain held in the function object's [[scope]] property, so it is important to understand how the internal [[scope]] property is defined.In ECMAScript functions are objects, they are created during variable instantiation from function declarations, during the evaluation of function expressions or by invoking the Function constructor.Function objects created with the Function constructor always have a [[scope]] property referring to a scope chain that only contains the global object.Function objects created with function declarations or function expressions have the scope chain of the execution context in which they are created assigned to their internal [[scope]] property.In the simplest case of a global function declaration such as:-function exampleFunction(formalParameter){... // function body code}- the corresponding function object is created during the variable instantiation for the global execution context. The global execution context has a scope chain consisting of only the global object. Thus the function object that is created and referred to by the property of the global object with the name "exampleFunction" is assigned an internal [[scope]] property referring to a scope chain containing only the global object.A similar scope chain is assigned when a function expression is executed in the global context:-var exampleFuncRef = function(){... // function body code}- except in this case a named property of the global object is created during variable instantiation for the global execution context but the function object is not created, and a reference to it assigned to the named property of the global object, until the assignment expression is evaluated. But the creation of the function object still happens in the global execution context so the [[scope]] property of the created function object still only contains the global object in the assigned scope chain.Inner function declarations and expressions result in function objects being created within the execution context of a function so they get more elaborate scope chains. Consider the following code, which defines a function with an inner function declaration and then executes the outer function:-function exampleOuterFunction(formalParameter){function exampleInnerFuncitonDec(){... // inner function body}... // the rest of the outer function body.}exampleOuterFunction( 5 );The function object corresponding with the outer function declaration is created duringvariable instantiation in the global execution context so its [[scope]] property contains theone item scope chain with only the global object in it.When the global code executes the call to the exampleOuterFunction a new execution context iscreated for that function call and an Activation/Variable object along with it. The scope ofthat new execution context becomes the chain consisting of the new Activation objectfollowed by the chain refereed to by the outer function object's [[scope]] property (just theglobal object). Variable instantiation for that new execution context results in thecreation of a function object that corresponds with the inner function definition and the [[scope]] property of that function object is assigned the value of the scope from the execution context in which it was created. A scope chain that contains the Activation objectfollowed by the global object.So far this is all automatic and controlled by the structure and execution of the sourcecode. The scope chain of the execution context defines the [[scope]] properties of thefunction objects created and the [[scope]] properties of the function objects define thescope for their execution contexts (along with the corresponding Activation object). ButECMAScript provides the with statement as a means of modifying the scope chain.The with statement evaluates an expression and if that expression is an object it is addedto the scope chain of the current execution context (in front of the Activation/Variableobject). The with statement then executes another statement (that may itself be a blockstatement) and then restores the execution context's scope chainto what it was before.A function declaration could not be affected by a with statement as they result in thecreation of function objects during variable instantiation, but a function expression can beevaluated inside a with statement:-/* create a global variable - y - that refers to an object:- */var y = {x:5}; // object literal with an - x - propertyfunction exampleFuncWith(){var z;/* Add the object referred to by the global variable - y - to thefront of he scope chain:-*/with(y){/* evaluate a function expression to create a function objectand assign a reference to that function object to the localvariable - z - :-*/z = function(){... // inner function expression body;}}...}/* execute the - exampleFuncWith - function:- */exampleFuncWith();When the exampleFuncWith function is called the resulting execution context has a scope chainconsisting of its Activation object followed by the global object. The execution of the withstatement adds the object referred to by the global variable y to the front of that scopechain during the evaluation of the function expression. The function object created by theevaluation of the function expression is assigned a [[scope]] property that corresponds withthe scope of the execution context in which it is created. A scope chain consisting ofobject y followed by the Activation object from the execution context of the outer functioncall, followed by the global object.When the block statement associated with the with statement terminates the scope of the execution context is restored (the y object is removed), but the function object has been created at that point and its [[scope]] property assigned a reference to a scope chain with the y object at its head.Identifier ResolutionIdentifiers are resolved against the scope chain. ECMA 262 categorises this as a keyword rather than an identifier, which is not unreasonable as it is always resolved dependent on the this value in the execution context in which it is used, without reference to the scope chain.Identifier resolution starts with the first object in the scope chain. It is checked to see if it has a property with a name that corresponds with the identifier. Because the scope chain is a chain of objects this checking encompasses the prototype chain of that object (if it has one). If no corresponding value can be found on the first object in the scope chain the search progresses to the next object. And so on until one of the objects in the chain (or one of its prototypes) has a property with a name that corresponds with the identifier or the scope chain is exhausted.The operation on the identifier happens in the same way as the use of property accessors on objects described above. The object identified in the scope chain as having the corresponding property takes the place of the object in the property accessor and the identifier acts as a property name for that object. The global object is always at the end of the scope chain.As execution contexts associated with function calls will have the Activation/Variable object at the front of the chain, identifiers used in function bodies are effectively first checked to see whether they correspond with formal parameters, inner function declaration names or local variables. Those would be resolved as named properties of theActivation/Variable object.ClosuresAutomatic Garbage CollectionECMAScript uses automatic garbage collection. The specification does not define the details, leaving that to the implementers to sort out, and some implementations are known to give a very low priority to their garbage collection operations. But the general idea is that if an object becomes un-referable (by having no remaining references to it left accessible to executing code) it becomes available for garbage collection and will at some future point be destroyed and any resources it is consuming freed and returned to the system for re-use. This would normally be the case upon exiting an execution context. The scope chain structure, the Activation/Variable object and any objects created within the execution context, including function objects, would no longer be accessible and so would become available for garbage collection.Forming ClosuresA closure is formed by returning a function object that was created within an execution context of a function call from that function call and assigning a reference to that inner function to a property of another object. Or by directly assigning a reference to such a function object to, for example, a global variable, a property of a globally accessible object or an object passed by reference as an argument to the outer function call. e.g:-function exampleClosureForm(arg1, arg2){var localVar = 8;function exampleReturned(innerArg){return ((arg1 + arg2)/(innerArg + localVar));}/* return a reference to the inner function defined as -exampleReturned -:-*/return exampleReturned;}var globalVar = exampleClosureForm(2, 4);Now the function object created within the execution context of the call to exampleClosureForm cannot be garbage collected because it is referred to by a global variable and is still accessible, it can even be executed with globalVar(n).But something a little more complicated has happened because the function object nowreferred to by globalVar was created with a [[scope]] property referring to a scope chain containing the Activation/Variable object belonging to the execution context in which it was created (and the global object). Now the Activation/Variable object cannot be garbage collected either as the execution of the function object referred to by globalVar will needto add the whole scope chain from its [[scope]] property to the scope of the execution context created for each call to it.A closure is formed. The inner function object has the free variables and theActivation/Variable object on the function's scope chain is the environment that binds them. The Activation/Variable object is trapped by being referred to in the scope chain assignedto the internal [[scope]] property of the function object now referred to by the globalVar variable. The Activation/Variable object is preserved along with its state; the values ofits properties. Scope resolution in the execution context of calls to the inner functionwill resolve identifiers that correspond with named properties of that Activation/Variable object as properties of that object. The value of those properties can still be read and set even though the execution context for which it was created has exited.In the example above that Activation/Variable object has a state that represents the values of formal parameters, inner function definitions and local variables, at the time when the outer function returned (exited its execution context). The arg1 property has the value2,the arg2 property the value 4, localVar the value 8 and an exampleReturned property that is a reference to the inner function object that was returned form the outer function. (We will be referring to this Activation/Variable object as "ActOuter1" in later discussion, for convenience.)If the exampleClosureForm function was called again as:-var secondGlobalVar = exampleClosureForm(12, 3);- a new execution context would be created, along with a new Activation object. And a new function object would be returned, with its own distinct [[scope]] property referring to a scope chain containing the Activation object form this second execution context, with arg1 being 12 and arg2 being 3. (We will be referring to this Activation/Variable object as "ActOuter2" in later discussion, for convenience.)A second and distinct closure has been formed by the second execution of exampleClosureForm. The two function objects created by the execution of exampleClosureForm to which references have been assigned to the global variable globalVar and secondGlobalVar respectively, return the expression ((arg1 + arg2)/(innerArg + localVar)). Which applies various operators to four identifiers. How these identifiers are resolved is critical to the use and value of closures.Consider the execution of the function object referred to by globalVar, as globalVar(2). A new execution context is created and an Activation object (we will call it "ActInner1"), whichis added to the head of the scope chain referred to the [[scope]] property of the executed function object. ActInner1 is given a property named innerArg, after its formal parameter and the argument value 2 assigned to it. The scope chain for this new execution context is:ActInner1->ActOuter1->global object.Identifier resolution is done against the scope chain so in order to return the value of the expression ((arg1 + arg2)/(innerArg + localVar)) the values of the identifiers will be determined by looking for properties, with names corresponding with the identifiers, on each object in the scope chain in turn.The first object in the chain is ActInner1 and it has a property named innerArg with the value 2. All of the other 3 identifiers correspond with named properties of ActOuter1; arg1 is 2, arg2 is 4 and localVar is 8. The function call returns ((2 + 4)/(2 + 8)).Compare that with the execution of the otherwise identical function object referred to by secondGlobalVar, as secondGlobalVar(5). Calling the Activation object for this new execution context "ActInner2", the scope chain becomes: ActInner2->ActOuter2->global object. ActInner2 returns innerArg as 5 and ActOuter2 returns arg1, arg2 and localVar as 12, 3 and 8 respectively. The value returned is ((12 + 3)/(5 + 8)).Execute secondGlobalVar again and a new Activation object will appear at the front of the scope chain but ActOuter2 will still be next object in the chain and the value of its named properties will again be used in the resolution of the identifiers arg1, arg2 and localVar. This is how ECMAScript inner functions gain, and maintain, access to the formal parameters, declared inner functions and local variables of the execution context in which they were created. And it is how the forming of a closure allows such a function object to keep referring to those values, reading and writing to them, for as long as it continues to exist. The Activation/Variable object from the execution context in which the inner function was created remains on the scope chain referred to by the function object's [[scope]] property, until all references to the inner function are freed and the function object is made available for garbage collection (along with any now unneeded objects on its scope chain).Inner function may themselves have inner functions, and the inner functions returned from the execution of functions to form closures may themselves return inner functions and form closures of their own. With each nesting the scope chain gains extra Activation objects originating with the execution contexts in which the inner function objects were created. The ECMAScript specification requires a scope chain to be finite, but imposes no limits on their length. Implementations probably do impose some practical limitation but no specific magnitude has yet been reported. The potential for nesting inner functions seems so far to have exceeded anyone's desire to code them.What can be done with Closures?Strangely the answer to that appears to be anything and everything. I am told that closures enable ECMAScript to emulate anything, so the limitation is the ability to conceive and implement the emulation. That is a bit esoteric and it is probably better to start with something a little more practical.Example 1: setTimeout with Function ReferencesA common use for a closure is to provide parameters for the execution of a function prior to the execution of that function. For example, when a function is to be provided as the first argument to the setTimout function that is common in web browser environments.setTimeout schedules the execution of a function (or a string of javascript source code, but not in this context), provided as its first argument, after an interval expressed in milliseconds (as its second argument). If a piece of code wants to use setTimeout it calls the setTimeout function and passes a reference to a function object as the first argument and the millisecond interval as the second, but a reference to a function object cannot provide parameters for the scheduled execution of that function.However, code could call another function that returned a reference to an inner function。