js闭包理解面试题

合集下载

前端开发工程师面试题及答案

前端开发工程师面试题及答案

前端开发工程师面试题及答案在前端开发领域,面试是选拔优秀人才的重要环节。

以下是一些常见的前端开发工程师面试题以及对应的参考答案。

一、HTML 和 CSS 相关问题1、解释一下盒模型以及它在布局中的作用。

答案:盒模型是 CSS 中用于布局的基本概念,它由内容(content)、内边距(padding)、边框(border)和外边距(margin)组成。

在布局中,理解盒模型对于准确计算元素的尺寸和间距非常重要,能够帮助我们实现各种复杂的页面布局。

2、如何实现一个两栏布局,左边固定宽度,右边自适应?答案:可以使用多种方法实现。

一种常见的方式是使用浮动(float),将左边栏设置为固定宽度并向左浮动,右边栏不浮动,并设置其左边的外边距(marginleft)为左边栏的宽度。

也可以使用 flex 布局,将父容器设置为 display: flex; ,左边栏设置固定宽度,右边栏设置flex: 1; 以实现自适应。

3、说一说 CSS 选择器的种类和优先级。

答案:CSS 选择器包括元素选择器、类选择器、id 选择器、属性选择器、伪类选择器、伪元素选择器等。

选择器的优先级从高到低依次为:内联样式(通过 style 属性设置)> id 选择器>类选择器、属性选择器、伪类选择器>元素选择器、伪元素选择器。

二、JavaScript 相关问题1、谈谈你对 JavaScript 中作用域和闭包的理解。

答案:作用域决定了变量的可见性和可访问性。

在 JavaScript 中有全局作用域和函数作用域。

闭包是指有权访问另一个函数作用域中的变量的函数。

闭包可以让函数记住其创建时的环境,即使外部函数已经执行完毕,闭包仍能访问外部函数中的变量。

2、如何实现 JavaScript 的继承?答案:常见的实现方式有原型链继承、借用构造函数继承、组合继承、寄生组合继承等。

原型链继承通过将子类型的原型指向父类型的实例来实现继承;借用构造函数继承通过在子类型的构造函数中调用父类型的构造函数来继承属性;组合继承结合了原型链继承和借用构造函数继承的优点;寄生组合继承是一种优化的组合继承方式,避免了不必要的父类实例属性的重复创建。

JS面试题--使用for循环打印1-10,每个数字出现的间隔约500ms

JS面试题--使用for循环打印1-10,每个数字出现的间隔约500ms

JS⾯试题--使⽤for循环打印1-10,每个数字出现的间隔约500ms ⼜来刷⾯试题啦,哈哈。

要求:使⽤for循环打印1-10,每个数字出现的间隔约500ms。

分析:考察点--闭包,块级作⽤域
⽅式⼀、使⽤闭包+⽴即执⾏函数,⾃⼰当时的思路也是这样想的,但是,结果却没有体现间隔500ms
/*结果虽然依次输出了1-10,但是每个数字之间没有间隔,是⼀次性输出的,所以不正确*/
for (var i = 1; i <= 10; i++) {
setTimeout((function(i) {
console.log(i);
})(i), 500);
}
经过修改,结果满⾜要求:1.setTimeout每次的间隔500*i,保证每隔500ms输出⼀次 2.将⽴即执⾏移到外层
/**
* 使⽤for循环打印1-10,每个数字出现的间隔约500ms
* ⽅法⼀、使⽤闭包,注意setTimeout,每隔500ms,因此每次传递的间隔时间要乘以i
*/
for(var i=1;i<=10;i++){
(function(i){
setTimeout(function(){
console.log(i);
},500*i);
})(i);
}
⽅法⼆、使⽤let,let本⾝就是块级作⽤域
for(let i=1;i<=10;i++){
setTimeout(function(){
console.log(i);
},500*i);
}。

闭包的面试题

闭包的面试题

闭包的面试题闭包是JavaScript中一个重要的概念,在面试中也经常会遇到与闭包相关的面试题。

下面将介绍一些常见的闭包面试题,并解答这些问题。

题目一:什么是闭包?回答:闭包是指有权访问另一个函数作用域中变量的函数。

闭包使得函数可以保留对其创建时所在作用域的访问权,即使该函数在其创建时所在的作用域之外执行。

题目二:请给出一个闭包的实例。

回答:以下是一个闭包的例子:```javascriptfunction outer() {var count = 0;function inner() {count++;console.log(count);}return inner;}var closure = outer();closure(); // 输出1closure(); // 输出2```在这个例子中,`inner`函数可以访问`outer`函数中的`count`变量,即使`outer`函数已经执行完毕并返回了。

通过将`inner`函数赋值给`closure`变量,我们创建了一个闭包,使得`inner`函数仍然可以访问并修改`count`变量。

题目三:闭包有什么应用场景?回答:闭包在JavaScript中有许多应用场景,以下列举几个常见的例子:1. 封装私有变量:通过闭包,我们可以创建仅在特定函数范围内访问的私有变量,防止变量被外部访问和修改。

2. 计数器:使用闭包可以创建计数器函数,每次调用计数器函数时,返回的值会自增。

3. 延迟函数执行:通过使用闭包,我们可以延迟函数的执行,将函数定义和函数执行的时机分开。

4. 模块化开发:使用闭包可以实现模块化开发,将代码划分为独立的模块,提高代码的可维护性和复用性。

题目四:闭包会有什么问题?回答:虽然闭包在某些情况下非常有用,但也会带来一些问题。

其中最常见的问题是内存泄漏。

当一个函数形成闭包后,它会继续持有对其所在作用域的引用,导致作用域的变量无法被垃圾回收机制回收。

javascript面试题

javascript面试题

1、form中的input有哪些类型?各是做什么处理使用的?text radio c heckbox file button image submit reset hiddensubmit是button的一个特例,也是button的一种,它把提交这个动作自动集成了。

如果表单在点击提交按钮后需要用JS进行处理(包括输入验证)后再提交的话,通常都必须把submit 改成button,即取消其自动提交的行为,否则,将会造成提交两次的效果,对于动态网页来说,也就是对数据库操作两次。

button具有name、v alue属性,能触发onclick事件submit继承了buttonsubmit增加了触发表单onsubmit事件的功能、增加了执行表单的submit()方法的功能INPUT type=submit按回车提交表单button提交的是innerTEXT2、table标签中border,c ellpadding td标签中c olspan,rowspan分别起什么作用?border边界cellpadding边距cellpadding,是补白,是指单元格内文字与边框的距离cellspacing,两个单元格之间的距离colspan跨列数rowspan跨行数3、form中的input可以设置readonly和disable,请问这两项属性有什么区别?readonly不可编辑,但可以选择和复制disable不能编辑复制选择4、JS中的三种弹出式消息提醒(警告窗口、确认窗口、信息输入窗口)的命令是什么?alertconfirmprompt5.题目:当点击按钮时,如何实现两个td的值互换?用jav asc ript实现此功能。

