【前端面试题】—100多个常见JS面试题-有答案 一共有200多道题,这里的重中之重当属事件和DOM操作,这也是 JavaScript的核心部分。在 ECMAScript中,小到运算符,大到函数的闭包、作用域,以及原型链等都是应试者必须掌握的技术知识。 JavaScript是网页中的一种脚本语言,其前身叫做LiveScript,由Netscape(网景)公司开发。后来在Sun公司推出著名的Java语言之后,Netscape公司和Sun公司于1995年一起重新设计了LiveScript,并把它改名为JavaScript。 作为一门独立的网页脚本编程语言,JavaScript可以做很多事情,但最主流的应用是在Web上创建网页特效或验证信息。图1和图2所示为使用JavaScript脚本语言对用户输入的内容进行验证。如果用户在注册信息文本框中输入的信息不符合注册要求,或在“确认密码”与“密码”文本框中输入的信息不同,将弹出相应的提示信息。 1、JavaScript有哪些垃圾回收机制? 有以下垃圾回收机制。 标记清除( mark and sweep) 这是 JavaScript最常见的垃圾回收方式。当变量进入执行环境的时候,比如在函数中声明一个变量,垃圾回收器将其标记为“进入环境”。当变量离开环境的时候(函数执行结束),将其标记为“离开环境”。 垃圾回收器会在运行的时候给存储在内存中的所有变量加上标记,然后去掉环境中的变量,以及被环境中变量所引用的变量(闭包)的标记。在完成这些之后仍然存在的标记就是要删除的变量。 引用计数( reference counting) 在低版本的E中经常会发生内存泄漏,很多时候就是因为它采用引用计数的方式进行垃圾回收。引用计数的策略是跟踪记录每个值被使用的次数。 当声明了一个变量并将个引用类型赋值给该变量的时候,这个值的引用次数就加1.如果该变量的值变成了另外一个,则这个值的引用次数减1.当这个值的引用次数变为0的时候,说明没有变量在使用,这个值没法被访问。 因此,可以将它占用的空间回收,这样垃圾回收器会在运行的时候清理引用次数为0的值占用的空间在正中虽然 JavaScript对象通过标记清除的方式进行垃圾回收,但是BOM与DOM对象是用引用计数的方式回收垃圾的。 也就是说,只要涉及BOM和DOM,就会出现循环引用问题 2、列举几种类型的DOM节点 有以下几类DOM节点。 整个文档是一个文档( Document)节点。 每个HTML标签是一个素( Element)节点。 每一个HTML属性是一个属性( Attribute)节点。 包含在HTML素中的文本是文本(Text)节点。 3、谈谈 script标签中 defer和 async属性的区别。 区别如下。 (1) defer属性规定是否延迟执行脚本,直到页面加载为止, async属性规定脚本一旦可用,就异步执行。 (2) defer并行加载 JavaScript文件,会按照页面上 script标签的顺序执行, async并行加载 JavaScript文件,下载完成立即执行,不会按照页面上 script标签的顺序执行。 4、说说你对闭包的理解。 使用闭包主要是为了设计私有的方法和变量。闭包的优点是可以避免全局变量的污染;缺点是闭包会常驻内存,增加内存使用量,使用不当很容易造成内存泄漏。在JavaScript中,函数即闭包,只有函数才会产生作用域闭包有3个特性 (1)函数嵌套函数。 (2)在函数内部可以引用外部的参数和变量 (3)参数和变量不会以垃圾回收机制回收 5、解释一下 unshift0方法。 该方法在数组启动时起作用,与 push()不同。它将参数成员添加到数组的顶部下面给出一段示例代。 输出如下所示。 6、encodeR0和 decodeR0的作用是什么? encodeURI()用于将URL转换为十六进制编码。而 decodeURI()用于将编码的URL转换回正常URL。 7、为什么不建议在 JavaScript中使用 innerHTML? 通过 innerHTML修改内容,每次都会刷新,因此很慢。在 innerHTML中没有验证的机会,因此更容易在文档中插入错误代码,使网页不稳定。 8、如何在不支持 JavaScript的旧浏览器中隐藏 JavaScript代码? 在< script>标签之后的代码中添加“<!–”,不带引号。 在< /script>标签之前添加“//–>”,代码中没有引号。 旧浏览器现在将 JavaScript代码视为一个长的HTML注释,而支持 JavaScript的浏览器则将”<!-“和”//–>”作为一行注释。 9、在DOM操作中怎样创建、添加、移除、替换、插入和查找节点? 具体方法如下。 (1)通过以下代码创建新节点。 (2)通过以下代码添加、移除、替换、插入节点 10、如何实现浏览器内多个标签页之间的通信? 调用 localstorge、 cookie等数据存储通信方式 11、null和 undefined的区别是什么? null是一个表示“无”的对象,转为数值时为0;undefined是一个表示“无”的原始值,转为数值时为NaN。 当声明的变量还未初始化时,变量的默认值为 undefined 。 null用来表示尚未存在的对象,常用来表示函数企图返回一个不存在的对象。 undefined表示“缺少值”,即此处应该有一个值,但是还没有定义,典型用法是如下。 (1)如果变量声明了,但没有赋值,它就等于 undefined (2)当调用函数时,如果没有提供应该提供的参数,该参数就等于 undefined。 (3)如果对象没有赋值,该属性的值为 undefined。 (4)当函数没有返回值时,默认返回 undefined。 null表示“没有对象”,即此处不应该有值,典型用法是如下。 (1)作为函数的参数,表示该函数的参数不是对象。 (2)作为对象原型链的终点。 12、new操作符的作用是什么? 作用如下: (1)创建一个空对象。 (2)由this变量引用该对象 (3)该对象继承该函数的原型(更改原型链的指向) (4)把属性和方法加入到this引用的对象中。 (5)新创建的对象由this引用,最后隐式地返回this,过程如下: 13、JavaScript延迟加载的方式有哪些? 包括 defer和 async、动态创建DOM(创建 script,插入DOM中,加载完毕后回调、按需异步载入 JavaScript。 14、call()和apply()的区别和作用是什么? 作用都是在函数执行的时候,动态改变函数的运行环境(执行上下文)。 call和 apply的第一个参数都是改变运行环境的对象。 区别如下。 call从第二个参数开始,每一个参数会依次传递给调用函数;apply的第二个参数是数组,数组的每一个成员会依次传递给调用函数。 如 对应的 apply写法为: 15、哪些操作会造成内存泄漏? 内存泄漏指不再拥有或需要任何对象(数据)之后,它们仍然存在于内存中。 提示:垃圾回收器定期扫描对象,并计算引用了每个对象的其他对象的数量。如果一个对象的引用数量为0(没有其他对象引用过该对象),或对该对象的唯一引用是循环的,那么该对象占用的内存立即被回收。 如果 setTimeout的第一个参数使用字符串而非函数,会引发内存泄漏闭包、控制台日志、循环(在两个对象彼此引用且彼此保留时,就会产生一个循环)等会造内存泄漏。 16、列举E与 firefox的不同之处。 不同之处如下 (1)IE支持 currentStyle;Firefox使用 get ComputStyle。 (2)IE使用 inner Text;Firefox使用 textContent。 (3)在透明度滤镜方面,正使用 filter:alpha( opacity=num);Firefox使用-moz- opacity :num (4)在事件方面,IE使用 attachEvent:Firefox使用 add Event Listener (5)对于鼠标位置:IE使用 event. clientX;Firefox使用 event. pageX。 (6)IE使用 event. srcElement;Firefox使用 event. target (7)要消除list的原点,IE中仅须使 margin:0即可达到最终效果;Firefox中需要设置margin:0、 padding:0和 list-style:none (8)CSS圆角:IE7以下不支持圆角。 17、讲解一下 JavaScript对象的几种创建方式。 有以下创建方式: (1) Object构造函数式。 (2)对象字面量式。 (3)工厂模式。 (4)安全工厂模式。 (5)构造函数模式。 (6)原型模式。 (7)混合构造函数和原型模式。 (8)动态原型模式。 (9)寄生构造函数模式。 (10)稳妥构造函数模式。 18、如何实现异步编程? 具体方法如下: 方法1,通过回调函数。优点是简单、容易理解和部署;缺点是不利于代码的阅读和维护,各个部分之间高度耦合( Coupling),流程混乱,而且每个任务只能指定一个回调函数。 方法2,通过事件监听,可以绑定多个事件,每个事件可以指定多个回调函数,而且可以“去耦合”( Decoupling),有利于实现模块化;缺点是整个程序都要变成事件驱动型,运行流程会变得很不清晰。 方法3,采用发布/订阅方式。性质与“事件监听”类似,但是明显优于后者。 方法4,通过 Promise对象实现, Promise对象是 Commonjs工作组提出的一种规范,旨在为异步编程提供统一接口。它的思想是,每一个异步任务返回一个 Promise对象,该对象有一个then方法,允许指定回调函数。 19、请解释一下 JavaScript的同源策略。 同源策略是客户端脚本(尤其是 JavaScript)的重要安全度量标准。它最早出自Netscape Navigator2.0,目的是防止某个文档或脚本从多个不同源装载。 这里的同源策略指的是协议、域名、端口相同。同源策略是一种安全协议。指一段脚本只能读取来自同一来源的窗口和文档的属性。 20、为什么要有同源限制? 我们举例说明。比如一个黑客,他利用 Iframe把真正的银行登录页面嵌到他的页面上,当你使用真实的用户名、密码登录时,他的页面就可以通过 Javascript读取到你表单上 Input中的内容,这样黑客就会轻松得到你的用户名和密码。 21、在 JavaScript中,为什么说函数是第一类对象? 第一类函数即 JavaScript中的函数。这通常意味着这些函数可以作为参数传递给其他函数,作为其他函数的值返回,分配给变量,也可以存储在数据结构中。 22、什么是事件?E与 Firefox的事件机制有什么区别?如何阻止冒泡? 事件是在网页中的某个操作(有的操作对应多个事件)例如,当单击一个按钮时,就会产生一个事件,它可以被 JavaScript侦测到,在事件处理机制上,正E支持事件冒泡;Firefox同时支持两种事件模型,也就是捕获型事件和冒泡型事件。 阻止方法是 ev.stop Propagation.注意旧版E中的方法 ev. cancelBubble=true. 23、函数声明与函数表达式的区别? 在 JavaScript中,在向执行环境中加载数据时,解析器对函数声明和函数表达式并非是一视同仁的。解析器会首先读取函数声明,并使它在执行任何代码之前可用(可以访问)。至于函数表达式,则必须等到解析器执行到它所在的代码行,才会真正解析和执行它。 24、如何删除一个 cookie? 为了删除 cookie,要修改 expires,代码如下。 document. cookie =’user=icketang;expires =’+ new Date(0) 25、编写一个方法,求一个字符串的长度(单位是字节) 假设一个英文字符占用一字节,一个中文字符占用两字节: 26、对于素, attribute和 property的区别是什么? attribute是DOM素在文档中作为HTML标签拥有的属性;property就是DOM素在 JavaScript中作为对象拥有的属性。 对于HTML的标准属性来说, attribute和 property是同步的,会自动更新,但是对于自定义的属性来说,它们是不同步的。 27、解释延迟脚本在 JavaScript中的作用。 默认情况下,在页面加载期间,HTML代码的解析将暂停,直到脚本停止执行。 这意味着,如果服务器速度较慢或者脚本特别“沉重”,则会导致网页延迟。在使用Deferred时,脚本会延迟执行,直到HTML解析器运行。这缩短了网页的加载时间,并且它们的显示速度更快。 28、什么是闭包( closure)? 为了说明闭包,创建一个闭包。 执行 hello()后, hello()闭包内部的变量会存在,而闭包内部函数的内部变量不会存在,使得 JavaScript的垃圾回收机制不会收回hello()占用的资源,因为hell()中内部函数的执行需要依赖 hello()中的变量。 29、如何判断一个对象是否属于某个类? 使用 instanceof关键字,判断一个对象是否是类的实例化对象;使用 constructor属性,判断一个对象是否是类的构造函数。 30、JavaScript中如何使用事件处理程序? 事件是由用户与页面的交互(例如单击链接或填写表单)导致的操作。需要个事件处理程序来保证所有事件的正确执行。事件处理程序是对象的额外属性。此属性包括事件的名称和事件发生时采取的操作。 31、在 JavaScript中有一个函数,执行直接对象查找时,它始终不会查找原型,这个函数是什么? hasOwnProperty。 32、在 JavaScript中如何使用DOM? DOM代表文档对象模型,并且负责文档中各种对象的相互交互。DOM是开发网页所必需的,其中包括诸如段落、链接等对象。可以操作这些对象,如添加或删除等。为此,DOM还需要向网页添加额外的功能。 33、documen.wrte和 innerHTML的区别是什么? document.wite重绘整个页面;innerHTML可以重绘页面的一部分。 34、在 JavaScript中读取文件的方法是什么? 可以通过如下方式读取服务器中的文件内容。 可以通过如下方式读取本地计算机中的内容。 35、如何分配对象属性? 将属性分配给对象的方式与赋值给变量的方式相同。例如,表单对象的操作值以下列方式分配给” submit”:document.form. action=” submit'” 36、请说几条书写 JavaScript语句的基本规范。 基本规范如下: (1)不要在同一行声明多个变量。 (2)应使用==/!==来比较true/ false或者数值。 (3)使用对象字面量替代 new Array这种形式。 (4)不要使用全局函数。 (5) switch语句必须带有 default分支。 (6)函数不应该有时有返回值,有时没有返回值。 (7)for循环必须使用大括号括起来。 (8)if语句必须使用大括号括起来。 9)for-in循环中的变量应该使用war关键字明确限定的作用域,从而避免作用域污染。 37、eva的功能是什么? 它的功能是把对应的字符串解析成 Javascript代码并运行应该避免使用eval,它会造成程序不安全,非常影响性能(执行两次,一次解析成JavaScript语句,一次执行) 38、[“1,”2,”3″].map( parselnt)的执行结果是多少? [1,NaN,NaN],因为 parseInt需要两个参数(val, radix),其中 radix表示解析时用的基数(进制);map传递了3个参数(item, index,aray),对应的radix不合法导致解析失败。 39、谈谈你对this对象的理解。 this是 JavaScript的一个关键字,随着函数使用场合的不同,this的值会发生变化。但是有一个总原则,即this指的是调用函数的那个对象一般情况下,this是全局对象 Global,可以作为方法调用 40、Web- garden和web-farm有什么不同? web-garden和 web-farm都是网络托管系统。唯一的区别是 web-garden是在单个服务器中包含许多处理器的设置,而web-farm是使用多个服务器的较大设置。 41、说一下 document. write0的用法。 document. write()方法可以用在两个地方,页面载入过程中用实时脚本创建页面内容,以及用延时脚本创建本窗口或新窗口的内容document. write只能重绘整个页面, innerHTML可以重绘页面的一部分。 42、在 JavaScript中什么是类(伪)数组?如何将类(伪)数组转化为标准数组? 典型的类(伪)数组是函数的 argument参数,在调用 getElements By TagName和 document .childNodes方法时,它们返回的 NodeList对象都属于伪数组。可以使用Array .prototype. slice. call( fake Array)将数组转化为真正的Aray对象。 43、JavaScript中callee和 caller的作用是什么? caller返回一个关于函数的引用,该函数调用了当前函数;callee返回正在执行的函数,也就是指定的 function对象的正文。 44、讲一下手写数组快速排序的步骤。 ”快速排序”的思想很简单,整个排序过程只需要3步 (1)在数据集之中,选择一个素作为“基准”( pivot)。 (2)将所有小于“基准”的素,都移到“基准”的左边;将所有大于“基准”的素,都移到“基准”的右边。 (3)对“基准”左边和右边的两个子集,不断重复第(1)步和第(2)步,直到所有子集只剩下一个素为止。 45、如何统计字符串“ aaaabbbccccddfgh”中字母的个数或统计最多的字母数? 具体代码如下 46、写一个 function,清除字符串前后的空格(兼容所有浏览器)。 具体代码如下 47、列出不同浏览器中关于 JavaScript兼容性的两个常见问题。 (1)事件绑定兼容性问题。 IE8以下的浏览器不支持用 add Event Listener来绑定事件,使用 attachement可以解决这个问题 (2) stopPropagation兼容性问题 IE8以下的浏览器不支持用 e .stopPropagation()来阻止事件传播,使用 e .return Value =false可以解决这个问题。 48、闭包的优缺点是什么? 优点是不产生全局变量,实现属性私有化缺点是闭包中的数据会常驻内存,在不用的时候需要删除,否则会导致内存溢出(内存泄漏)。 49、用 JavaScript实现一个数组合并的方法(要求去重)。 代码如下。 执行concat(arrl,ar2,ar3)后,会返回[‘a’,null, undefined,’e’,[‘d],’c’,’b’]。 50、说明正则表达式给所有string对象添加去除首尾空白符的方法(trim方法)。 代码如下。 51、说明用 JavaScript实现一个提取电话号码的方法。 代码如下 测试“12345678901 021-12345678有课前端网0418-1234567 13112345678”,得到的结果应该是:[12345678901,021-12345678,0418-1234567,13112345678] 52、JavaScript中常用的逻辑运算符有哪些? ”and”(&&)运算符、“or”(‖)运算符和”not”(!)运算符,它们可以在 JavaScript中使用。 53、什么是事件代理(事件委托)? 事件代理( Event Delegation),又称为事件委托,是 JavaScript中绑定事件的常用技巧。顾名思义,“事件代理”就是把原本需要绑定的事件委托给父素,让父素负責事件监听。事件代理的原理是DOM素的事件冒泡。使用事件代理的好处是可以提高性能。 54、什么是 JavaScript? JavaScript是客户端和服务器端的脚本语言,可以插入HTML页面中,并且是目前较热门的Web开发语言,同时, JavaScript也是面向对象的编程语言。 55、列举Java和 JavaScript的不同之处。 Java是一门十分完整、成熟的编程语言。相比之下, JavaScript是一个可以被引入HTML页面的编程语言。这两种语言并不完全相互依赖,而是针对不同的意图而设计的。Java是一种面向对象编程(OOP)或结构化编程语言,类似的语言有C++;而 JavaScript是客户端脚本语言,它称为非结构化编程。 56、JavaScript和ASP脚本相比,哪个更快? JavaScript更快。JavaScript是一种客户端语言,因此它不需要Web服务器的协助就可以执行;ASP是服务器端语言,因此它总是比 JavaScript慢,值得注意的是, JavaScript现在也可用于服务器端语言( Node. js) 57、什么是负无穷大? Infinity代表了超出 JavaScript处理范围的数值。也就是说, JavaScript无法处理的数值都是 Infinity.实践证明, JavaScript所能处理的最大值( Number. MAX VALUE)是17976931348623157e+308,超过该数则为正无穷大;而最小值( Number. MIN VALUE) 是5e-324,小于该数则为0.所以负无穷大代表的是小于- Number MAX VALUE的数字, JavaScript中对应静态变量 Number NEGATIVE INFINITY 58、如何将 JavaScript代码分解成几行? M:在字符串语句中可以通过在第一行末尾使用反斜杠“\”来完成,例如, document. write(”This is \a program”)。 如果不是在字符串语句中更改为新行,那么 JavaScript会忽略行中的断点下面的代码是完美的,但并不建议这样做,因为阻碍了调试。 59、什么是未声明和未定义的变量? 未声明的变量是程序中不存在且未声明的变量。如果程序尝试读取未声明变量的值,则会在运行时遇到错误。未定义的变量是在程序中声明但尚未给出任何值的变量如果程序尝试读取未定义变量的值,则返回未定义的值60.:如何编写可动态添加新素的代码? 下面给出一段示例代码 61、什么是全局变量?这些变量如何声明?使用全局变量有哪些问题? 全局变量是整个代码中都可用的变量,也就是说,这些变量没有任何作用域var关键字用于声明局部变量,如果省略var关键字,则声明一个全局变量使用全局变量面临的问题是局部变量和全局变量名称的冲突。此外,很难调试和测试依赖于全局变量的代码。 62、解释 JavaScript中定时器的工作,并说明使用定时器的缺点。 定时器用于在设定的时间执行一段代码,或者在给定的时间间隔内重复该代码这通过使用函数 setTimeout、setInterval和 clearInterva来完成。 setTimeout( function, delay)函数用于启动在所属延迟之后调用特定功能的定时器。 setInterval( function,dlay)函数用于在提到的延迟中重复执行给定的功能,只有在取消时才停止。 clearInterval(id)函数指示定时器停止定时器在一个线程内运行,因此事件可能需要排队等待执行。 63、ViewState和 SessionState有什么区别? View State特定于会话中的页面; SessionState特定于可在Web应用程序中的所有页面上访问的用户特定数据。 64、什么是===运算符? ===称为严格等式运算符,当两个操作数具有相同的值和类型时,该运算符返回true。 65、说明如何使用 JavaScript提交表单。 要使用 JavaScript提交表单,可以使用以下代码。 document .form [0] .submit(); 66、素的样式/类如何改变? 可以通过以下方式改变素的样式。 可以通过以下方式改变素的类。 67、JavaScript中的循环结构都有哪些? for、 while、do.… while、 for in、 for of(ES6新增的) 68、如何在 JavaScript中将base字符串转换为 integer? parselnt()函数解析一个字符串参数,并返回一个指定基数的整数。 parselnt()将要转换的字符串作为其第一个参数,第二个参数是给定字符串的转换进制基数。 为了将4F(基数16)转换为整数,可以使用代码 parrent(”4F”,16)。 69、说明“==”和“===”的区别。 “==”仅检查值相等性,而“===”用于更严格的等式判定。如果两个变量的值或类型不同,则后者返回 false。 70、3+2+“7”的结果是什么? 由于3和2是整数,它们将直接相加,同时由于“7”是一个字符串,将会被直连接,因此结果将是57。 71、如何检测客户端机器上的操作系统? 为了检测客户端机器上的操作系统,应使用 navigator.app Version字符串(属性)。 72、JavaScript中的null表示什么? null用于表示无值或无对象。它意味着没有对象或空字符串,没有有效的布尔没有数值和数组对象 73、delete操作符的功能是什么? delete操作符用于删除对象中的某个属性,但不能删除变量、函数等。 74、JavaScript中有哪些类型的弹出框? ua; alert、 confirm和 prompt。 75、void(0)的作用是什么? void操作符使表达式的运算结果返回 undefined。 void(0)用于防止页面刷新,并在调用时传递参数“0”。 void(0)用于调用另一种方法而不刷新页面。 76、如何强制页面加载 JavaScript中的其他页面? 必须插入以下代码才能达到预期效果。 77、转义字符是用来做什么的? 当使用特殊字符(如单引号、双引号、撇号和&符号)时,将使用转义字符(反斜杠)。在字符前放置反斜杠,使其显示。 下面给出两个示例。 78、什么是 JavaScript cookie? cookie是存储在访问者计算机中的变量。每当一台计算机通过浏览器请求某个页面时,就会发送这个 cookie。可以使用 JavaScript来创建和 cookie的值。 79、解释 JavaScript中的pop()方法。 pop()方法与shift()方法类似,但不同之处在于shift()方法在数组的开头工作。此外,pop()方法将最后一个素从给定的数组中取出并返回,然后改变被调用的数组例如: 80、在 JavaScript中使用 innerHTML的缺点是什么? 缺点如下: (1)内容随处可见 (2)不能像“追加到 innerHTML”一样使用。 (3)即使使用+=,如” innerHTML= innerhTML+’htm'”,旧的内容仍然会被HTML替换。 (4)整个 innerHTML内容被重新解析并构建成素,因此它的速度要慢得多。 (5) innerHTML不提供验证,因此可能会在文档中插入具有破坏性的HTML并将其中断。 81、break和 continue语句的作用是什么? break语句从当前循环中退出; continue语句继续下一个循环语句。 82、在 JavaScript中, datatypes的两个基本组是什么? 两个基本组是原始类型和引用类型。 原始类型包括数字和布尔类型。引用类型包括更复杂的类型,如字符串和日期。 83、如何创建通用对象? 通用对象可以通过以下代码创建。 var o= new Object ()。 84、typeof是用来做什么的? typeof是一个运算符,用于返回变量类型的字符串描述。 85、哪些关键字用于处理异常? 86、JavaScript中不同类型的错误有几种? 有3种类型的错误。 Load time errors,该错误发生于加载网页时,例如出现语法错误等状况,称为加载时间错误,并且会动态生成错误。 Run time errors,由于在HTML语言中滥用命令而导致的错误。 Logical errors,这是由于在具有不同操作的函数上执行了错误逻辑而发生的错误。 87、在 JavaScript中,push方法的作用是什么? push方法用于将一个或多个素添加或附加到数组的末尾。使用这种方法,可通过传递多个参数来附加多个素。 88、在 JavaScript中, unshift方法的作用是什么? unshift方法就像在数组开头工作的push方法。该方法用于将一个或多个素添加到数组的开头。 89、如何为对象添加属性? 为对象添加属性有两种常用语法。 中括号语法,比如obj[” class”]=12。 点语法,比如 obj. class=12。 90、获得 CheckBox状态的方式是什么? alert( document getElement Byld(’checkbox1’) .checked; 如果 CheckBox选中,此警告将返回TRUE。 91、解释一下 window. onload和 onDocumentReady。 在载入页面的所有信息之前,不运行 window. onload。这导致在执行任何代码之前会出现延迟。 window.onDocumentReady在加载DOM之后加载代码。这允许代码更早地执行(早于 window. onload)。 92、如何理解 JavaScript中的闭包? 闭包就是能够读取其他函数内部变量的函数。 闭包的用途有两个,一是可以读取函数内部的变量,二是让这些变量的值始终保持在内存中。 93、如何把一个值附加到数组中? 可以在数组末尾处添加成员arr[ arr length]= value;或者调用push方法 arr.push(value)。 94、解释一下for-in循环。 for-in循环用于循环对象的属性。 for-in循环的语法如下。 for (var iable name in object){} 在每次循环中,来自对象的一个属性与变量名相关联,循环继续,直到对象的所有属性都被遍历。 95、描述一下 JavaScript中的匿名函数。 被声明为没有任何命名标识符的函数称为匿名函数。一般来说,匿名函数在声明后无法访问。 匿名函数声明示例如下。 96、和DOM事件流的区别是什么? 区别如下。 (1)执行顺序不一样 (2)参数不一样。 (3)事件名称是否加on不一样。 (4)this指向问题不一样。 97、阐述一下事件冒泡。 Java Script允许DOM素嵌套在一起。在这种情况下,如果单击子级的处理程序,父级的处理程序也将执行同样的工作。 98、JavaScript里函数参数 arguments是数组吗? 在函数代码中,使用特殊对象 arguments,开发者无须明确指出参数名,使用下标就可以访问相应的参数。 arguments虽然有数组的性质,但其并非真正的数组。它只是一个类数组对象,并没有数组的方法,不能像真正的数组那样调用 .join()、, .concat()、.pop()等方法。 99、什么是构造函数?它与普通函数有什么区别? 构造函数是一种特殊的方法,主要用来创建对象时初始化对象,经常与new运算符一起使用,创建对象的语句中构造函数的名称必须与类名完全相同。 与普通函数相比,区别如下 (1)构造函数只能由new关键字调用 (2)构造函数可以创建实例化对象 (3)构造函数是类的标志。 100、请解释一下 JavaScript和CSS阻塞。 JavaScript的阻塞特性是所有浏览器在下载 JavaScript代码的时候,会阻止其他一切活动,比如其他资源的下载,内容的呈现等,直到 JavaScript代码下载、解析、执行完毕后才开始继续并行下载其他资源并渲染内容。 为了提高用户体验,新一代浏览器都支持并行下载 JavaScript代码,但是 JavaScript代码的下载仍然会阻塞其他资源的下载(例如图片、CSS文件等)。 为了防止 JavaScript修改DOM树,浏览器需要重新构建DOM树,所以就会阻塞其他资源的下载和渲染。 嵌入的 JavaScript代码会阻塞所有内容的呈现,而外部 JavaScript代码只会阻塞其后内容的显示,两种方式都会阻塞其后资源的下载。也就是说,外部脚本不会阻塞外部脚本的加载,但会阻塞外部脚本的执行。 CSS本来是可以并行加载的,但是当CSS后面跟着嵌入的 JavaScript代码的时候,该CSS就会阻塞后面资源的下载。 而当把嵌入的 JavaScript代码放到CSS前面时,就不会出现阻塞的情况了(在IE6下CSS都会阻塞加载)。 根本原因是因为浏览器会维持HTML中CSS和 JavaScript代码的顺序,样式表必须在嵌入的 JavaScript代码执行前先加载、解析完。而嵌入的 JavaScript代码会阻塞后面的资源加载,所以就会出现CSS阻塞资源加载的情况。 101、嵌入的 JavaScript代码应该放在什么位置? 应放在以下位置。 (1)放在底部,虽然放在底部照样会阻塞所有内容的呈现,但不会阻塞资源下载。 (2)如果嵌入的 JavaScript代码放在head中,请把嵌入的 JavaScript代码放在CSS头部。 (3)使用 defer的地方(只支持lE)。 (4)不要在嵌入的 JavaScript代码中调用运行时间较长的函数,如果一定要调用,可以用 setTimeout来调用。 102、请说出 JavaScript无阻塞加载的具体方式。 将脚本放在底部。 <link>放在head中,以保证在 JavaScript代码加载前,能加载出正常显示的页面。 < script>标签放在</body>前。 在阻塞脚本中,因为每个< script标签下载时都会阻塞页面的解析,所以限制页面的< script>总数也可以改善性能。它适用于内嵌脚本和外链脚本。 在非阻塞脚本中,等页面完成加载后,再加载 Javascript代码。也就是说,在window.onload事件发出后开始加载代码。 其中, defer属性支持lE4和 Fierfox3.5及更高版本的浏览器。通过动态脚本素,文档对象模型(DOM)允许使用 JavaScript动态创建HTML的几乎全部文档内容,代码如下。 此技术的重点在于,无论在何处启动下载,即使在head里,文件的下载和运行都不会阻塞其他页面的处理过程。 103、请解释一下事件冒泡机制。 在一个对象上触发某类事件(比如onclick事件)时,如果此对象定义了此事件的处理程序,那么此事件就会调用这个处理程序;如果没有定义此事件处理程序或者事件返回true,那么这个事件会向这个对象的父级对象传播,从里到外,直至它被处理(父级对象所有同类事件都将被激活),或者它到达了对象层次的最顶层,即 document对象(有些浏览器中是 window)。 冒泡型事件触发顺序是指从最特定的事件目标(触发事件对象)到最不特定的事件目标对象( document对象)。 JavaScript冒泡机制是指如果某素定义了事件A,如 click事件,如果触发了事件之后,没有阻止冒泡事件,那么该事件将向父级素传播,触发父类的 click事件。 104、请说出阻止事件冒泡的方法 阻止事件冒泡的方法,包括兼容IE浏览器(e.cancle Bubble)和标准浏览器(e. stopProgation)。下面给出一段示例代码。 105、请指出split()与join()函数的区别。 split()将字符串切割成数组,是关于字符串的方法;join()将数组转换成字符串,是关于数组的方法。 对数组执行 join()函数,然后通过参数分隔符字符串将它们连接起来,从而返回一个字符串。对字符串执行 split()函数,然后在参数分隔符处将其断开,从而返回一个数组。 简单地说,split()把一个字符串(根据某个分隔符字符串)切割成若干个字符串并存放在一个数组里。而 join()把数组中的字符串连成一个长串,可以认为它是 split()的逆操作。 106、说说你对原型( prototype)的理解。 JavaScript是一种通过原型实现继承的语言,它与别的高级语言是有区别的,例如Java。C#是通过类型决定继承关系的, Javascript是动态的弱类型语言。总之,可以认为 JavaScript中所有数据都是对象。 在 JavaScript中,原型也是一个对象,用原型可以实现对象的属性继承, JavaScript的对象中都包含了一个” prototype”内部属性,这个属性所对应的就是该对象的原型。 作为对象的内部属性,” prototype”是不能直接访问的。 所以,为了方便查看对象的原型, Firefox和 Chrome内核的 JavaScript引擎中提供了” proto”这个非标准的访问器(ECMA新标准中引入了标准对象原型访问器” Object. getPrototype( object)”)。 原型的主要作用就是实现继承与扩展对象。 107、typeof与 instanceof的区别是什么? 在 JavaScript中,判断一个变量的类型可以用 typeof。 (1)如果是数字类型, typeof返回的值是 number。 比如 typeof(”1″)返回的值是 number。 (2)如果是字符串类型, typeof返回的值是 string。比如 typeof(”123″)返回的值是string。 (3)如果是布尔类型, typeof返回的值是 boolean。比如 typeout(true)返回的值是boolean。 (4)如果是对象、数组、null, typeof返回的值是 object。比如 typeof( window)、typeof(document)、 typeof(null)返回的值都是 object。 (5)如果是函数类型, typeof返回的值是 function。比如 typeof(eval)、 typeof(Date)返回的值都是 function (6)对于不存在的变量、函数或者 undefined,将返回 undefined。比如 typeof(abc)、typeof(undefined)都返回 undefined。 在 JavaScript中, instanceof用于判断某个对象是否被另一个类构造(也就是说,是否是该类的实例化对象)。 当使用 typeof运算符判断引用类型存储值时,会出现一个问题,无论引用的是什么类型的对象,它都返回” object”。ECMAScript引入了另一个Java运算符 instanceof来解决这个问题。 与 typeof运算符相似, instanceof运算符用于识别正在处理的对象的类型与 typeof方法不同的是, instanceof方法要求开发者明确地给出对象的特定类型。 108、什么是事件流? 事件流是指从页面中接收事件的顺序。也就是说,当一个事件产生时,这个事件的传播过程就是事件流。 109、什么是事件冒泡? IE中的事件流叫事件冒泡。事件冒泡是指事件开始时由最具体的素接收,然后逐级向上传播到较为不具体的节点(文档)。 对于HTML来说,当一个素产生一个事件时,它会把这个事件传递给它的父素,父素接收到之后,还要继续传递给它的上一级素,就这样一直传播到 document对象(一些浏览器会传播到 window对象)。 110、什么是事件捕获 事件捕获是指不太具体的素更早地接收到事件,而最具体的节点最后接收到事件。它们的用意是在事件到达目标之前就捕获它;也就是与冒泡的过程正好相反。 以HTML的 click事件为例, document对象(DOM0级规范要求从 document开始传播,但是现在的浏览器是从 window对象开始的)最先接收到 click事件,然后事件沿着DOM树依次向下传播,一直传播到事件的实际目标。 111、如何清除一个定时器? 清除定时器使用的方法是:window. clearInterval( )。清除循环定时器使用的方法x window. clearTimeout( )。 112、如何在body中添加一个DOM对象?innerHTML和 inner Text有什么区别? 在body中添加DOM的方法是使用body.appendChild(DOM素)。 innerHTML是指从对象的起始位置到终止位置的全部内容,包括HTML标签。 innerText是指从起始位置到终止位置的内容,但它不包括HTML标签。 113、列出几个 window对象和属性。 window对象如下。 window.event、 window.document、 window.history、 window.screen、 window. navigator、 window. external。 window对象的属性如下。 114、什么是回调函数? 回调函数就是一个通过函数指针调用的函数。如果把函数的指针(地址)作为参数传递给另一个函数,当这个指针用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的执行方直接调用的,而是在特定的事件或条件发生时由另一方调用的,用于对该事件或条件进行响应。 115、什么是自执行函数?它有哪些应用场景?有什么好处? 自执行函数是指声明的一个匿名函数,可以立即调用这个匿名函数作用是创建一个独立的作用域。一般用于框架、插件等场景。 妤处是防止变量弥散到全局,避免各种 JavaScript库冲突;隔离作用域,避免污染,或者截断作用域链,避免闭包造成引用变量无法释放;利用立即执行特性,返回需要的业务函数或对象,避免每次用条件判断来处理。 116、什么是事件委托?它有什么好处? 事件委托指利用冒泡的原理,把事件加到父级上,触发执行效果好处如下。减少事件数量,提高性能。预测未来素,新添加的素仍然可以触发该事件。避免内存外泄,在低版本正E中,防止删除素而没有移除事件造成的内存溢出。 117、节点类型是有哪些?如何判断当前节点类型? 节点有以下类型。素节点属性节点;文本节点注释节点;文档节点。 用 nodeObject.nodeType判断节点类型。其中, nodObject为DOM节点(节点对象) 该属性返回用数字表示节点的类型,例如,素节点返回1,属性节点返回2。 118、什么是强制(显式)类型转换?什么是隐式类型转换? 强制(显式)类型转换如下。 隐式类型转换如下。 在使用算术运算符时,运算符两边的数据类型可以是任意的,比如,一个字符串可以和数字相加。之所以不同的数据类型之间可以做运算,是因为 JavaScript引擎在运算之前会悄悄地对它们进行隐式类型转换。 例如 119、已知id为 icketang的 input输入框,如何这个输入框的输入值(不使用第三方框架)? 使用document getElement Byld(”icketang”).value 120、使用 typeof bar===” object”可以确定bar是不是对象的潜在陷阱,如何避免这个陷阱? 尽管 typeof bar===” object”可以是检查bar是不是对象的可靠方法,但是在 JavaScript中也认为nul是对象。 因此,下面的代码将在控制台中输出true(而不是 false)。 只要清楚了这一点,同时检查bar是否为nul,就可以很容易地避免问题console. log((bar !== null) &&(typeof bar ===object”));// false 要答全问题,还有其他两件事情值得注意。 首先,上述解决方案将返回 false,当bar是一个函数的时候,在大多数情况下,这是期望结果,但当你想对函数返回true的时候,可以这样修改上面的解决方案。 其次,当bar是一个数组(例如,当 var bar=口)的时候,上述解决方案将返回true。在大多数情况下,这是期望的结果,因为数组是真正的对象,但当你想对数组返回 false时,可以这样修改上面的解决方案。 或者在ES5规范中输入如下内容。 121、下面的代码将输出什么到控制合?为什么? 输出结果如下。 a和b都定义在函数的封闭范围内,并且都始于var关键字,因此大多数 JavaScript开发人员期望 typeof a和 typeof b在上面的例子中都是 undefined。 然而,事实并非如此。问题在于大多数开发人员将语句vara=b=3错误地理解为是以下声明的简写 但事实上,var a=b=3实际是以下声明的简写 因此(如果你不使用严格模式),该代码段的输出如下。 但是,b如何定义在封闭函数的范围之外呢? 既然语句vara=b=3是语句b=3和vara=b的简写,b最终就成为一个全局变量 (因为它没有前缀var关键字),于是需要定义在封闭函数之外。 需要注意的是,在严格模式下(使用 use strict),语句var a=b=3将生成 Reference error;b is not defined的运行时错误,从而避免任何 headfakes或bug 122、下面的代码将输出什么内容到控制台?为什么? 上面的代码将输出以下内容到控制台。 在外部函数中,this和self都指向 myObject,因此两者都可以正确地引用和访问foo。 在内部函数中,this不再指向 myObject。结果是,this.foo没有在内部函数中定义,相反,指向到本地的变量seIf保持在范围内,并且可以访问(在 ECMAScript5之前,在内部函数中this将指向全局的 window对象;反之,内部函数中的this是未定义的) 123、封装 JavaScript源文件的全部内容到一个函数块有什么意义? 这是一个越来越普遍的做法,已被许多流行的 JavaScript库( jQuery、 Node. js等)采用。这种技术创建了一个围绕文件全部内容的闭包。最重要的是,创建了一个私有的命名空间,有助于避免不同 JavaScript模块和库之间的命名冲突。 这种技术的另一个特点是,允许把一个易于引用的(更短的)别名用于全局变 量。例如, jQuery插件中, jQuery允许你使用 jQuery. no Conflict(),来禁止$引用到jQuery命名空间。在完成这项工作之后,利用这种闭包技术,代码仍然可以使用$,如下所示。 (function(s){/* jQuery plugin code referencing s */} )(jQuery); 124、为了在 script里访问在 script下面的HTML中的素,可以用什么技术实现? Javascript不能访问当前 script素后面定义的HTML素,但在 window里有个 onload函数,把代码写在 window. onload= function函数体里就可以访问了。 125、以下两个函数会返回相同的结果吗?为什么相同或为什么不相同? 这两个函数返回的内容并不相同。通过以下语句查看返回值。 输出结果如下。 这不仅令人惊讶,而且让人困惑,因为foo2()返回 undefined,却没有任何错误抛出。 原因与这样一个事实有关,即分号在 JavaScript中是一个可选项(尽管省略它们通常是非常糟糕的形式)。结果是,当碰到foo2()中包含 return语句的代码行时(代码行上没有其他任何代码),分号会立即自动插入返回语句之后,也不会拋出错误,因为代码的其余部分是完全有效的,即使它没有得到调用或做任何事情。 这也说明了在 JavaScript中大括号的位置应该放在语句后面的编程风格更符合 JavaScript的语法要求。 126、NaN是什么?它的类型是什么?如何可靠地判断一个值是否等于NaN? NaN属性代表一个“不是数字”的值。这个特殊的值是因为运算不能执行而导致的,不能执行的原因可能是其中的运算对象之一非数字(例如,”abc”/4),也可能是是运算的结果非数字(例如,除数为零)。 虽然这看上去很简单,但NaN有一些令人惊讶的特点,如果你不知道它们,可能会导致令人头痛的Bug。 首先,虽然NaN意味着“不是数字”,但是它的类型是 Number。 此外,NaN和任何内容比较一甚至是它自己本身一结果都是 false 。 可以用一种半可靠的方法来判断了一个数字是否等于NaN,使用内置函数 isNaNO但即使使用 isTaNA也并非是一个完美的解决方案。 一个更好的解决办法是使用 value!= value,如果值等于NaN,只会产生true.另外, ECMAScript6中拓展了两个处理NaN的方法。一个是 Number isnaN()函数,比全局 isNaN(函数更可靠,比较的时候不会做数据类型的转换。另一个是 Object is,它可以判断两个NaN是否相等。 127、说明下列代码将输出什么,并解释原因。 它会输出以下内容。 原因如下。 十进制数0.1对应二进制数0.00011001100110011…(循环0011)。 十进制数0.2对应二进制数0.0011001100110011…(循环001) 两者相加得到达以下结果 0.00011001100110011001100110011001100110011001100110011001… +0.00110011001l00110011001100110011001100110011001100110011 =0.01001100110011001100110011001100110011001100110011001100… 转换成十进制之后得到0.300000000000004。 128、写出函数 islnteger(x)的实现方法,用于确定x是否是整数。 ECMAScript6引入了一个新的方法,即 Number. isInteger(),它可以用来判断一个数字是否是整数。在 ECMAScript6之前, isInteger的实现会更复杂。在 ECMAScript规格说明中,整数只是在概念上存在,即,数字值总是存储为浮点数值。 考虑到这一点,有如下几种实现方案 下面的解决方法虽然不如上面那个方法优雅,但也是可行的。 请注意, Math. ceil()和 Math. floor()在上面的实现中等同于 Math. round()。 或者使用以下实现方案。 一个比较普遍的错误解决方案如下。 虽然这个以 parselnt函数为基础的方法在x取许多值时能良好地工作,但是一旦x取值相当大,它就会无法正常工作。问题在于 parselnt()在解析数字之前强制把第一个参数转换为字符串。 因此,一旦数目变得足够大,它的字符串就会表达为指数形式(例如le+21)。 因此, parselnt()函数就会解析le+21,但当解析到‘e’字符的时候,就会停止解析,因此只会返回1。 129、下列代码行1~4如何排序,才能使之能够在执行代码时输出到控制台?为什么? 序号如下 让我们先来解释比较显而易见的那部分。 1和4之所以放在前面,是因为它们只是简单调用 console.log(O,而没有任何延迟输出。 2之所以放在3的后面,是因为2是延迟了1000ms(即,ls)之后输出的,而3是延迟了0ms之后输出的。 浏览器有一个事件循环,它会检查事件队列和处理未完成的事件。例如,如果时间发生在后台(例如,脚本的 onload事件),浏览器正忙(例如,处理一个 onclick),那么事件会添加到队列中。当 onclick处理程序完成后,检查队列,然后处理该事件(例如,执行 onload脚本)。 同样,如果浏览器正忙。setTimeout0也会把其引用的函数的执行放到事件队列中当 setTimeout的第二个参数为0的时候,它代表“尽快”执行指定的函数。具体是指,函数的执行会从事件队列的下一个计时器开始。但是请注意,这不是立即执行:函数不会执行,除非下一个计时器开始计时,这就是为什么在上述例子中调用 console. log(4) 发生在调用 console. log(3)之前(因为调用 console. log(3)是通过 setTimeout完成的,因此会稍微延迟)。 130、写一个简单的函数(少于80个字符),要求返回一个布尔值,指明字符串是否为回文结构。 下面这个函数在str是回文结构的时候返回true;否则,返回 false 例如: 131、写一个sum方法,在使用任意语法调用时,都可以正常工作。 (至少)有两种方法可以做到。 方法1,代码如下。 在 JavaScript中,函数可以提供到 arguments对象的访问, arguments对象提供传递到函数的实际参数的访问。这时我们能够使用 length属性来确定在运行时传递给函数的参数数量。 如果传递两个参数,那么只须加在一起并返回。 否则,假设它以sum(2)(3)这样的形式调用,所以返回一个匿名函数,这个匿名函数合并了传递到sumO的参数和传递给匿名函数的参数。 方法2,代码如下。 当调用一个函数的时候, JavaScript不要求参数的数目匹配函数定义中的参数数量如果传递的参数数量大于函数定义中的参数数量,那么多余参数将简单地被忽略。 另一方面,如果传递的参数数量小于函数定义中的参数数量,那么在函数中引用缺少的参数时将会给一个 undefined值。 所以,在上面的例子中,简单地检查第2个参数是否未定义,就可以确定函数的调用方式。 132、请看下面的代码片段并回答以下问题。 (1)当用户单击“ Button4”的时候会输出什么到控制台,为什么? (2)提供一个或多个可当前i的值的实现方案。 (1)无论用户单击什么按钮,数字5将总会输出到控制台。这是因为,当调用onclick方法(对于任何按钮)的时候,for循环已经结柬,变量i已经获得了5的值。 (2)要让代码工作的关键是,通过传递到一个新创建的函数对象,在每次传递通过for循环时,捕捉到i值。下面是3种可能实现的方法。 可以通过闭包实现对循环变量i的存储 或者,可以封装全部调用到新匿名函数中的btn.addEventListener。 也可以调用数组对象的本地 for Each方法来替代for循环。 133、下面的代码将输出什么到控制台?为什么? 输出结果是如下 在上述代码执行之后,arr1和arr2相同,原因如下。 调用数组对象的 reverse()方法并不只是返回反顺序的阵列,它也反转了数组本身的顺序(即,在这种情况下,指的是arr1)。 reverse()方法返回一个对数组本身的引用(在这种情况下,即arr1)。其结果为,arr2仅仅是一个对arr1的引用(而不是副本)。因此,当对arr2做了任何事情(即当调用arr2 .push(arr3))时,arrl也会受到影响,因为arr1和arr2引用的是同一个对象。 134、下面的代码将输出什么到控制台?为什么? 上面的代码将输出以下内容到控制台。 JavaScript( ECMAScript)是一种弱类型语言,它可对值进行自动类型转换,以适应正在执行的操作。 例1:1+”2”+”2”输出”122″。下面分析原因。1+”2”是执行的第一个操作,由于其中一个运算对象(”2″)是字符串, JavaScript会假设它需要执行字符串连接,因此会将1的类型转换为”1″,1+”2″结果就是”12″。然后,”12″+”2″就是”122″。 例2:1++”2″+”2”输出”32″。下面分析原因。根据运算的顺序,要执行的第一个运算是+”2”(第一个”2″前面的“+”被视为一运算符),因此, JavaScript将”2″的类型转换为数字。其结果是,接下来的运算就是1+2,这当然是3.然后我们需要在个数字和一个字符串之间进行运算(即,3和”2″)。同样, JavaScript会将数值类型转换为字符串,并执行字符串的连接,产生”32”。 例3:1+-“1”+”2”输出”02″。下面分析原因。这里的解释和前一个例子相同,除了此处的一运算符是“-”,当应用“-”时”1″变为了-1.然后将其与1相加,结果为0,再将其转换为字符串,连接最后的”2”,得到”02″。 例4:十”1″+”1”+”2”输出”12″。下面分析原因。虽然第一个运算对象”1″因为前缀的一”艹”运算符类型转换为数值,但是当连接到笫二个运算对象”I”的时候,立即转换回字符串。最后与”2″连接,产生了字符串”112”。 例5:”A””B”+”2”输出”NaN2″。说明:由于运算符“-”对”A”和”B”处理的时候,都不能转换成数值,因此”A”-“B”的结果是NaN,然后再和字符串”2″连接,得到”NaN2”。 例6:”A”-“B”+2输出NaN。说明:参见前一个例子,”A”-“B”结果为NaN,但是,应用任何运算符到NaN与其他任何的数字运算对象上,结果仍然是NaN。 135、下面的递归代码在数组列表偏大的情况下会导致堆栈溢出,在保留递归模式的基础上,怎么解决这个问题? 堆栈溢出之所以会被消除,是因为事件循环操纵了递归,而不是调用堆栈。当nextlistItem运行时,如果item不为空, timeout函数( nextlistltem)就会被推到事件队列,该函数退出,因此就清空调用堆栈。当事件队列运行其 timeout事件且进行到下个iem时,把定时器设置为再次调用 nextlistltem。因此,该方法从头到尾都没有直接的递归调用,所以无论迭代次数的多少,调用堆栈一直保持清空的状态。 136、JavaScript中的“闭包”是什么?请举一个例子。 闭包是一个可以访问外部(封闭)函数作用域链中变量的内部函数。闭包可以访问3种范围中的变量,这3个范围具体如下。自己范围内的变量。封闭函数范围内的变量。全局变量。 下面是一个简单的例子。 在上面的例子中,来自于 innerFunc、outerFunc和全局命名空间的变量都在 innerFunc的范围内。因此,上面的代码将输出如下结果 。 137、下面的代码将输出什么?闭包在这里能起什么作用? 上面的代码不会按预期显示值0、1、2、3和4,而是会显示5、5、5、5和5。 原因是,在循环中执行的每个函数将先整个循环完成之后执行,因此,将会引用存储在i中的最后一个值,那就是5。 闭包可以为每次迭代创建一个唯一的作用域,存储作用域内的循环变量。如下代码会按预期输出0、1、2、3和4到控制台。 138、以下代码行将输出什么到控制台? 该代码将输出以下结果。 详细分析如下。 在JavaScript中,‖ 和 && 都是逻辑运算符,从左至右进行运算。“或”(‖)运算符。在形如X || Y的表达式中,首先,计算X并将其表示为一个布尔值。如果这个布尔值是true,那么返回true(1),不再计算Y,因为“或”的条件已经满足。如果这个布尔值为false,那么,我们仍然无法知道X || Y是真还是假,直到计算Y,并且也把它表示为一个布尔值。 因此,0 ‖1的计算结果为true(1),同理计算1 ‖ 2。“与”(&&)运算符。在形如X&&Y的表达式中,首先,计算X并将其表示为一个布尔值。如果这个布尔值为false,那么返回false(0),不再计算Y,因为“与”的条件已经失败。如果这个布尔值为true,但是,我们仍然不知道X&&Y是真还是假,直到计算Y,并且也把它表示为一个布尔值。 不过,关于&&运算符最有趣的地方在于,当一个表达式的计算结果为“true”的时候,就返回表达式本身。这就解释了为什么1&&2返回2(而不是返回true或1)。 139、下面的代码将输出什么?请解释。 代码将输出以下结果: 在JavaScript中,有两种等于运算符。3个等于运算符===的作用类似于传统的等于运算符:如果两侧的表达式有相同的类型和相同的值,那么计算结果为true。而双等于运算符会只强制比较它们的值。因此,总体上而言,使用===而不是==的做法更好。!==与!=亦是同理。 140、以下代码将输出什么?解释你的答案。 这段代码将输出456(而不是123)。 原因是,当设置对象属性时,JavaScript会隐式地将[ ]内的变量转换成字符串。在这种情况下,由于b和c都是对象,因此,它们都将被转换为”[object Object]”。结果就是, a[b]和a[c]均相当于a[“[object Object]”],并可以互换使用。因此,设置或引用a[c]和设置或引用a[b]完全相同。 给大家分享我收集整理的各种学习资料,前端小白交流、学习交流,也可以直接问我,我会组织大家一起做项目练习,帮助大家匹配一位学习伙伴互相监督学习-下面是学习资料参考。小焱:前端学习交流、自学、学习资料等推荐
2024最新激活全家桶教程,稳定运行到2099年,请移步至置顶文章:https://sigusoft.com/99576.html
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。 文章由激活谷谷主-小谷整理,转载请注明出处:https://sigusoft.com/44399.html