整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

看看这些只有几行代码的JavaScript笔试题你会

看看这些只有几行代码的JavaScript笔试题你会做吗?


今天这篇文章整理了几道常见的Javascript笔试题,这些题目看似简单,但一不注意就会出错,来看看你都会做吗?

Javascript

题目1-typeof和instanceof

我们都知道typeof是用于检测一个变量的数据类型的,instanceof是用于判断某个变量是否是指定类型的实例。

我们来看看下面的代码。

题目1

在Javascript中Null作为一种单独的数据类型,其类型只有一个值null。Null是一个特殊的Object类型,因此在typeof null时,返回的是‘object’。

既然typeof null返回的是object,那么null instanceof Object是不是就返回true呢?结果是否定的。

由于Null的特殊性,null值的产生并不是通过Object原型链的,通过Object类型的原型链不能追溯到Null值,因此null instanceof Object返回值为false。

题目2-reduce方法

第二道题是reduce方法与Math.pow()方法结合,确定输出结果,代码如下。

题目2

首先我们来看看reduce方法的使用,它的API如下。

recude方法

接收一个回调函数,对数组中的元素依次进行处理,从参数名可以很容易看出previousValue为上一次计算结果的值,currentValue表示当前处理值。

同时可选择接收一个初始值initialValue,如果这个initialValue传递了,那么第一次调用回调函数时的previousValue就等于initialValue,如果没有传递则previousValue就等于数组的第一个值。

理解上述的原则后,我们再来看看这道题目。

题目2中的回调函数是Math.pow(),Math.pow(a, b)表示的是a的b次方。其中a就是reduce回调函数的previousValue,b就是currentValue了。

在第一段代码中,没有传递initialValue,则previousValue为3,currentValue为2,那么计算后是Math.pow(3, 2)=9。

同理在第二次计算时,previousValue为9,currentValue为1,则计算结果时Math.pow(9, 1)=9。

因此第一段代码最终结果是9。

再来看看第二段代码,不同于第一段的是它传递了initialValue为0,那么在进行第一次计算时,previousValue为0,currentValue为3,则第一次计算是Math.pow(0, 3)=0;

接下来进行第二次计算,previousValue为上一次计算结果0,currentValue为2,则计算结果是Math.pow(0, 2)=0;

同理最后一次计算,previousValue为0,currentValue为1,计算结果是Math.pow(0, 1)=0;

因此第二段代码最终结果是0。

题目3-Boolean与[0]

第三道题考察的是Boolean与[0]的用法,代码如下所示。

题目3

代码首先定义了一个变量a,为只有一个元素0的数组。

然后通过if语句判断[0]是否为true,进而输出不同的值。

这道题的核心在于if语句中的返回结果,需要注意的是,if语句的判断结果实际是利用了Boolean的构造方法,看看利用Boolean的构造方法能否将if语句中的值转化为true。

根据Boolean构造方法的定义,如果逻辑对象无初始值或者其值为 0、-0、null、""、false、undefined 或者 NaN,Boolean构造方法会返回false,否则返回true。

从题目中我们可以看出if语句中的值为[0],不满足任何一个返回false值的条件,因此Boolean([0])=true,那么if判断语句就进入到true的判断中。

那么就会执行console.log(a==true),注意这里的判断并不会调用Boolean的构造方法,而是直接比较[0]与true。

这个时候true会转换为1,[0]会进行隐式转换,[0]会转换为'0',然后转换为数字0,相当于比较0与1的值。

很明显0与1比较返回false,那么最终的结果是输出false

题目4

题目4主要考察的是算术运算符与正负运算符,题目代码如下。

题目4

很多人看到这么多加减号,都以为这题目是不是出错了?其实是没有问题的。

遇到这样的题目,只要记住以下这点内容:

  • 在数字后面的第一个符号为算术运算符加/减,其他加减号都是正负数转换的运算符。

第一行代码可以拆分成这样的内容。

1 + (- + + + - + 1)

优先处理后面括号中的值,其中的加减号表示正负数转换的。

从右往左看,首先是+1,然后是负号-,变为-1,在连续三个正号+,还是-1,最后是一个负号-,变为+1。

其实最后计算就是1 + 1=2。

懂得这个原理后,我们直接看第三行代码,拆分后变成这个样子。

1 - (- + + + - - - - + + 1) + (1) + (- - - - + - 1)