分析:这个题主要是考变量传值。

其次是考如何取元素的值。

第一种代码如下:Code1<!DOCTYPE html PUBLIC"-//W3C//DTD XHTML 1.0 Transitional//EN" "/TR/xhtml1/DTD/xhtml1-transitional.dtd">2<html xmlns="/1999/xhtml">3<head>4<meta http-equiv="Content-Type"content="text/html; charset=gb2312"/>5<title>无标题文档</title>6<script type="text/javascript">7//<![CDATA[8function submitbtn() {910var tText1=document.getElementById('txt1');11var SubmitBtn1=document.getElementById('submitBtn1');12var tText2=document.getElementById('txt2');13var SubmitBtn2=document.getElementById('submitBtn2');14 SubmitBtn1.onclick=function() {15var temp=tText1.value;16 tText1.value=tText2.value;17 tText2.value=temp;18 };19 SubmitBtn2.onclick=function() {20var temp=tText2.value;21 tText2.value=tText1.value;22 tText1.value=temp;23 };24}25window.onload=function() {26 submitbtn();27}28//]]>29</script>30</head>3132<body>33<input type="text"value="12345666"id="txt1"/>34<input type="submit"id="submitBtn1"/>35<input type="text"value="12345222"id="txt2"/>36<input type="submit"id="submitBtn2"/>37</body>38</html>复制代码第二种代码如下:Code1<!DOCTYPE html PUBLIC"-//W3C//DTD XHTML 1.0 Transitional//EN" "/TR/xhtml1/DTD/xhtml1-transitional.dtd">2<html xmlns="/1999/xhtml">3<head>4<meta http-equiv="Content-Type"content="text/html; charset=gb2312"/> 5<title>无标题文档</title>6<script type="text/javascript">7//<![CDATA[8function submitbtn() {910var tText1=document.getElementById('txt1');11var SubmitBtn1=document.getElementById('submitBtn1');12var tText2=document.getElementById('txt2');13var SubmitBtn2=document.getElementById('submitBtn2');14 SubmitBtn1.onclick=function() {15var temp=tText1.innerHTML;16 tText1.innerHTML=tText2.innerHTML;17 tText2.innerHTML=temp;18 };19 SubmitBtn2.onclick=function() {20var temp=tText2.innerHTML;21 tText2.innerHTML=tText1.innerHTML;22 tText1.innerHTML=temp;23 };24}25window.onload=function() {26 submitbtn();27}28//]]>29</script>30</head>3132<body>33<table width="200"border="1"cellpadding="0"cellspacing="0">34<tr>35 <td id="txt1">321445</td>36 <td><input type="submit"id="submitBtn1"/></td>37</tr>38<tr>39 <td id="txt2">123133</td>40 <td><input type="submit"id="submitBtn2"/></td>41</tr>42</table>43</body>44</html>45复制代码6. "闭包"问题Code<!DOCTYPE html PUBLIC"-//W3C//DTD XHTML 1.0 Transitional//EN" "/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="/1999/xhtml"><head><title>Untitled Page</title><script type="text/javascript">window.onload=function(){var ii,a="";var d=document.getElementsByTagName("DIV");for(ii=0;ii<d.length;ii++){if(d[ii].id=="top"){a=d[ii].getElementsByTagName("li");for(var i=0;i<a.length;i++){//a[i].onmouseover=function(){show(i)}; //此处的i是一个变量,在运行show取i的值,很显示你的i每次都会最终变成a.lengtha[i].onmouseover=new Function("show("+i+")");//这里的i是一个常量,就是此刻i是值}}}}function show(z){alert(z);}</script></head><body><div>div1</div><div id="top"><ul><li>a</li><li>a</li><li>a</li><li>a</li><li>a</li></ul></div></body></html>复制代码使用注释行的时候,总是提示5.在一般编程语言中, 参数都是"传值", 假设一个C函数的原型是int Fun(int value);当你调用这个函数时, Fun函数首先会在自己的函数栈上copy一份参数, 就是这个函数的副本, 当你在Fun 外部修改value值, 并不会影响Fun内部的v alue.而Jav asc ript的内嵌函数很特殊, 它并不会copy一个参数副本, 所有函数公用一套参数, 所以你在函数外部修改了参数值, 函数内部也会受影响.这就是为什么你的show函数, 它的z参数是最后一个值, 因为每一次循环, z都被更改了. 传值和传址的问题一、单选题1、以下哪条语句会产生运行错误:()A.var obj = ( );B.var obj = [ ];C.var obj = { };D.var obj = / /;2、以下哪个单词不属于javascript保留字:()A.withB.parentC.classD.void3、请选择结果为真的表达式:()A.null instanceof ObjectB.null === undefinedC.null == undefinedD.NaN == NaN二、不定项选择题4、请选择对javascript理解有误的:()A.JScript是javascript的简称B.javascript是网景公司开发的一种Java脚本语言,其目的是为了简化Java的开发难度C.FireFox和IE存在大量兼容性问题的主要原因在于他们对javascript的支持不同上D.AJAX技术一定要使用javascript技术5、foo对象有att属性,那么获取att属性的值,以下哪些做法是可以的:()A.foo.attB.foo(“att”)C.foo[“att”]D.foo{“att”}E.foo[“a”+”t”+”t”]6、在不指定特殊属性的情况下,哪几种HTML标签可以手动输入文本:()1 2 3 4A.<TEXTAREA></TEXTAREA>B.<INPUT type=”text”/>C.<INPUT type=”hidden”/>D.<DIV></DIV>7、以下哪些是javascript的全局函数:()A.escapeB.parseFloatC.evalD.setTimeoutE.alert8、关于IFrame表述正确的有:()A.通过IFrame,网页可以嵌入其他网页内容,并可以动态更改B.在相同域名下,内嵌的IFrame可以获取外层网页的对象C.在相同域名下,外层网页脚本可以获取IFrame网页内的对象D.可以通过脚本调整IFrame的大小9、关于表格表述正确的有:()A.表格中可以包含TBODY元素B.表格中可以包含CAPTION元素C.表格中可以包含多个TBODY元素D.表格中可以包含COLGROUP元素E.表格中可以包含COL元素10、关于IE的window对象表述正确的有:()A.window.opener属性本身就是指向window对象B.window.reload()方法可以用来刷新当前页面C.window.location=”a.html”和window.location.href=”a.html”的作用都是把当前页面替换成a.html页面D.定义了全局变量g;可以用window.g的方式来存取该变量三、问答题:1、谈谈javascript数组排序方法sort()的使用,重点介绍sort()参数的使用及其内部机制2、简述DIV元素和SPAN元素的区别。

