阿里达摩院训练题4

  |  

前言

每天一练


63



单选题

题目描述:以下选项错误的是

题目答案:b

题目解析:

a.我们应该尽量避免使用”==”来做比较

正确:==是弱等,他会先检查两个数数据类型,如果相同就进行===比较,如果不同,则会对数进行一次强制类型转换,转换成相同类型后再进行比较。而我们要尽量避免非主观的强制类型转换。

b.Object.is 与 “===” 除了对NaN的比较结果不同外,比较行为基本一致

错误:Object.is与===有两点不同:

  • 在Object.is的比较中+0不等于-0,而===则认为两者相等
  • 在Object.is的比较中NaN等于NaN,而===则认为两者不相等

除此之外,Object.is的行为与”===”基本一致

c.通过Object.toString方法可以帮助我们查看数据的类型,Object.prototype.toString.call(NaN)返回的值是’[object Number]’

正确:Object.prototype.toString.call()的确是一种效果极为不错的判断方式,至少在ES5版本中,这种方法的判断都是正确,这也是为什么jQuery采用这种方式来编写它的比较函数的原因。但是ES6提出Symbol概念以后这种方法也不是严格正确的了,因为我们可以通过对象原型上的Symbol.toStringTag来改变这种方法的返回值,虽然这样的行为并不被推荐,但是语言并没有禁止该行为。

toString

不过Object.prototype.toString.call仍是查看数据类型的一个好办法

d.表达式toString.call(new String(‘test’)) === toString.call(‘test’) && new String(‘test’) !== String(‘test’) 的结果是true

正确:首先toString.call(new String(‘test’))和toString.call(‘test’)的都会返回[object String],这是因为在被toString.call调用时’test’会被创建一个包装对象,所以两者的比较结果是true。

new String(‘test’) !== Strng(‘test’)的结果也是true,这是因为String()返回的是字符串,也就是基本类型值,而new String(‘test’)返回的是字符串对象,是引用类型。而类型不一样是不可能严格相等的。最后true && true,当然是true

e.Date实例的toLacaleString方法的返回值会根据语言环境返回不同的值

正确:Date.prototype.toLacaleString()方法返回一个表示该日期对象的字符串,该字符串与系统设置的地区关联,而使用不同语言的国家一般日期格式不相同

多选题

题目描述:以下选项正确的是

题目答案:a、c、d

题目解析:

a.setTimeout两次执行之间的间隔大于等于指定的时间,setInterval两次执行之间的间隔会小于指定的时间

正确:虽然setTimeout用执行间隔这个词描述不太严谨,因为setTimeout只执行一次。不过我能理解这里的意思,应该是只从setTiemout设置,到回调函数执行的间隔。这个间隔时间的确大于设定时间,因为setTimeout到指定的时间后,并不是立即执行回调函数,而是将回调函数放到宏任务队列中,所以会有一定的延迟,因为要等事件循环循环到宏任务执行,而且如果宏任务队列中之前还有其它宏任务,这个延迟还会更久。

setInterval是每隔指定时间执行一次回调函数,所以存在执行间隔,但是要考虑到回调函数执行也需要时间,但是计时是不考虑执行时间的,一旦回调函数被调用,他就开始重新计时。举个例子,假设我们设置100毫秒执行一次,而回调函数需要5毫秒的执行时间,那么在回调函数执行结束95毫秒后,它将再次执行。

b.requestAnimationFrame总是与浏览器屏幕的刷新次数匹配,大多数屏幕的刷新频率是60HZ,对应大约16.7ms就会执行一次回调函数

错误:没做过HTML5动画,只能百度了…

requestAnimationFrame是HTML5新增的专门用于请求动画的API。根据MDN的描述,该函数会要求浏览器在下次重绘之前调用指定的回调函数更新动画。在大多数遵循W3C标准的浏览器中,回调函数执行次数通常与浏览器屏幕刷新次数相匹配,一般为每秒60次。但是为了提高性能和电池寿命,因此在大多数浏览器里,当requestAnimationFrame() 运行在后台标签页或者隐藏的<iframe>里时,requestAnimationFrame() 会被暂停调用以提升性能和电池寿命。因此并总是与浏览器的刷新次数匹配的,存在浏览器刷新,但是回调函数不调用的情况。

c.promies.then中回调是异步执行的,且比setTimeout先执行

正确:这个选项的描述可能比较模糊

不过如果setTimeout和promies.then是在同一个任务中设置的。那么promise.then的回调函数的确会比setTimeout的回调函数先执行。因为promise.then属于微任务,不管设置的任务是宏任务还是微任务,promise.then的回调函数会在稍后得到执行。而setTimeout即使设置延迟为0,回调函数被立即放入宏任务队列中,它最早也得等到下一轮事件循环才能得到执行

1
2
3
4
5
6
7
setTimeout(() => {
console.log('setTimeout')
}, 0)
let pro = Promise.resolve(20);
pro.then(() => {
console.log('promise.then')
});

c

d.做动画效果,建议使用requestAnimationFrame > setTimeout

正确:requestAnimationFrame跟setTimeout相比,CPU节能,因为页面被隐藏或者最小化时,setTimeou仍会在后台执行动画任务,但是requestAnimationFrame则不会。其次,函数节流,在高频事件中,requestAnimationFrame可以保证每个刷新间隔内,函数只被执行一次。

编程题

题目描述:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
【编程】实现 parse 函数,满足如下用例
const template = 'there are ${count} ${name} on the ${place}.';
function create(value) {
return {
tag: 'div',
children: value
};
}
function parse(tpl, data, create){
// 补充代码
}
console.log(parse(template, {count: 2, name: 'apples', place: 'table'}, create));
/* 输出数据如下,最终输出的是混合了字符串和 JSON 对象的数组。
['there are ', {tag: 'div', children: 2}, ' ', {tag: 'div', children: 'apples'},' on the ', {tag: 'div', children: 'table'}, '.']
*/

题目解析:

这道题,要考虑data里面的参数和模板匹配不上的问题,比如所模板里有三个${}包裹的参数,而data对象中只有两个,那么模板中多出的一个,我们就得以字符串的形式处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
const template = 'there are ${count} ${name} on the ${place}.';
function create(value) {
return {
tag: 'div',
children: value
};
}
function parse(tpl, data, create) {
let reg = /\$\{(\w+)\}/g,
variableArray = tpl.match(reg).map(item => item.replace(reg,'$1'));
result = tpl.replace(/\$\{/g, ',').replace(/\}/g, ',').split(',');
for(let value of variableArray) {
result.map((item, index) => {
if(item == value) {
if(data[item]) {
result[index] = create(data[item]);
} else {
result[index] = '${' + result[index] + '}';
}
}
})
}
return result
}
parse(template, {count: 2, name: 'apples', place: 'table', test: 'test'}, create);

我们先用正则把和replace函数,将${}中的数据全部提取出来,然后为了方便字符串分隔,我们把字符串中的所有${}替换为逗号,再用逗号分隔字符串。

然后我们在遍历提取出来的数据的数组。如果传入参数中有对应的键,那么将对应的值传入create,并替代分隔后的数组中对应的值,如果没有,则将其重新变回${...}形式,最后完成了解析

编程题

文章目录
  1. 1. 单选题
  2. 2. 多选题
  3. 3. 编程题