JS经典题目解析
此次列举出一些觉得有意思的JS题目(来源于出了名的44题),相信有非常多关于这些题目的博客,写这篇博客的目的在于巩固一些知识点,希望能和读者共同进步。
1. map函数执行过程
["1", "2", "3"].map(parseInt)
2.[typeof null, null instanceof Object]
prototype 属性, 显而易见,null 没有构造函数,所以返回的是false3. 运算符优先级
var val = 'smtg';
console.log('Value is ' + (val === 'smtg') ? 'Something' : 'Nothing')
答案:Something解析:+ 运算符优先级高于 > ,所以没有括号的情况下, 会先执行字符串连接操作。所以等价于 ‘Value is true'? 'Something' : 'Nothing'如果搞不清运算符优先级的时候,可以加上括号4. 稀疏数组与Array.filter
var ary = [0,1,2];
ary[10] = 10;
ary.filter(function(x) { return x === undefined;});
答案:[]
解析: 这边的ary 是一个稀疏数组,index从3到9都没有定义,所以ary[3~9]的值是undefined(可以在chrome tool里通过ary[index]来查看),那么乍一看这个题的答案应该是返回7个undefined组成的数组。
但是这里返回的是[],原因在于filter函数的作用。
if (!Array.prototype.filter){
Array.prototype.filter = function(func, thisArg) {
'use strict';
if ( ! ((typeof func === 'Function' || typeof func === 'function') && this) )
throw new TypeError();
var len = this.length >>> 0,
res = new Array(len), // preallocate array
t = this, c = 0, i = -1;
if (thisArg === undefined){
while (++i !== len){
// checks to see if the key was set
//看这里 看这里
if (i in this){
if (func(t[i], i, t)){
res[c++] = t[i];
}
}
}
}
else{
while (++i !== len){
// checks to see if the key was set
if (i in this){
if (func.call(thisArg, t[i], i, t)){
res[c++] = t[i];
}
}
}
}
res.length = c; // shrink down array to proper size
return res;
};
}
可以看红色文字下方的代码,filter函数会先判断当前index是否在数组中被设置,即是否有ary[index] = value的过程,否则会跳过这个index。
所以对于稀疏数组,未定义的index会被跳过,从而导致这道题的答案是[]。 如果有ary[index] = undefined, 那么结果就会是返回由undefined 组成的数组。
5. String('A') 和 new String('A') 的区别
以下两个代码段的输出结果是?
function showCase(value) {
switch(value) {
case 'A':
console.log('Case A');
break;
case 'B':
console.log('Case B');
break;
case undefined:
console.log('undefined');
break;
default:
console.log('Do not know!');
}
}
showCase(new String('A'));
function showCase2(value) {
switch(value) {
case 'A':
console.log('Case A');
break;
case 'B':
console.log('Case B');
break;
case undefined:
console.log('undefined');
break;
default:
console.log('Do not know!');
}
}
showCase2(String('A'));
答案:‘Do not know!' ; 'Case A'
解析:为什么两个代码段的输出不一致呢?
两个原因:1.switch进行比较的时候用的是全等符“===”,所以不会做类型转换,即“10”不会等于10;
2. new String() 和 String 返回的类型不同,前者返回的是object,后者返回的是string,所以在做全等比较的时候,返回的结果是false。
所以如果有需要用到switch对于字符串做比较的时候,需要注意传入的参数类型。
6. 你真的了解"=="吗?
下面两个代码段的输出是?
var a = [0];
if ([0]) {
console.log(a == true);
} else {
console.log("wut");
}
[]==[]
答案:false, false
解析:如果单纯的把[0]转换成boolean类型的话,结果会是true,所以if判断语句的结果是true。
看了很多其他的博客,都有说到“==”会做类型转换,比较其值,我觉得这个答案依然无法详细解释上述代码的结果。
查阅了更多资料后,找到了一些“==“的规则:
1、如果两个值类型相同,进行 === 比较,比较规则同上
2、如果两个值类型不同,他们可能相等。根据下面规则进行类型转换再比较:
a、如果一个是null、一个是undefined,那么[相等]。
b、如果一个是字符串,一个是数值,把字符串转换成数值再进行比较。
c、如果任一值是 true,把它转换成 1 再比较;如果任一值是 false,把它转换成 0 再比较。
d、如果一个是对象,另一个是数值或字符串,把对象转换成基础类型的值再比较。对象转换成基础类型,利用它的toString或者valueOf方法。js核心内置类,会尝试valueOf先于toString;例外的是Date,Date利用的是toString转换。非js核心的对象,令说(比较麻烦,我也不大懂)
e、任何其他组合(array数组等),都不相等。
所以其实”==“的转换规则,并没有想象的那么简单,由此可见[0] == true, 应该采用的是规则c, 而[] == [] 应该采用的是规则e.
最后附上一张”==“比较的结果图