js常见的面试题及答案

js常见的面试题及答案

js常见的面试题及答案1. 什么是闭包,它有什么作用?闭包是一个函数和声明该函数的词法环境的组合。

闭包的主要作用是允许一个函数访问其词法作用域之外的变量,即使在函数执行完毕后,这些变量依然可以被访问和操作。

2. 解释JavaScript中的原型继承。

JavaScript中的原型继承是通过原型链实现的。

每个对象都有一个原型对象,对象的属性和方法首先在自身查找,如果找不到,则沿着原型链向上查找,直到Object.prototype。

3. 如何判断一个变量是数组类型?可以使用`Array.isArray()`方法来判断一个变量是否是数组类型。

这是一个简单且推荐的方式。

4. 解释`var`、`let`和`const`之间的区别。

- `var`声明的变量具有函数作用域或全局作用域,并且存在变量提升。

- `let`声明的变量具有块级作用域,不存在变量提升。

- `const`声明的常量也具有块级作用域,并且一旦赋值后无法修改。

5. 什么是事件冒泡和事件捕获?事件冒泡是指事件从最具体的元素(事件的实际目标)开始,然后逐级向上传播到较为不具体的节点(通常是文档的根节点)。

事件捕获则是相反的过程,事件从最不具体的节点开始捕获,然后逐级向下传播到最具体的节点。

6. 解释JavaScript中的异步编程。

JavaScript中的异步编程允许代码在等待操作完成(如网络请求、文件读写等)的同时继续执行其他任务。

常见的异步编程模式包括回调函数、Promises和async/await。

7. 什么是深拷贝和浅拷贝?浅拷贝只复制对象的第一层属性,而深拷贝则递归复制对象的所有层级。

浅拷贝可能导致原始对象和拷贝对象共享引用,而深拷贝则创建了对象的完全独立的副本。

8. 解释JavaScript中的事件循环。

事件循环是JavaScript运行时环境的一部分,它负责管理异步任务的执行。

当一个异步任务(如setTimeout)被调度时,事件循环会在任务队列中等待,直到它被执行栈调用。

什么是闭包?请举例说明(面试题目)

什么是闭包?请举例说明(面试题目)

什么是闭包?请举例说明(⾯试题⽬)⼀、变量的作⽤域要理解闭包,⾸先必须理解Javascript特殊的变量作⽤域。

变量的作⽤域⽆⾮就是两种:全局变量和局部变量。

Javascript语⾔的特殊之处,就在于函数内部可以直接读取全局变量。

Js代码 var n=999; function f1(){ alert(n); } f1(); // 999另⼀⽅⾯,在函数外部⾃然⽆法读取函数内的局部变量。

Js代码 function f1(){ var n=999; } alert(n); // error这⾥有⼀个地⽅需要注意,函数内部声明变量的时候,⼀定要使⽤var命令。

如果不⽤的话,你实际上声明了⼀个全局变量!Js代码 function f1(){ n=999; } f1(); alert(n); // 999--------------------------------------------------------------------------------------------------------⼆、如何从外部读取局部变量?出于种种原因,我们有时候需要得到函数内的局部变量。

但是,前⾯已经说过了,正常情况下,这是办不到的,只有通过变通⽅法才能实现。

那就是在函数的内部,再定义⼀个函数。