对括号中的数优先处理,第一个括号中得到的值是-1,第二个括号中得到的值是1,第三个括号中得到的值是-1。

所以实际的运算是1-(-1)+1+(-1)=2。

题目5-arguments

在JavaScript中有一个arguments对象,表示的是传递给函数的参数对象,这道题目也与arguments有关。

题目5

我们来分析下上面的代码。

  • 定义一个函数,用于将数组的第三个元素值赋给第一个元素。

  • 定义第二个函数,传递的参数先赋初始值,然后经过第一个函数处理。

  • 计算三个参数相加的和并返回。

在函数中arguments是直接代表该函数接收的参数列表的,上面的bar函数内部的arguments实际就是[a, b, c]。

我们需要记住以下这条规则,在函数没有接收变长参数(...扩展运算符),默认参数和结构赋值等ES6的新特性时,arguments对象的值和参数的值是相互影响的。

因此第一个函数中将第三个元素值赋给第一个元素是生效的,那么c=10,a=10,b=1,所以最终结果返回21。

但是如果使用了ES6中的几个新特性时,arguments对象的值和参数值是不会相互受影响的。

我们来看看以下的例子。

  • 使用变长参数

只需要将上面的题目做简单的修改,第一个函数的参数ary变为...ary即可。

修改1-变长参数

使用变长参数后,对ary进行修改,不会影响到原来函数的参数a,b,c的值,所以a=1, b=1,c=10,最终结果返回12。

  • 使用默认参数

同样对以上原始题目做简单的修改,对c使用默认参数。

默认参数

修改后的代码中,给c设定默认值为2。使用默认参数后情况与上面一种一样,最终的结果也是返回12。

  • 使用解构赋值

对以上代码进行简单的改造,得到如下使用解构赋值的代码。

使用解构赋值

同样最终的结果返回12。

结束语

今天这篇文章讲解了几道JavaScript相关的题目,虽然代码量都很少,但是理解起来却不是那么容易,需要慢慢消化,希望今天的文章对你们有帮助噢~

avaScript作为一门如此灵活的语言,自然在编码时给我们带来了很多方便,但方便的同时,也衍生出了很多变态的语法,下面我们来梳理一些常见的变态语法,希望你下次在某位大牛的代码中看到这样的东西,不要惊掉下巴。


?

NO.1

Number.prototype.add=function(n){

return this+n;

}

2["add"](3)

最后一句话是什么玩意儿?好像没看懂呢? 我们来运行一下看看:

擦? 居然执行了?结果是5,看上去似乎对2和3做了加法。不是说变量名不能数字开头么?这是怎么回事?浏览器抽风了?

实际上js有很多不能说的秘密,其中一个就叫做自动装箱,这是引用java里的叫法。也就是说,当我们试图2[“add”]的时候,这个数字2已经不再是2了,它被自动转换成了Number对象,跟java中的包装类型是一个意思。

等价于这样写:

new Number(2)