7. Arguments of methods
function sidEffecting(ary) {
ary[0] = ary[2];
}
function bar(a,b,c) {
c = 10
sidEffecting(arguments);
return a + b + c;
}
bar(1,1,1)
function sidEffecting(ary) {
ary[0] = ary[2];
}
function bar(a,b,c=3) {
c = 10
sidEffecting(arguments);
return a + b + c;
}
bar(1,1,1)
答案:21, 12
解析:第一个代码段的答案,我相信很容易得出。问题是第二个代码段,乍一看结果应该和第一个代码段相同,实则不然,那么是为什么呢?
其实这边不同的结果是由arguments 这个对象(arguments 不是数组)造成的,如果函数的参数有默认值的时候,那么arguments这个对象不会追踪参数值的变化,并且只记录传递过来的值。
所以第二个代码段中,arguments的结果是(1,1,1),sideEffecting函数拿到的结果是ary[0] =1, ary[2] =1; 所以回到a+b+c = 1+1+10 ==》 12。更多详情可以点击下方链接。
8. 有趣的比较符又来了
[1 < 2 < 3, 3 < 2 < 1]
答案: true, true
解析:1<2<3 等价于1<2=> true; true<3 => 1<3=> true;
3<2=> false; false<1 => 0<1=> true.
9.变量提升
(function(){
var x = y = 1;
})();
console.log(y);
console.log(x);
答案: 1, error
解析:这道题目涉及到变量提升的范围,以及赋值语法。
var x=y=1 等价于 var x=1; y=1; 这里的y会被提升至全局域,所以的除上述答案。
var x=1,y=1 等价于var x=1; var y=1, 这样写的话,x,y都是局部变量,不会被提升。
先总结这么几道,之后碰到觉得有趣的题目,会持续更新。
JS经典题目解析的更多相关文章
- js的预解析
在ES6之前,变量使用var声明,会存在变量的预解析(函数也有预解析).ES6引了let和const,但是现阶段ES6并没有完全普及,而且很多比较老的代码都还是按照ES5的标准甚至是ES3的标准来书写 ...
- 【前端】Vue.js经典开源项目汇总
Vue.js经典开源项目汇总 原文链接:http://www.cnblogs.com/huyong/p/6517949.html Vue是什么? Vue.js(读音 /vjuː/, 类似于 view) ...
- Vue.js经典开源项目汇总
Vue.js经典开源项目汇总 原文链接:http://www.cnblogs.com/huyong/p/6517949.html Vue是什么? Vue.js(读音 /vjuː/, 类似于 view) ...
- js经典试题之常用的方法
js经典试题之常用的方法 1.下面代码输出的值 let s = "bob" const replaced = s.replace('b', 'l') replaced === &q ...
- js经典试题之运算符的优先级
js经典试题之运算符 1.假设val已经声明,可定义为任何值.则下面js代码有可能输出的结果为: console.log('Value is ' + (val != '0') ? 'define' : ...
- js经典试题之ES6
js经典试题之ES6 1:在ECMAScript6 中,Promise的状态 答案:pending resolved(fulfilled) rejected 解析: Promise对象只有三种状态: ...
- js经典试题之w3规范系列
js经典试题之w3规范系列 1:w3c 制定的 javascript 标准事件模型的正确的顺序? 答案:事件捕获->事件处理->事件冒泡 解析:先事件捕获从windows > doc ...
- js经典试题之原型与继承
js经典试题之原型与继承 1:以下代码中hasOwnProperty的作用是? var obj={} …….. obj.hasOwnProperty("val") 答案:判断obj ...
- js经典试题之数组与函数
js经典试题之数组与函数 1:列举js的全局函数? 答案:JavaScript 中包含以下 7 个全局函数escape( ).eval( ).isFinite( ).isNaN( ).parseFlo ...
随机推荐
- 深入浅出Redis
一.Redis的诞生 Redis创建者,出生于西西里岛的意大利人(antirez)发明的,个人网站,http://invece.org.早年是系统管理员,2004-2006 年做嵌入式方面的工作,之后 ...
- Java集合排序(面试必考点之一)
集合是Java面试必考知识点,而集合的排序也是非常重要的,工作中经常用到,那么这个知识点也是必须要掌握的,下面是我曾经面试时被面试官问的问题: 根据API可知,Java集合的工具类Collection ...
- Javascript高级编程学习笔记(76)—— 表单(4)选择文本
文本框脚本 在HTML中文本框有两种实现方式: <input> <textarea> 这两种实现方式虽然在多数情况下表现一致,但是两者之间仍存在许多重要区别 对于<inp ...
- Javascript高级编程学习笔记(65)—— 事件(9)复合事件
复合事件 复合事件是 DOM3 中新增的一类事件,用于处理 IME 的输入序列 IME(输入法编辑器)通常用于输入物理键盘上找不到的字符,而这种输入方式通常需要同时按住多个键,但最终只输入一个字符 复 ...
- 第62节:探索Java中的网络编程技术
前言 感谢! 承蒙关照~ 探索Java中的网络编程技术 网络编程就是io技术和网络技术的结合,网络模型的定义,只要共用网络模型就可以两者连接.网络模型参考. 一座塔有七层,我们需要闯关. 第一层物理层 ...
- [Postman]查找替换(5)
在邮差中查找和替换 在Postman中快速轻松地查找和替换API项目中的文本.Postman应用程序使您能够执行全局查找和替换操作,该操作可在其各种组件(如集合,环境,全局和打开选项卡)中无缝工作.这 ...
- 边学边做,简单的 GraphQL 实例
项目中有功能要调用 API,对方 API 用的是 GraphQL 实现,就简单学了下,感叹技术进步真快,Facebook 发明的这玩意儿咋这么牛逼,使前端开发人员变得主动起来,想要什么接口.返回什么结 ...
- 为什么 array.foreach 不支持 async/await
一.背景 react 项目中,渲染组件时,显示的数据一直有问题,本来以为是 react 组件的问题,后来才发现罪魁祸首在 fetch 数据的过程,因为我用了 async/await ,而却搭配了 fo ...
- Java提高(5)---map集合排序
map集合排序 这篇文章讲的不仅仅是map排序,比如把对象按某一属性排序,它都可以解决这些问题. 比如,有N个对象,每个对象有个属性就是成绩,成绩分:优秀,良好,合格.那我们如何按照成绩的好坏进行排序 ...
- PHP取得json前面有乱码(去除文件头部BOM)
curl请求接口时,返回结果如下: {} 想把json转换成数组或者对象,但是用json_decode返回是空的,然后用var_dump打印了一下返回结果,发现结果如下: ) 发现前面多了两个字符,因 ...