Js代码 function f1(){ n=999; function f2(){ alert(n); // 999 } }在上⾯的代码中,函数f2就被包括在函数f1内部,这时f1内部的所有局部变量,对f2都是可见的。

但是反过来就不⾏,f2内部的局部变量,对f1 就是不可见的。

这就是Javascript语⾔特有的“链式作⽤域”结构(chain scope),⼦对象会⼀级⼀级地向上寻找所有⽗对象的变量。

所以,⽗对象的所有变量,对⼦对象都是可见的,反之则不成⽴。

既然f2可以读取f1中的局部变量,那么只要把f2作为返回值,我们不就可以在f1外部读取它的内部变量了吗!Js代码function f1(){ n=999; function f2(){ alert(n); } return f2; } var result=f1(); result(); // 999--------------------------------------------------------------------------------------------------------三、闭包的概念上⼀节代码中的f2函数,就是闭包。

前端js面试题及答案

前端js面试题及答案

前端js面试题及答案面试是求职者进入前端行业的重要环节,了解常见的前端JavaScript面试题及相应的答案是备战面试的关键。

本文将介绍一些常见的前端JavaScript面试题及答案,以帮助读者更好地应对面试。

一、JavaScript基础1. 什么是JavaScript?JavaScript是一种广泛应用于网页端的脚本语言,它可以为网页添加交互性和动态性。

2. JavaScript有哪些数据类型?JavaScript有七种数据类型,包括未定义的(undefined)、空值(null)、布尔值(boolean)、数字(number)、字符串(string)、对象(object)和符号(symbol)。

3. JavaScript中的闭包是什么?闭包是指一个函数可以访问并操作其所在外部函数的变量。

它可以使用父函数中的变量并将其保留在内存中,即使父函数已经执行完毕。

4. JavaScript中的作用域是什么?作用域指的是变量的可访问范围。

在JavaScript中,有全局作用域和函数作用域。

全局作用域中定义的变量可以在整个代码中访问,而函数作用域中定义的变量只能在函数内部访问。

5. 如何避免JavaScript中的变量污染?可以使用立即调用的函数表达式(IIFE)来创建一个独立的作用域,这样变量就不会泄漏到全局作用域中。

另外,使用严格模式("use strict")也可以限制变量的作用范围。

二、DOM操作1. 什么是DOM?DOM(Document Object Model)是一种用于处理HTML和XML文档的编程接口。

它将文档视为一个由节点组成的树状结构,通过操作这些节点可以改变文档的结构、样式和内容。

2. 如何通过JavaScript创建一个新的元素节点?可以使用document.createElement()方法创建一个新的元素节点,并使用appendChild()方法将其添加到文档中。

js闭包面试题

js闭包面试题

js闭包面试题在面试中,经常会遇到JS闭包相关的问题。

能够正确回答这些问题,不仅展示了你对JS闭包的理解程度,还能够展示你对JS底层原理的掌握。

下面将介绍一些常见的JS闭包面试题,并给出详细的解析。

问题一:什么是闭包?请举一个简单的例子来说明。

闭包是指内部函数可以访问外部函数作用域中的变量,即使外部函数已经执行完毕。

一个典型的闭包例子是在一个函数内部定义另外一个函数,并且返回这个函数。

下面给出一个例子来说明闭包的概念。

```javascriptfunction outerFunction() {var outerVariable = "I am outside!";function innerFunction() {console.log(outerVariable);}return innerFunction;}var closureExample = outerFunction();closureExample(); // 输出"I am outside!"```在这个例子中,`innerFunction`内部定义了一个对外部函数`outerFunction`中的变量`outerVariable`的引用,尽管`outerFunction`已经执行完毕,但是由于闭包的存在,`innerFunction`仍然可以访问并输出`outerVariable`的值。

问题二:闭包有哪些优缺点?请举例说明。

闭包的优点:1. 可以实现信息隐藏和封装,保护数据的安全性。

2. 可以模拟私有变量和方法,实现面向对象编程的特性。

3. 可以实现函数的记忆功能,提高程序执行效率。

闭包的缺点:1. 内存占用较大:由于闭包会引用外部函数的作用域,导致外部函数的局部变量无法被垃圾回收机制回收,占用内存较多。

2. 可能会造成内存泄漏:如果不适当地使用闭包,可能会导致内存泄漏问题,即使外部函数执行完毕,仍然无法释放内存。

睿联技术面试题目及答案

睿联技术面试题目及答案

睿联技术面试题目及答案尊敬的应聘者,感谢您对睿联技术的关注并参与我们的面试。

以下是一些常见的技术面试题目及其答案,希望对您的面试准备有所帮助。

1. 什么是回调函数(Callback Function)?回调函数是一种在特定条件下由另一个函数来调用的函数。

它可以作为参数被传递给调用函数,并在满足特定条件时被调用。

2. 请解释什么是闭包(Closure)?闭包是指一个函数内部包含了对外部函数作用域中变量的引用,并且该函数可以在外部函数执行完毕后仍然能够访问到这些变量。

闭包可以延长变量的生命周期,并提供了对私有变量的访问方式。

3. 请描述什么是 RESTful API?RESTful API是一种基于REST(Representational State Transfer)原则的应用程序接口设计风格。

它通过使用HTTP协议的不同方法(GET、POST、PUT、DELETE等)来实现对网络资源的增删改查操作。

4. 请解释什么是数据库事务(Database Transaction)?数据库事务是指由一组数据库操作构成的逻辑工作单元,它要么完全执行,要么完全不执行,不存在部分执行的情况。

事务具有ACID(原子性、一致性、隔离性、持久性)特性,可以确保数据的完整性和一致性。

5. 请描述HTTP和HTTPS的区别。

HTTP(Hypertext Transfer Protocol)是一种用于传输超文本的应用层协议,它基于TCP/IP协议,用于在客户端和服务器之间传输信息。

而HTTPS是在HTTP的基础上加入了SSL/TLS协议层,用于对网络传输进行加密和身份验证,提供了更安全的数据传输方式。

6. 请解释什么是跨域请求(Cross-Origin Request)?跨域请求是指在浏览器中向不同域名、不同端口或不同协议的服务器发送请求的行为。

由于浏览器的同源策略限制,跨域请求会收到一定的限制,如不允许读取和修改响应内容。

js试题及答案

js试题及答案

js试题及答案1. 单选题:以下哪个选项是JavaScript中声明变量的正确方式?A. var variableB. var variable;C. variableD. variable;答案:B2. 多选题:在JavaScript中,以下哪些是合法的变量名?A. _variableB. $variableC. 2variableD. variableName答案:A, B, D3. 判断题:JavaScript中,函数可以作为值传递。

正确/错误答案:正确4. 填空题:在JavaScript中,使用______( )函数可以创建一个新对象。

答案:new Object5. 简答题:请简述JavaScript中闭包的概念。

答案:闭包是指一个函数和它声明时所在的词法环境的组合。

它允许函数访问其定义时的作用域链,即使在其定义的作用域之外执行。

6. 编程题:编写一个JavaScript函数,该函数接受一个数字数组作为参数,并返回数组中的最大值。

```javascriptfunction findMaxValue(arr) {return Math.max(...arr);}```7. 单选题:以下哪个选项不是JavaScript中的数据类型?A. NumberB. StringC. BooleanD. Undefined答案:D8. 多选题:在JavaScript中,以下哪些是字符串对象的方法?A. toLowerCase()B. toUpperCase()C. split()D. join()答案:A, B, C, D9. 判断题:JavaScript中,使用`==`运算符时,会进行类型转换。

正确/错误答案:正确10. 填空题:在JavaScript中,使用______( )函数可以获取当前日期和时间。

答案:new Date11. 简答题:请解释JavaScript中的原型继承。

答案:JavaScript中的原型继承是通过原型链实现的。

javascript面试题及答案

javascript面试题及答案

javascript面试题及答案javascript面试题及答案(一)一、假设为页面的onload事件指定了事件处理函数,如何删除该事件处理函数。

如何为一个事件指定两个或多个处理函数。

functionaddLoadEvent(func){varoldonLoad=window.onload;if(typeofwindow.onload!=function){window.onload=func;}else{window.onload=function(){oldonload();func();}}}addLoadEvent函数主要是完成如下的操作:1、把现有的window.onload事件处理函数的值存入到oldonload中。

2、如果在这个处理函数上还没有绑定任何函数,就将该函数添加给它。

3、如果在这个处理函数上已经绑定了一些函数,就把该函数追加到现有指定的末尾。

通过addLoadEvent函数,只需要调用该函数就可以进行绑定了。

二、写一个函数,返回指定的英文句子中的每个单词及其字符的起止位置,单词间使用一个空格隔开按空格拆分到数组里,取出每个元素三、构造一个自定义对象,实现对一个矩形的对象化,要求:a)描述矩形的标识(name)b)描述矩形的颜色(color)c)描述矩形的宽度(width)d)描述矩形的高度(height)e)提供获取矩形面积的方法(getArea())f)写出构造函数的完整代码g)给出调用的实例代码四、frame之间如何交换数据,frame和iframe有什么区别,iframe有哪些用途。

window.parent.frames它不同于Frame标记最大的特征即这个标记所引用的HTML文件不是与另外的HTML文件相互独立显示,而是可以直接嵌入在一个HTML文件中,与这个HTML 文件内容相互融合,成为一个整体;因为它可以多次在一个页面内显示同一内容,而不必重复写内容,所以人们形象称这种效果为“画中画”。

前端面试常见问题解答

前端面试常见问题解答

前端面试常见问题解答前言:前端工程师是当今互联网行业中非常热门的职位之一。

为了更好地应对面试时的挑战,以下是一些前端面试中经常被问及的问题及其解答。

希望这些内容能帮助你更好地准备自己的面试。

问题一:请介绍一下前端开发。

