25个你需要知道的JavaScript面试问题
1.使用typeof bar==='object '来判断bar是否是具有潜在缺点的对象。如何避免这种弊端?
使用typeof的缺点很明显(这个缺点与使用instanceof相同):
let obj={ };让arr=[];console . log(object==' object ')的类型;//true console . log(arr==' object ')的类型;//true console . log(type of null==' object ');//true从上面的输出结果可以看出,typeof bar===' Object '并不能准确判断bar是对象。您可以通过使用object . prototype . tostring . call(bar)==='[object object]'来避免这个缺点:
let obj={ };让arr=[];console . log(object . prototype . tostring . call(obj));//[对象对象]console . log(Object . prototype . tostring . call(arr));//[对象数组]控制台. log(object . prototype . tostring . call(null));//[对象Null]另外,为了珍惜生命,请远离==:
和[]===false返回false。
2.下面的代码将在控制台中输出什么?为什么呢?
(函数(){ var a=b=3;})();console.log('已定义的?(a的类型!==' undefined ');console.log('b已定义?(b的类型!==' undefined ');这与变量的范围有关,输出更改如下:
console . log(b);//3console,log(type of a);//undefined反汇编自执行函数中的变量赋值:
b=3;var a=b;
因此,b成为全局变量,而a是自执行函数的局部变量。
3.下面的代码将在控制台中输出什么?为什么呢?
var myObject={ foo: 'bar ',func : function(){ var self=this;console . log(' outer func : this . foo=' this . foo ');console . log(' outer func : self . foo=' self . foo ');(function(){ console . log(' inner func : this . foo=' this . foo ');console . log(' inner func : self . foo=' self . foo ');}());}};myobject . func();第一和第二输出不难判断。在ES6之前,JavaScript只有函数作用域,所以func中的IIFE有自己独立的作用域,可以在外部作用域访问self,所以第三个输出会报错,因为这在可访问的作用域是未定义的,第四个输出是bar。如果知道闭包,就很容易解决:
(function(test){ console . log(' inner func : this . foo=' test . foo ');//' bar ' console . log(' inner func : self . foo=' self . foo ');}(自我));如果您不熟悉闭包,可以参考本文:从范围链谈闭包。
4.在功能块中包含JavaScript代码有什么意义?你为什么要这么做?
换句话说,为什么要使用立即调用的函数表达式?
IIFE有两个经典的使用场景,一个类似于定期循环输出数据项,另一个类似于JQuery/Node插件和模块开发。
for(var I=0;i5;I){ setTimeout(function(){ console . log(I));}, 1000);}上面的输出并不是你想象的0、1、2、3、4,而是所有的输出都是5,那么IIFE就可以有用了:
for(var I=0;i5;i ) {(函数(i) { setTimeout(函数(){ console . log(I));}, 1000);})(i)}而在JQuery/Node的插件和模块开发中,也是避免变量污染的一大IIFE:
(函数($) {//代码})(jQuery);5.“使用严格”开发JavaScript有什么好处?
消除Javascript语法中一些不合理、不严谨的地方,减少一些怪异的行为;消除代码操作的一些不安全部分,保证代码操作的安全性;提高编译器效率和速度;为未来新版本的Javascript铺平道路。6.以下两个函数的返回值是否相同?为什么呢?
function foo 1(){ return { bar : ' hello ' };} function foo 2(){ return { bar : ' hello ' };}在编程语言中,分号(;),这样可以增加代码的可读性和整洁性。在JS中,如果每个语句占据一个独立的行,分号(;),JS解析器会根据是否可以正常编译来决定是否自动填充分号:
var测试=1 2console.log(测试);//3在上述情况下,为了正确解析代码,不会自动填充分号,但是对于return、break、continue等语句,如果后面有新的一行,解析器会自动填充分号(;),那么上面的第二个函数就变成了这样:
function foo 2(){ return;{ bar : ' hello ' };}所以第二个函数是返回undefined。
7.神马是什么?它是什么类型?如何测试一个值是否等于NaN?
NaN是Not a Number的缩写,这是JavaScript中的一个特殊值,其类型是Number。您可以通过isNaN(param)判断一个值是否为NaN:
console . log(ISnan(NAn));//true console . log(ISnan(23));//false console . log(ISnan(' ds '));//true console . log(ISnan(' 32131 sdad ');//true console . log(NAn===NAn);//false console . log(NAn===undefined);//false console . log(undefined===undefined);//falseconsole.log(类型为NAn);//number console . log(object . prototype . tostring . call(NAn));//[对象编号]在es6中,isNaN()成为编号的静态方法:Number.isNaN()。
8.解释以下代码的输出。
console . log(0.1 0.2);//0.300000000000000004 con sole . log(0.1 0.2==0.3);//false JavaScript中的数字类型为浮点类型,JavaScript中的浮点数采用IEEE-754格式,为二进制记数法,可以准确表示分数,如1/2、1/8、1/1024,每个浮点数占用64位。但是二进制浮点表示法不能准确表示0.1这样的简单数字,会出现舍入误差。
因为二进制,JavaScript无法表达1/10、1/2等分数。在二进制系统中,1/10(0.1)表示为0.0011001100110011.注意0011是无限重复的,这是舍入误差造成的,所以对于0.1 0.2这样的运算,先将操作数转换成二进制,然后计算:
0.1=0.0001 1001 1001 .(无限循环)0.2=0.0011 0011 0011 0011.(无限循环)双精度浮点数的小数部分最多可支持52位。因此,将它们相加后,我们得到一个0.0100110011001100110011001100110011001100…的字符串,由于浮点数小数位数的限制,二进制数字被截断。这时,当我们把它换算成十进制时,就变成了0.3000000000000000000000000000000000000000000000000000000000000000000
有两种常见的方法可以保证浮点数计算的准确性。
首先,提高功率,然后降低功率:
函数add(num1,num2){让r1,r2,m;r1=('' num1)。拆分('.')[1].长度;r2=('' num2)。拆分('.')[1].长度;m=Math.pow(10,Math.max(r1,R2));返回(num 1 * m num 2 * m)/m;}console.log(add(0.1,0.2));//0.3console.log(add(0.15,0.2256));//0.3756其次,使用内置的toPrecision()和toFixed()方法。注意方法的返回值字符串。
函数add(x,y){ return x . Toprecision()y . Toprecision()} console . log(add(0 . 1,0 . 2));//'0.10.2'9.实现函数isInteger(x)判断x是否为整数。
可以将x转换成小数,判断和本身是否相等:
函数isInteger(x) { return parseInt(x,10)===x;}ES6扩展了数值,提供了一个静态的方法isInteger()来判断参数是否为整数:
number . Isinteger(25)//TrueNumber . Isinteger(25.0)//TrueNumber . Isinteger(25.1)//FastNumber . Isinteger(' 15 ')//FastNumber . Isinteger(True)//True JavaScript可以准确表示的整数范围在-2 53到2 53之间(不包括两个端点)。超出这个范围,这个值就不能准确表示。ES6引入了两个常数,数字。MAX_SAFE_INTEGER和Number。MIN_SAFE_INTEGER,来表示这个范围的上下限,并提供Number.isSafeInteger()来判断一个整数是否为安全整数。
10.在下面的代码中,数字1-4将以什么顺序输出?为什么是这个输出?
(function(){ console . log(1);setTimeout(function(){ console . log(2)},1000);setTimeout(function(){ console . log(3)),0);console . log(4);})();这就不多解释了,主要是JavaScript的计时机制和时间周期。别忘了,JavaScript是单线程的。详细说明请参考setTimeout的JavaScript运行机制。
11.写一个少于80个字符的函数来判断一个字符串是否是回文。
函数ispalidome(str){ str=str . replace(/\ W/g ' ')。toLowerCase();返回(str==str.split(')。反转()。join(“”);}我在codewars上遇到过这个问题,包含了一些不错的解决方案,可以戳到这里:回文For Your Dome。
12.写一个sum方法,可以用下面的方法正常调用。
console.log(sum(2,3));//Outputs 5 console . log(sum(2)(3));//输出5对于这个问题,可以判断要实现的参数数量:
函数sum() { var fir=参数[0];if(arguments . length===2){ return arguments[0]arguments[1]} else { return function(sec){ return fir sec;}} }13.根据下面的代码片段回答以下问题。
for(var I=0;i5;I){ var BTN=document . create element(' button ');BTN . appendchild(document . createtextnode(' Button ' I));btn.addEventListener('click ',function(){ console . log(I);});document . body . appendchild(BTN);}1.点击按钮4,控制台会输出什么?
2.给一个方法,让它像预期的那样实现。
1.单击5个按钮中的任意一个,它将被输出。2.参考IIFE。14.下面的代码会输出什么?为什么呢?
var arr1='john '。拆分(“”);j o h nvar arr 2=arr 1 . reverse();n h o jvar arr3='jones '。拆分(“”);j o n e sarr 2 . push(arr 3);console.log('array 1:长度=' arr 1 . length ' last=' arr 1 . slice(-1));console.log('array 2:长度=' arr 2 . length ' last=' arr 2 . slice(-1));会输出什么?你运行的时候就会知道,可能会出乎意料。
Reverse()更改数组本身,并返回对原始数组的引用。
关于切片的用法,请参考:切片。
15.下面的代码会输出什么?为什么呢?
console . log(1 ' 2 ' ' 2 ');console . log(1 ' 2 ' ' 2 ');console . log(1-' 1 ' ' 2 ');console . log(' 1 ' ' 1 ' ' 2 ');console . log(' A '-' B ' 2 ');console . log(' A '-' B ' 2);输出什么,自己运行,需要注意三点:
当多个数字和数字字符串混合在一起时,它与操作数的位置有关。
console . log(2 1 ' 3 ');//' 33 ' console . log(' 3 ' 2 1);//'321 '当数字字符串前的数字中有一个符号(/-),它将被转换为数字。
console.log(类型为“3”);//stringconsole.log(类型为“3”);//number同样,可以在数字前添加“”,将数字转换为字符串。
console.log(类型为3);//number console . log(type of(' 3));//string如果运算结果不能转换为数字,将返回NaN。
console . log(' a ' * ' SD ');//nanconsole . log(' A '-' B ');//NaN这张图是算术变换的规律。
16、
如果列表很大,下面的递归代码将导致堆栈溢出。如果在不改变递归模式的情况下修复这段代码?
var list=readHugeList();var next listitem=function(){ var item=list . pop();if (item) { //处理列表项.nextListItem();}};最初的解决方案是添加一个计时器:
var list=readHugeList();var next listitem=function(){ var item=list . pop();if (item) { //处理列表项.setTimeout(nextListItem,0);}};解决方案的原理请参考问题10。
17.什么是结束?说明
你可以参考这篇文章:从范围链谈闭包。
18.下面的代码会输出什么?为什么呢?
for(var I=0;i5;I){ setTimeout(function(){ console . log(I));},I * 1000);}请向前转,参考问题4。解决方案已经在上面了。
19.解释以下代码的输出。
console . log(' 0 | | 1='(0 | | 1));console . log(' 1 | | 2='(1 | | 2));console . log(' 0 1='(0 1));console . log(' 12='(12));逻辑“与”和“或”运算符返回值,两者都是短路运算符:
逻辑并返回第一个为假的操作数或最后一个为真的操作数。
console . log(1 2 0);//0 console . log(1 0 1);//0 console . log(1 2 3);//3如果操作数为false,则不会计算其后的操作数。
Or逻辑返回为真的第一个操作数或为假的最后一个操作数。
console . log(1 | | 2 | | 0);//1 con sole . log(0 | | 2 | | 1);//2 con sole . log(0 | | 0 | | false);//false如果操作数为true,则不会计算操作数之后的操作数。
如果逻辑“与”和逻辑“或”混合使用,则逻辑“与”的优先级较高:
console . log(1 2 | | 0);//2 con sole . log(0 | | 2 ^ 1);//1 console . log(0 ^ 2 | | 1);//1在JavaScript中,常见的错误值:
0,' 0 ',0,-0,false ' ',null,undefined,null,nan注意空数组([])和空对象({}):
console . log([]==false)//true console . log({}==false)//false console . log(布尔值([]))//trueconsole.log(布尔值({ })//true,所以在if中,[]和{ }都是true:
20.解释以下代码的输出。
console . log(false==' 0 ')console . log(false==' 0 ')请参考上面问题14中的运算符转换规则图。
21.解释以下代码的输出。
var a={},b={key:'b'},c={ key : ' c ' };a[b]=123;a[c]=456;console . log(a[b]);输出为456。
22.解释以下代码的输出。
console.log((函数f(n){ return((n ^ 1)?n * f(n-1):n)})(10));结果是10的阶乘。这是一个递归调用。为了简化,我初始化n=5,调用链和返回链如下:
23.解释以下代码的输出。
(函数(x) { return(函数(y){ console . log(x));})(2)})(1);1、闭包可以访问外部范围的变量或参数。
24.解释以下代码的输出,并修复存在的问题。
var hero={ _name: 'John Doe ',getsecrettientity : function(){返回此。_ name}};var stoleSecretIdentity=hero . getsecretentity;console . log(stoleSecretIdentity());console . log(hero . getsecretentity());给stolessecretidentity赋予getSecretIdentity相当于定义了stolessecretidentity函数:
var stoleSecretIdentity=function(){返回这个。_ name} stoleSecretIdentity的上下文是一个全局环境,因此第一个输出是未定义的。要输出约翰多伊,通过调用、应用和绑定的方式来改变斯托雷秘书处的这个英雄。
第二种是调用对象的方法并输出John Doe。
25.给你一个DOM元素,创建一个可以访问该元素所有子元素的函数,并将每个子元素传递给指定的回调函数。
该函数接受两个参数:
使用深度优先搜索将DOM指定的回调函数的原始文本提供给一个实现:
函数Traverse(p_element,p _ callback){ p _ callback(p _ element);var list=p _ element.childrenfor(var I=0;一、清单.长度;i ) { Traverse(list[i],p _ callback);//递归调用}}以上是25个JavaScript面试问题分享给大家,希望能帮助大家参与面试。
版权声明:25个你需要知道的JavaScript面试问题是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。