而对象是可以通过[“prop"]这种形式来获取属性的,于是我们就不难推理了~

2["add"] 相当于new Number(2).add

最终变成

new Number(2).add(3);

结果是 5

NO.2

+function(){;}()

这又是个什么玩意儿?函数前面带个+号? 这难道是自动类型转换?等等,里面是个;号? 后面还有一对( )?

先不要着急惊讶,其实还有很多,例如:

-function(){;}()

!function(){;}()

~function(){;}()

void function(){;}()

new function(){;}()

delete function(){;}()

var i=function(){;}()

1 && function(){;}()

0 || function(){;}()

1 & function(){;}()

1 | function(){;}()

1 ^ function(){;}()

1, function(){;}()

这些“丧尽天良”的写法是谁发明的?!你给我站出来,我保证不打死你!(此处作者冷静了5分钟)……

接下来说说它的原理吧!

首先 , ;号本身也是一条语句,相信大多数同学应该是知道的,就不多说了。其次,一个函数的自调用,如果写成这样:

错误的原因在于,函数声明和函数调用是不可以混在一起的,所以通常的写法是:

这并不是把函数当成了一个整体来运行,这里其实还有一个不能说的秘密。

( )这个符号,在js里是运算符。(A)的结果是返回表达式A

所以它的出现,让这个匿名函数从声明变成了执行,也就是编译期间浏览器不会提前准备它,自然就没有语法错误。而几分钟前我们看到的那些丧心病狂的写法,其实原理都一样,通过运算符把声明变成执行。当然这些符号都不会影响函数的正常执行结果。

但是问题又来了,这种泯灭人性的写法,现在居然还挺常见的,例如:

没错,这就是著名的bootstrap的js源码,连它都是这么写的,莫非真有什么好处?

通过在网上查询大量的资料,我还真发现有人专门对此做了研究,将上面这些写法全部在各个浏览器中间做了压力测试,发现+function( ){;}( ) 执行速度最快,比(function( ){})( )要快出好几倍,而 new function( ){;}( ) 执行速度最慢。

不过为了追求效率而把代码写成这样到底值不值,那只能你自己去判断了。

NO.3

!!a

这又是什么鬼啊?!!a 实际上等价于 a || false

由于js中所有的内容都是可以跟布尔类型互换的,这也是js特别让人费解的地方,比如

if(window.VBArray){…}

可以用来判断IE浏览器,因为对象存在时,等价于true,undefined等价于false,但是!很多时候我们判断一个属性是否存在,并不需要马上作出反应,而是将结果告知他人,比如说有个函数,test(hasSuperman),函数规定调用时需要传入一个布尔类型,告知它superman是否存在,你可能会这样写:

if(window.superman){

test(true);

} else {

test(false);

}

但你最好不要这么写:

test(window.superman);

因为你并不知道test函数内部发生了什么,所以很难预料会不会产生错误,因此最好的写法是这样:

test(!!window.superman);

通过两次取反,保证了值没有变化,但类型已经被转为了布尔类型。好吧,似乎这么写还有点道理。

NO.4 最短IE(6,7,8)判定

if(!-[1,]){

//判断IE6,7,8

}

它的原理实际上是利用了IE的bug。

当我们写下一个数组 [1,].length

在IE中 [1,].length -------> 2

在非IE中 [1,].length -------> 1

当我们试图打印[1,],相当于调用toString()方法

在IE中 [1,] -------> "1,"

在非IE中 [1,] -------> "1"

当我们给它加上负号-[1,]

在IE中 -[1,] -------> NaN

在非IE中 -[1,] -------> -1

当我们对它进行取反!-[1,]

在IE中 !-[1,] -------> true

在非IE中 !-[1,] -------> false

这样我们就可以判断是否为IE浏览器了,这个bug一直到IE9之后才消失的。

好了,这次的变态语法就先讲这么多,以后碰到更新鲜的再来给大家更新,拜拜。

编辑:千锋web前端


今天这篇文章整理了几道常见的Javascript笔试题,这些题目看似简单,但一不注意就会出错,来看看你都会做吗?

Javascript

题目1-typeof和instanceof

我们都知道typeof是用于检测一个变量的数据类型的,instanceof是用于判断某个变量是否是指定类型的实例。

我们来看看下面的代码。

题目1

在Javascript中Null作为一种单独的数据类型,其类型只有一个值null。Null是一个特殊的Object类型,因此在typeof null时,返回的是‘object’。

既然typeof null返回的是object,那么null instanceof Object是不是就返回true呢?结果是否定的。

由于Null的特殊性,null值的产生并不是通过Object原型链的,通过Object类型的原型链不能追溯到Null值,因此null instanceof Object返回值为false。

题目2-reduce方法

第二道题是reduce方法与Math.pow()方法结合,确定输出结果,代码如下。

题目2

首先我们来看看reduce方法的使用,它的API如下。

recude方法

接收一个回调函数,对数组中的元素依次进行处理,从参数名可以很容易看出previousValue为上一次计算结果的值,currentValue表示当前处理值。

同时可选择接收一个初始值initialValue,如果这个initialValue传递了,那么第一次调用回调函数时的previousValue就等于initialValue,如果没有传递则previousValue就等于数组的第一个值。

理解上述的原则后,我们再来看看这道题目。

题目2中的回调函数是Math.pow(),Math.pow(a, b)表示的是a的b次方。其中a就是reduce回调函数的previousValue,b就是currentValue了。

在第一段代码中,没有传递initialValue,则previousValue为3,currentValue为2,那么计算后是Math.pow(3, 2)=9。

同理在第二次计算时,previousValue为9,currentValue为1,则计算结果时Math.pow(9, 1)=9。

因此第一段代码最终结果是9。

再来看看第二段代码,不同于第一段的是它传递了initialValue为0,那么在进行第一次计算时,previousValue为0,currentValue为3,则第一次计算是Math.pow(0, 3)=0;

接下来进行第二次计算,previousValue为上一次计算结果0,currentValue为2,则计算结果是Math.pow(0, 2)=0;

同理最后一次计算,previousValue为0,currentValue为1,计算结果是Math.pow(0, 1)=0;

因此第二段代码最终结果是0。

题目3-Boolean与[0]

第三道题考察的是Boolean与[0]的用法,代码如下所示。

题目3

代码首先定义了一个变量a,为只有一个元素0的数组。

然后通过if语句判断[0]是否为true,进而输出不同的值。

这道题的核心在于if语句中的返回结果,需要注意的是,if语句的判断结果实际是利用了Boolean的构造方法,看看利用Boolean的构造方法能否将if语句中的值转化为true。

根据Boolean构造方法的定义,如果逻辑对象无初始值或者其值为 0、-0、null、""、false、undefined 或者 NaN,Boolean构造方法会返回false,否则返回true。

从题目中我们可以看出if语句中的值为[0],不满足任何一个返回false值的条件,因此Boolean([0])=true,那么if判断语句就进入到true的判断中。

那么就会执行console.log(a==true),注意这里的判断并不会调用Boolean的构造方法,而是直接比较[0]与true。

这个时候true会转换为1,[0]会进行隐式转换,[0]会转换为'0',然后转换为数字0,相当于比较0与1的值。

很明显0与1比较返回false,那么最终的结果是输出false

题目4

题目4主要考察的是算术运算符与正负运算符,题目代码如下。

题目4

很多人看到这么多加减号,都以为这题目是不是出错了?其实是没有问题的。

遇到这样的题目,只要记住以下这点内容:

  • 在数字后面的第一个符号为算术运算符加/减,其他加减号都是正负数转换的运算符。

第一行代码可以拆分成这样的内容。

1 + (- + + + - + 1)

优先处理后面括号中的值,其中的加减号表示正负数转换的。

从右往左看,首先是+1,然后是负号-,变为-1,在连续三个正号+,还是-1,最后是一个负号-,变为+1。

其实最后计算就是1 + 1=2。

懂得这个原理后,我们直接看第三行代码,拆分后变成这个样子。

1 - (- + + + - - - - + + 1) + (1) + (- - - - + - 1)

对括号中的数优先处理,第一个括号中得到的值是-1,第二个括号中得到的值是1,第三个括号中得到的值是-1。

所以实际的运算是1-(-1)+1+(-1)=2。

题目5-arguments

在JavaScript中有一个arguments对象,表示的是传递给函数的参数对象,这道题目也与arguments有关。

题目5

我们来分析下上面的代码。

  • 定义一个函数,用于将数组的第三个元素值赋给第一个元素。

  • 定义第二个函数,传递的参数先赋初始值,然后经过第一个函数处理。

  • 计算三个参数相加的和并返回。

在函数中arguments是直接代表该函数接收的参数列表的,上面的bar函数内部的arguments实际就是[a, b, c]。

我们需要记住以下这条规则,在函数没有接收变长参数(...扩展运算符),默认参数和结构赋值等ES6的新特性时,arguments对象的值和参数的值是相互影响的。

因此第一个函数中将第三个元素值赋给第一个元素是生效的,那么c=10,a=10,b=1,所以最终结果返回21。

但是如果使用了ES6中的几个新特性时,arguments对象的值和参数值是不会相互受影响的。

我们来看看以下的例子。

  • 使用变长参数

只需要将上面的题目做简单的修改,第一个函数的参数ary变为...ary即可。

修改1-变长参数

使用变长参数后,对ary进行修改,不会影响到原来函数的参数a,b,c的值,所以a=1, b=1,c=10,最终结果返回12。

  • 使用默认参数

同样对以上原始题目做简单的修改,对c使用默认参数。

默认参数

修改后的代码中,给c设定默认值为2。使用默认参数后情况与上面一种一样,最终的结果也是返回12。

  • 使用解构赋值

对以上代码进行简单的改造,得到如下使用解构赋值的代码。

使用解构赋值

同样最终的结果返回12。

结束语

今天这篇文章讲解了几道JavaScript相关的题目,虽然代码量都很少,但是理解起来却不是那么容易,需要慢慢消化,希望今天的文章对你们有帮助噢~