解答:前端开发是指使用 HTML、CSS 和 JavaScript 等技术来构建和设计用户在浏览器中与之交互的网页或者应用程序的过程。

前端开发既关注用户界面的呈现和交互体验,也关注与后端的数据交互和处理。

问题二:请描述一下 HTML、CSS 和 JavaScript 在前端开发中的作用。

解答:HTML(超文本标记语言)负责定义网页的结构和内容。

CSS(层叠样式表)用于设置网页的样式和外观。

JavaScript 是一种脚本语言,可以实现动态的页面效果和与用户的交互。

问题三:请解释一下什么是响应式设计(Responsive Design)。

解答:响应式设计是一种能够适应不同设备尺寸和屏幕分辨率的网页设计方法。

通过使用弹性布局、媒体查询、流式图片等技术,使网页在不同的设备上都能够提供最佳的视觉和用户体验。

问题四:请介绍一下盒子模型(Box Model)。

解答:盒子模型用于描述网页中元素的布局和渲染方式。

它将每个元素看作是一个盒子,包括内容、内边距、边框和外边距。

理解盒子模型对于控制元素的大小、位置和样式具有重要意义。

问题五:请解释一下浮动(float)在布局中的作用。

解答:浮动是 CSS 布局中的一种属性,可以让元素脱离正常的布局流,并在容器中浮动。

浮动常用于实现网页中的多栏布局和图像的环绕效果。

问题六:请介绍一下 CSS 的选择器(Selector)。

解答:CSS 选择器用于选择需要样式化的 HTML 元素。

常见的选择器有标签选择器、类选择器、ID 选择器、后代选择器、伪类选择器等。

选择器的灵活运用可以提高样式的精确度和可维护性。

问题七:请谈谈你对 JavaScript 闭包(Closure)的理解。

javascript基本面试题

javascript基本面试题

一、单选题1、以下哪条语句会产生运行错误:(a )A.var obj = ();//语法错误B.var obj = [];//创建数组C.var obj = {};//创建对象D.var obj = //;原因:var obj = new Array ();是对的;JavaScript 中大括号表示创建对象。

var obj = { id:1, name:"jacky" };alert();上例表示创建一个具有属性 id (值为 1)、属性 name (值为 jacky )的对象。

属性名称可以用引号引起来成 "id"、"name",也可以不引。

当然除了属性,也可以创建方法。

试验代码/* window.onload=function(){ // var obj = ();var obj1 = [];//objectvar obj2 = {};//objectvar obj3 = //;//undefinealert(typeof(obj1));alert(typeof(obj2));alert(typeof(obj3));}*/function showName(){ alert(); }var obj = { id:1, name:"jacky", showName:showName };obj.showName();2、以下哪个单词不属于javascript 保留字:(b )A.withB.parentC.classD.void以下的保留字不可以用作变量,函数名,对象名等,其中有的保留字是为以后JAV ASCRIPT 扩展用的.abstract boolean break byte case catch char class const continue default do double elseextends false final finally float for function goto if implements import in instanceof int interface long native new null package private protected public return short static super switch synchronized this throw throws transient true try var void while with3、请选择结果为真的表达式:(c)A.null instanceof Object(if(!(null instanceof Object))是真的)B.null === undefinedC.null == undefinedD.NaN == NaN(1) null确实可以理解为原始类型,不能当Object理解!null,int,float.....等这些用关键字表示的类型,都不属于Object.至于可以把null作为参数,只是特殊规定而已.可以这么理解: 对象的引用代表的是一个内存的值,null是一个空引用,可以理解为内存的值为0;按这个意思对代码(2) function f1(){ }1. alert(f1 instanceof Function);//true2. alert(f1 instanceof Object);//true3. alert(Function instanceof Object);//true4. alert(Object instanceof Function);//trueFunction 是Object的实例,Object又是Function的实例Function是函数的构造函数,而Object也是函数,Function自身也是函数Object.prototype是一切原型链的顶点,instanceof会查找整个原型链alert(Function);alert(Function.prototype);alert(Function.__proto__);alert(Object);alert(Object.prototype);alert(Object.__proto__);alert((function(){}).prototype);alert((function(){}).__proto__);alert((function(){}).__proto__.prototype);alert((function(){}).prototype.__proto__);alert(Array.__proto__);alert((123).__proto__);alert((Number).__proto__);alert(("test").__proto__);alert((String).__proto__);alert((true).__proto__);alert((Boolean).__proto__);/* window.onload=function(){if(NaN == NaN){alert("ddd");}}*/二、不定项选择题4、请选择对javascript理解有误的:(abcd)A.JScript是javascript的简称B.javascript是网景公司开发的一种Java脚本语言,其目的是为了简化Java 的开发难度C.FireFox和IE存在大量兼容性问题的主要原因在于他们对javascript的支持不同上D.AJAX技术一定要使用javascript技术5、foo对象有att属性,那么获取att属性的值,以下哪些做法是可以的:(ACE)A.foo.attB.foo(“att”)C.foo[“att”]D.foo{“att”}E.foo[“a”+”t”+”t”]6、在不指定特殊属性的情况下,哪几种HTML标签可以手动输入文本:(a ce)A.<TEXTAREA></TEXTAREA>B.<INPUT type=”text”/>C.<INPUT type=”hidden”/>D.<DIV></DIV>7、以下哪些是javascript的全局函数:(abc)A.escapeB.parseFloatC.evalD.setTimeoutE.alert8、关于IFrame表述正确的有:(abcd)A.通过IFrame,网页可以嵌入其他网页内容,并可以动态更改B.在相同域名下,内嵌的IFrame可以获取外层网页的对象C.在相同域名下,外层网页脚本可以获取IFrame网页内的对象D.可以通过脚本调整IFrame的大小9、关于表格表述正确的有:(abcde)A.表格中可以包含TBODY元素B.表格中可以包含CAPTION元素C.表格中可以包含多个TBODY元素D.表格中可以包含COLGROUP元素E.表格中可以包含COL元素10、关于IE的window对象表述正确的有:(acd)A.window.opener属性本身就是指向window对象B.window.reload()方法可以用来刷新当前页面C.window.location=”a.html”和window.location.href=”a.html”的作用都是把当前页面替换成a.html页面D.定义了全局变量g;可以用window.g的方式来存取该变量三、问答题:1、谈谈javascript数组排序方法sort()的使用,重点介绍sort()参数的使用及其内部机制sort的实现的功能类似JAVA的比较器,数据排序从多维数组的第一维开始排序可以自己定义排序方法,很不多的函数2、简述DIV元素和SPAN元素的区别。

js面试题及答案2019

js面试题及答案2019

js面试题及答案2019JavaScript(简称JS)是一种常用的脚本语言,广泛应用于Web开发中。

