好程序员Java教程分享JavaScript常见面试题四

  好程序员Java教程分享JavaScript常见面试题四一、下面的代码将输出什么到控制台,为何?程序员

 

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);面试

 

上面的代码将输出如下内容到控制台:数组

 

"122""32""02""112""NaN2"NaN闭包

 

缘由是ide

 

这里的根本问题是,JavaScript(ECMAScript)是一种弱类型语言,它可对值进行自动类型转换,以适应正在执行的操做。让咱们经过上面的例子来讲明这是如何作到的。函数

 

11 + "2" + "2" 输出:"122" 说明: 1 + "2" 是执行的第一个操做。因为其中一个运算对象("2")是字符串,JavaScript会假设它须要执行字符串链接,所以,会将 的类型转换为 "1", 1 + "2"结果就是 "12"。而后, "12" + "2" 就是 "122"spa

 

2: 1 + +"2" + "2" 输出: "32" 说明:根据运算的顺序,要执行的第一个运算是 +"2"(第一个 "2" 前面的额外 被视为一元运算符)。所以,JavaScript将 "2" 的类型转换为数字,而后应用一元 (即,将其视为一个正数)。其结果是,接下来的运算就是 1 + 2 ,这固然是 3。而后咱们须要在一个数字和一个字符串之间进行运算(即, 和 "2"),一样的,JavaScript会将数值类型转换为字符串,并执行字符串的链接,产生 "32"orm

 

3: 1 + -"1" + "2" 输出: "02" 说明:这里的解释和前一个例子相同,除了此处的一元运算符是 而不是 +。先是 "1" 变为 1,而后当应用 时又变为了 -1 ,而后将其与 1相加,结果为 0,再将其转换为字符串,链接最后的 "2" 运算对象,获得 "02"对象

 

4: +"1" + "1" + "2" 输出: "112" 说明:虽然第一个运算对象 "1"由于前缀的一元 运算符类型转换为数值,但又当即转换回字符串,当链接到第二个运算对象 "1" 的时候,而后又和最后的运算对象"2" 链接,产生了字符串 "112"教程

 

5: "A" - "B" + "2" 输出: "NaN2" 说明:因为运算符 不能被应用于字符串,而且 "A" 和 "B" 都不能转换成数值,所以,"A" - "B"的结果是 NaN,而后再和字符串 "2" 链接,获得 "NaN2" 

 

6: "A" - "B" + 2 输出: NaN 说明:参见前一个例子, "A" - "B" 结果为 NaN。可是,应用任何运算符到NaN与其余任何的数字运算对象,结果仍然是 NaN

 

2下面的递归代码在数组列表偏大的状况下会致使堆栈溢出。在保留递归模式的基础上,你怎么解决这个问题?

 

var list = readHugeList();var nextListItem = function() { var item = list.pop(); if (item) { // process the list item...

 

nextListItem();

 

}

 

};

 

潜在的堆栈溢出能够经过修改nextListItem 函数避免:

 

var list = readHugeList();var nextListItem = function() { var item = list.pop(); if (item) { // process the list item...

 

setTimeout( nextListItem, 0);

 

}

 

};

 

堆栈溢出之因此会被消除,是由于事件循环操纵了递归,而不是调用堆栈。当 nextListItem 运行时,若是 item不为空,timeout函数(nextListItem)就会被推到事件队列,该函数退出,所以就清空调用堆栈。当事件队列运行其timeout事件,且进行到下一个 item 时,定时器被设置为再次调用 extListItem。所以,该方法从头至尾都没有直接的递归调用,因此不管迭代次数的多少,调用堆栈保持清空的状态。

 

3JavaScript中的“闭包”是什么?请举一个例子。

 

闭包是一个能够访问外部(封闭)函数做用域链中的变量的内部函数。闭包能够访问三种范围中的变量:这三个范围具体为:(1)本身范围内的变量,(2)封闭函数范围内的变量,以及(3)全局变量。

 

下面是一个简单的例子:

 

var globalVar = "xyz";

 

(function outerFunc(outerArg) { var outerVar = 'a';

 

(function innerFunc(innerArg) { var innerVar = 'b'; console.log( "outerArg = " + outerArg + "\n" + "innerArg = " + innerArg + "\n" + "outerVar = " + outerVar + "\n" + "innerVar = " + innerVar + "\n" + "globalVar = " + globalVar);

 

})(456);

 

})(123);

 

在上面的例子中,来自于 innerFunc, outerFunc和全局命名空间的变量都在 innerFunc的范围内。所以,上面的代码将输出以下:

 

outerArg = 123innerArg = 456outerVar = ainnerVar = bglobalVar = xyz

 

4下面的代码将输出什么:

 

for (var i = 0; i < 5; i++) {

 

setTimeout(function() { console.log(i); }, i * 1000 );

 

}

 

解释你的答案。闭包在这里能起什么做用?

 

上面的代码不会按预期显示值0123,和4,而是会显示5555,和5

 

缘由是,在循环中执行的每一个函数将整个循环完成以后被执行,所以,将会引用存储在 i中的最后一个值,那就是5

 

闭包能够经过为每次迭代建立一个惟一的范围,存储范围内变量的每一个惟一的值,来防止这个问题,以下:

 

for (var i = 0; i < 5; i++) {

 

(function(x) {

 

setTimeout(function() { console.log(x); }, x * 1000 );

 

})(i);

 

}

 

这就会按预期输出0123,和4到控制台。

相关文章
相关标签/搜索