在面试中,针对JS的问题也是常见的。

本文将为您提供一些2019年JS面试题及答案,希望能够帮助您更好地准备面试。

一、JS基础知识1. 什么是JavaScript?JavaScript是一种脚本语言,通常用于网页开发,用于提升用户体验。

2. JS的数据类型有哪些?JS有七种数据类型:Undefined、Null、Boolean、Number、String、Symbol(ES6新增)、Object。

3. 如何声明变量?可以使用var、let和const关键字声明变量。

其中,var在全局作用域中声明变量,let和const在块级作用域中声明变量。

4. null和undefined有什么区别?null表示一个空对象指针,而undefined表示一个未定义的值。

在使用时,null通常是程序员设定的,而undefined通常是表达式的默认值。

5. 什么是闭包?闭包是指一个函数可以访问其它函数的作用域链,即使这些函数已经执行完毕。

6. 如何判断一个变量的数据类型?可以使用typeof运算符,例如typeof x会返回变量x的数据类型。

7. 如何遍历一个对象的所有属性?可以使用for...in循环遍历对象的所有可枚举属性。

二、JS高级知识1. 什么是原型链?原型链是一种通过对象的原型(prototype)来实现属性和方法继承的机制。

2. 什么是事件冒泡和事件捕获?事件冒泡是指事件先在内部元素上触发,然后逐级向外冒泡触发。

事件捕获则是从最外层的元素开始触发,逐级向内捕获。

3. 如何阻止事件冒泡或事件捕获?可以使用事件对象的stopPropagation方法来阻止事件的冒泡或捕获传播。

4. 什么是回调函数?回调函数是指将一个函数作为参数传递给另一个函数,当满足某个条件时,另一个函数会调用传入的回调函数。

5. 如何实现异步编程?可以使用回调函数、Promise、async/await等方式来实现异步编程。

js工程师面试题及答案

js工程师面试题及答案

js工程师面试题及答案HTML+CSS1.对WEB标准以及W3C的理解与认识标签闭合、标签小写、不乱嵌套、提高搜索机器人搜索几率、使用外链css和js脚本、结构行为表现的分离、文件下载与页面速度更快、内容能被更多的用户所访问、内容能被更广泛的设备所访问、更少的代码和组件,容易维护、改版方便,不需要变动页面内容、提供打印版本而不需要复制内容、提高网站易用性;2.xhtml和html有什么区别HTML是一种基本的WEB网页设计语言,XHTML是一个基于XML的置标语言最主要的不同:XHTML 元素必须被正确地嵌套。

XHTML 元素必须被关闭。

标签名必须用小写字母。

XHTML 文档必须拥有根元素。

3.Doctype? 严格模式与混杂模式-如何触发这两种模式,区分它们有何意义? 用于声明文档使用那种规范(html/Xhtml)一般为严格过度基于框架的html文档加入XMl声明可触发,解析方式更改为IE5.5 拥有IE5.5的bug4.行内元素有哪些?块级元素有哪些?CSS的盒模型?块级元素:div p h1 h2 h3 h4 form ul行内元素: a b br i span input select Css盒模型:内容,border ,margin,padding5.CSS引入的方式有哪些? link和@import的区别是?内联内嵌外链导入区别:同时加载前者无兼容性,后者CSS2.1以下浏览器不支持 Link 支持使用javascript改变样式,后者不可。

6.CSS选择符有哪些?哪些属性可以继承?优先级算法如何计算?内联和important哪个优先级高?标签选择符类选择符 id选择符继承不如指定 Id>class>标签选择后者优先级高7.前端页面有哪三层构成,分别是什么?作用是什么?结构层Html 表示层 CSS 行为层 js8.css的基本语句构成是?选择器{属性1:值1;属性2:值2;……}9.你做的页面在哪些流览器测试过?这些浏览器的内核分别是什么?Ie(Ie内核) 火狐(Gecko)谷歌(webkit) opear(Presto)10.写出几种IE6 BUG的解决方法1.双边距BUG float引起的使用display2.3像素问题使用float引起的使用dislpay:inline -3px3.超链接hover 点击后失效使用正确的书写顺序 linkvisited hover active4.Ie z-index问题给父级添加position:relative5.Png 透明使用js代码改6.Min-height 最小高度!Important 解决’7.select 在ie6下遮盖使用iframe嵌套8.为什么没有办法定义1px左右的宽度容器(IE6默认的行高造成的,使用over:hidden,zoom:0.08 line-height:1px)11.标签上title与alt属性的区别是什么?Alt 当图片不显示是用文字代表。

js八股文面试题

js八股文面试题

js八股文面试题
1. 请解释什么是事件冒泡和事件捕获,以及它们之间的区别。

2. 请解释什么是闭包,并举例说明如何使用闭包。

3. 请解释什么是原型链,以及如何利用原型链实现对象继承。

4. 请解释什么是异步编程,以及有哪些方式可以实现异步编程。

5. 请解释什么是事件委托,并说明它的优势和用途。

6. 请解释什么是回调函数,并说明如何避免回调地狱的问题。

7. 请解释什么是浏览器的同源策略,以及如何处理跨域请求。

8. 请解释什么是前端优化,以及有哪些常见的前端优化技巧。

9. 请解释什么是事件循环,以及如何利用事件循环实现异步编程。

10. 请解释什么是模块化,以及如何使用模块化来组织和管理
代码。

这些问题涵盖了常见的JavaScript面试题,通过对它们的回答,可以展示个人对JavaScript语言的理解和运用能力。

js面试题及答案

js面试题及答案

js面试题及答案Javascript(简称为JS)是一种广泛应用于网页上的编程语言。

在近年来,随着互联网的发展,JS的重要性也急速增长。

许多公司都将JS 作为面试的重要考察点。

本文将带你回顾一些常见的JS面试题及其答案,希望能够帮助你在JS面试中取得好成绩。

1. 请介绍一下Javascript的基本数据类型。

Javascript有六种基本数据类型,包括:数值(Number)、字符串(String)、布尔值(Boolean)、空(Null)、未定义(Undefined)以及符号(Symbol)。

数值类型是用来表示数值的,可以是整数或者浮点数;字符串类型是用来表示文本的,使用引号包裹起来;布尔值类型用来表示真(True)或假(False);空(Null)表示一个空引用;未定义(Undefined)表示尚未被赋值;符号(Symbol)在ES6中引入,用于创建唯一的标识符。

2. 解释一下JS中的事件冒泡和事件捕获。

事件冒泡和事件捕获是JS中两种不同的事件传播方式。

事件冒泡是指当一个元素上的事件被触发时,不仅该元素会受到影响,而且其父元素也会逐层触发该事件,直到根元素。

事件冒泡的顺序是从最具体的元素逐级向上传播,例如:点击了一个子元素,点击事件会先触发子元素的事件处理程序,然后再逐级往上触发祖先元素的事件处理程序。

事件捕获是指当一个元素上的事件被触发时,根元素会最先接收到该事件,然后逐级传递到具体的元素。

事件捕获的顺序与事件冒泡相反,从根元素开始,逐级向下传播。

3. 请解释一下手动绑定事件和自动绑定事件的区别。

手动绑定事件是通过addEventListener()方法或者HTML属性来手动为元素绑定事件处理程序。

手动绑定事件的方式允许我们在需要的时候添加或移除事件处理程序,以及更灵活地控制事件的传播方式。

自动绑定事件是指在HTML中直接使用内联事件处理程序属性,例如onclick="doSomething()"。

js面试题及答案

js面试题及答案

js面试题及答案# js面试题及答案1. 问题一:解释JavaScript中的闭包是什么?答案:闭包是一个函数能够记住并访问其创建时作用域中的变量,即使该函数在那个作用域之外被执行。

简单来说,闭包就是函数能够“记住”它被创建时的环境。

2. 问题二:什么是原型继承?答案:原型继承是JavaScript中实现对象之间继承的一种机制。

每个JavaScript对象都有一个原型对象,当我们试图访问一个对象的属性或方法时,如果该对象本身没有这个属性或方法,JavaScript引擎会去它的原型对象上查找。

3. 问题三:请解释`var`, `let`, 和 `const` 在JavaScript中的区别。

答案:- `var` 是ES5中定义变量的关键字,它的作用域是函数作用域或全局作用域,可以被重新声明和赋值。

- `let` 是ES6中新增的关键字,用于声明块级作用域的变量,不能在同一作用域内重新声明。

- `const` 同样是ES6新增的关键字,用于声明一个只读的常量,一旦声明并初始化后,不能重新赋值。

4. 问题四:什么是事件循环(Event Loop)?答案:事件循环是JavaScript运行时的一种机制,它允许JavaScript引擎在单线程中处理异步操作。

事件循环涉及到调用栈(Call Stack)、事件队列(Event Queue)和事件处理器等概念,通过循环检查调用栈是否为空,然后取出事件队列中的事件进行处理。

5. 问题五:解释`this`在JavaScript中的工作原理。

答案: `this`的值取决于函数的调用方式。

在全局函数中,`this`指向全局对象(在浏览器中是`window`)。

在对象的方法中,`this`通常指向调用该方法的对象。

在构造函数中,`this`指向新创建的对象。

使用箭头函数时,`this`的值由外层作用域决定。

6. 问题六:什么是异步编程,JavaScript中有哪些实现异步编程的方式?答案:- 异步编程允许程序在等待某些操作完成时继续执行其他任务,而不是阻塞等待。

经典JS闭包面试题

经典JS闭包面试题

经典JS闭包面试题都答对了么?如果都答对了恭喜你在js闭包问题当中几乎没什么可以难住你了;如果没有答案,继续往下分析。

AD:由工作中演变而来的面试题这是一个我工作当中的遇到的一个问题,似乎很有趣,就当做了一道题去面试,发现几乎没人能全部答对并说出原因,遂拿出来聊一聊吧。

先看题目代码:function fun(n,o) {console.log(o)return {fun:function(m){return fun(m,n);}};}var a = fun(0); a.fun(1); a.fun(2); a.fun(3);//undefined,?,?,?var b = fun(0).fun(1).fun(2).fun(3);//undefined,?,?,?var c = fun(0).fun(1); c.fun(2); c.fun(3);//undefined,?,?,?//问:三行a,b,c的输出分别是什么?这是一道非常典型的JS闭包问题。

其中嵌套了三层fun函数,搞清楚每层fun的函数是那个fun函数尤为重要。

可以先在纸上或其他地方写下你认为的结果,然后展开看看正确答案是什么?答案都答对了么?如果都答对了恭喜你在js闭包问题当中几乎没什么可以难住你了;如果没有答案,继续往下分析。

JS中有几种函数首先,在此之前需要了解的是,在javascript中函数可以分为两种,具名函数(命名函数)和匿名函数。

区分这两种函数的方法非常简单,可以通过输出 来判断,有name的就是具名函数,没有name的就是匿名函数注意:在低版本IE上无法获取具名函数的name,会返回undefined,建议在火狐或是谷歌浏览器上测试或是采用兼容IE的获取函数name方法来获取函数名称:/*** 获取指定函数的函数名称(用于兼容IE)* @param {Function} fun 任意函数*/function getFunctionName(fun) {if ( !== undefined)return ;var ret = fun.toString();ret = ret.substr('function '.length);ret = ret.substr(0, ret.indexOf('('));return ret;}遂用上述函数测试是否为匿名函数:image可以得知变量fn1是具名函数,fn2是匿名函数创建函数的几种方式说完函数的类型,还需要了解javascript中创建函数都有几种创建方法。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

一、什么是闭包?官方”的解释是:闭包是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。

相信很少有人能直接看懂这句话,因为他描述的太学术。

其实这句话通俗的来说就是:JavaScript中所有的function都是一个闭包。

不过一般来说,嵌套的function所产生的闭包更为强大,也是大部分时候我们所谓的“闭包”。

看下面这段代码:1function a() { 2var i = 0; 3function b() { alert(++i); } 4return b;5 }6 var c = a();7 c();这段代码有两个特点:1、函数b嵌套在函数a内部;2、函数a返回函数b。

引用关系如图:这样在执行完var c=a()后,变量c实际上是指向了函数b,再执行c()后就会弹出一个窗口显示i的值(第一次为1)。

这段代码其实就创建了一个闭包,为什么?因为函数a外的变量c引用了函数a内的函数b,就是说:当函数a的内部函数b被函数a外的一个变量引用的时候,就创建了一个闭包。

让我们说的更透彻一些。

所谓“闭包”,就是在构造函数体内定义另外的函数作为目标对象的方法函数,而这个对象的方法函数反过来引用外层函数体中的临时变量。

这使得只要目标对象在生存期内始终能保持其方法,就能间接保持原构造函数体当时用到的临时变量值。

尽管最开始的构造函数调用已经结束,临时变量的名称也都消失了,但在目标对象的方法内却始终能引用到该变量的值,而且该值只能通这种方法来访问。

即使再次调用相同的构造函数,但只会生成新对象和方法,新的临时变量只是对应新的值,和上次那次调用的是各自独立的。

二、变量的作用域要理解闭包,首先必须理解Javascript特殊的变量作用域。

变量的作用域无非就是两种:全局变量和局部变量。

Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量。

下面通过一段代码来看一下1var n=999;2function f1(){3alert(n);4}5f1(); // 999另一方面,在函数外部自然无法读取函数内的局部变量。

1function f1(){2var n=999;3}4alert(n); // error这里有一个地方需要注意,函数内部声明变量的时候,一定要使用var命令。

如果不用的话,你实际上声明了一个全局变量!1function f1(){2n=999;3}4f1();5alert(n); // 999以上只是一个关于javascript变量作用域基础的例子。

三、如何从外部读取局部变量?(闭包)我们有时候需要得到函数内的局部变量。

但是,前面已经说过了,正常情况下,这是办不到的,只有通过变通方法才能实现。

当然这个变通的方法便是使用闭包,下面再通过一个例子来看一下1function f1(){2n=999;3function f2(){4alert(n);5}6return f2;7}8var result=f1();9result(); // 999这个便是闭包的一个简单的例子。

由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成“定义在一个函数内部的函数”。

所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。

和面向对象的语言相比,闭包便是使用对象中一个特定的公有函数去访问这个对象的私有变量。

四、闭包的用途闭包可以用在许多地方。

它的最大用处有两个,一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。

怎么来理解这句话呢?请看下面的代码。

1function f1(){ 2var n=999; 3nAdd=function(){n+=1} 4function f2(){ 5alert(n); 6} 7return f2; 8} 9var result=f1();10result(); // 99911nAdd();12result(); // 1000在这段代码中,result实际上就是闭包f2函数。

它一共运行了两次,第一次的值是999,第二次的值是1000。

这证明了,函数f1中的局部变量n一直保存在内存中,并没有在f1调用后被自动清除。

为什么会这样呢?原因就在于f1是f2的父函数,而f2被赋给了一个全局变量,这导致f2始终在内存中,而f2的存在依赖于f1,因此f1也始终在内存中,因为全局变量只有在代码执行完退出的时候才清楚,所以f1不会在调用结束后,被垃圾回收机制(garbage collection)回收,而会一直存在直到程序退出。

这段代码中另一个值得注意的地方,就是“nAdd=function(){n+=1}”这一行,首先在nAdd 前面没有使用var关键字,因此nAdd是一个全局变量,而不是局部变量。

其次,nAdd的值是一个匿名函数(anonymous function),而这个匿名函数本身也是一个闭包,所以nAdd 相当于是一个setter,可以在函数外部对函数内部的局部变量进行操作。

五、Javascript的垃圾回收机制还是以这个图来说:在Javascript中,如果一个对象不再被引用,那么这个对象就会被GC回收。

如果两个对象互相引用,而不再被第3者所引用,那么这两个互相引用的对象也会被回收。

因为函数a被b引用,b又被a外的c引用,这就是为什么函数a执行后不会被回收的原因。

六、使用闭包的注意点1、由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。

解决方法是,在退出函数之前,将不使用的局部变量全部删除。

2、闭包会在父函数外部,改变父函数内部变量的值。

所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。

七、思考题如果你能理解下面代码的运行结果,应该就算理解闭包的运行机制了。

1var name = "The Window"; 2var object = { 3name : "My Object", 4getNameFunc : function(){ 5return function(){ 6return ; 7}; 8} 9 }; 10alert(object.getNameFunc()()); //The Window上面例子中对象中getNameFunc方法使用了一个闭包,而这个返回的闭包中又包含了一个闭包返回,当执行object.getNameFunc()()时,会先解析到第一对圆括号执行getNameFunc函数,返回了一个闭包函数,然后再次读后面的圆括号,将这个闭包返回的函数执行,然后返回,这段代码里面相当于执行了两层闭包。

1function outerFun() 2 { 3var a=0; 4function innerFun() 5 { 6 a++; 7alert(a);8 }9return innerFun; //注意这里10}11var obj=outerFun();12obj(); //结果为113obj(); //结果为214var obj2=outerFun();15obj2(); //结果为116obj2(); //结果为2上面的例子,当内部函数在定义它的作用域的外部被引用时,就创建了该内部函数的闭包,因为是在被外部引用是创建了一个闭包,所以当被外部两次引用的时候便会同时也创建两个闭包,每个闭包各不干涉。

如果内部函数引用了位于外部函数的变量,当外部函数调用完毕后,这些变量在内存不会被释放,因为闭包需要它们。

八、闭包内的微观世界如果要更加深入的了解闭包以及函数a和嵌套函数b的关系,我们需要引入另外几个概念:函数的执行环境(excution context)、活动对象(call object)、作用域(scope)、作用域链(scope chain)。

以函数a从定义到执行的过程为例阐述这几个概念。

1.当定义函数a的时候,js解释器会将函数a的作用域链(scope chain)设置为定义a时a所在的“环境”,如果a是一个全局函数,则scope chain中只有window对象。

2.当执行函数a的时候,a会进入相应的执行环境(excution context)。

3.在创建执行环境的过程中,首先会为a添加一个scope属性,即a的作用域,其值就为第1步中的scope chain。

即a.scope=a的作用域链。

4.然后执行环境会创建一个活动对象(call object)。

活动对象也是一个拥有属性的对象,但它不具有原型而且不能通过JavaScript代码直接访问。

创建完活动对象后,把活动对象添加到a的作用域链的最顶端。

此时a的作用域链包含了两个对象:a的活动对象和window对象。

5.下一步是在活动对象上添加一个arguments属性,它保存着调用函数a时所传递的参数。

6.最后把所有函数a的形参和内部的函数b的引用也添加到a的活动对象上。

在这一步中,完成了函数b的的定义,因此如同第3步,函数b的作用域链被设置为b所被定义的环境,即a的作用域。

到此,整个函数a从定义到执行的步骤就完成了。

此时a返回函数b的引用给c,又函数b的作用域链包含了对函数a的活动对象的引用,也就是说b可以访问到a中定义的所有变量和函数。

函数b被c引用,函数b又依赖函数a,因此函数a在返回后不会被GC回收。

当函数b执行的时候亦会像以上步骤一样。

因此,执行时b的作用域链包含了3个对象:b的活动对象、a的活动对象和window对象,如下图所示:如图所示,当在函数b中访问一个变量的时候,搜索顺序是:1.先搜索自身的活动对象,如果存在则返回,如果不存在将继续搜索函数a的活动对象,依次查找,直到找到为止。

2.如果函数b存在prototype原型对象,则在查找完自身的活动对象后先查找自身的原型对象,再继续查找。

这就是Javascript中的变量查找机制。

3.如果整个作用域链上都无法找到,则返回undefined。

九、结语理解JavaScript的闭包是迈向高级JS程序员的必经之路,理解了其解释和运行机制才能写出更为安全和优雅的代码。

相关文档
最新文档