前言:
最近总结了一些自己做题过程中遇到的易错问题,附带解析,希望对大家有帮助。
复制代码
1.下面哪些执行结果为true()
A ‘foo’ == new function(){ return String(‘foo’); };
B ‘foo’ == new function(){ return new String(‘foo’); };
C [] == 0
D ![]
E !0
点击查看答案
答案:B C E
点击查看涉及到的知识点
1.new返回值
2.String()与 new String()区别
3.隐式类型转换
解析:
A ‘foo’ == new function(){ return String(‘foo’); };
String('foo')
=>'foo'
new function
的return
会判断返回值是否为引用数据类型,如果不是引用数据类型会返回空对象{}
,所以new function(){ return String('foo'); }
返回{}
'foo' == {}
,{}
进行隐式类型转换,{}
调用valueOf
方法返回{}
对象,判断{}
不是基本数据类型,继续调用toString()
方法,返回'[object Object]'
。'foo' == '[object Object]'
,返回false
B ‘foo’ == new function(){ return new String(‘foo’); };
- new String(‘foo’);返回String对象。
- ‘foo’ == new String(‘foo’), new String(‘foo’)调用自身valueOf方法,返回’foo’
- ‘foo’ == ‘foo’ 返回 true
C [] == 0
引用数据类型会先转换为String,然后再转换为number
- 数组会先调用自身toString()方法
[].toString(); => ”
2. 使用Number(”)转为数字
Number(”) => 0
3. 0 == 0 => true
D ![]
将[]隐式转化为布尔值
- Boolean([]) => true
- !true => false
E !0
- Boolean(0) => false
- !false => true
Tips:
在==比较时遵循以下原则
1. 如果有一个操作数是布尔值,则在比较相等性之前,将其转换为数值;
2. 如果一个操作数是字符串,另一个操作数是数值,在比较之前先将字符串转换为数值;
3. 如果一个操作数是对象,另一个操作数不是,则调用对象的 valueOf() 方法,用得到的基本类型值按照前面的规则进行比较;
4. 如果有一个操作数是 NaN,无论另一个操作数是什么,相等操作符都返回 false;
5. 如果两个操作数都是对象,则比较它们是不是同一个对象。如果指向同一个对象,则相等操作符返回 true;
6. 在比较相等性之前,不能将 null 和 undefined 转成其他值。
7. null 和 undefined 是相等的。
复制代码
2.以下哪些事件会在页面加载完成(onload)之前触发?
A readystatechange
B pageshow
C beforeunload
D DOMContentLoaded
点击查看答案
答案:A D
点击查看涉及到的知识点
1.渲染过程
解析
A readystatechange
document有个readyState属性来描述document的状态,当readyState发生变化时会触发readystatechange事件。
loading:文档加载中
interactive:文档加载完毕,此时同样会触发DOMContentLoaded事件
complete:文档以及所引入的图片等资源加载完毕,此时同样会触发load事件
B pageshow
当load事件触发完毕后会触发pageshow事件
C beforeunload
当dom卸载时会触发,浏览器刷新页面、跳转页面、关闭页面时会触发。
D DOMContentLoaded
当dom解析完毕,同步js、css加载完毕时触发,会早于load事件。
Tips:
页面加载渲染简易流程
html解析为DOM,css解析为CSSOM,合并css与dom生成渲染树,布局,并进行渲染,下发简易为渲染
1.浏览器请求html
2.浏览器获取到html
3.浏览器解析html
4.解析到head标签,如果同步js则停止dom解析(等待js下载完毕并执行后继续dom解析),如果是css则不影响dom继续解析(但是影响dom渲染)。
5.进入body标签
- 如果只有dom则解析dom,同css树合并为渲染树,进行渲染。
- 如果有外链js,如果是同步js则下载并执行js,此时dom暂停解析,等待js执行完毕后继续解析,解析后生成dom树,并渲染。
- 如果有js也有css引入,同步js阻塞dom解析,dom等待js下载执行完,dom解析完毕后还需要等待css下载完成,然后dom与cssom合并为渲染树然后渲染。
6.当dom解析完毕
Tips:
浏览器遇到通过src引入外部js时,会先渲染已解析的dom
例:
引入外部js, 遇到script src时会先渲染已解析的dom
test.js
var i = 1000000000
while(i>0){
i--
}
console.log("解析完成")
html
<h1>Hello</h1>
<script type="text/javascript" src="https://juejin.cn/post/test.js"></script>
<h1>world</h1>
执行时,页面会先显示Hello,等几秒后会显示world
页面内写的js会阻塞dom解析与渲染
<h1>Hello</h1>
<script type="text/javascript">
var i = 1000000000
while(i>0){
i--
}
console.log("解析完成")
</script>
<h1>world</h1>
js执行完后才会显示 Hello world
复制代码
3.关于这段代码正确的结论是:()
var F=function(){};
Object.prototype.a=function(){};
Function.prototype.b=function(){};
var f=new F();
复制代码
A f能取到a,但取不到b
B f能取到a,b
C F能取到b,不能取到a
D F能取到a,不能取到b
点击查看答案
答案:A
点击查看涉及到的知识点
1.原型
解析:
一. f能访问那些
f
的__proto__
指向的是F构造函数的prototype
。- 属性查找是通过原型链查找的。
f.__proto__
=F.prototype
,F.prototype.__proto__
=Object.prototype
,Object.prototype.__proto__
=null
。f
可以获取到a
。
二. F能访问那些
F.__proto__
=Function.prototype
。所以F能访问到bFunction.prototype.__proto__
=Object.prototype
。所以F能访问a。- 结论,F能访问a跟b。
4.以下结果里,返回 false
的是?
A [] == true
B !![]
C NaN == NaN
D null == undefined
点击查看答案
答案:A C
点击查看涉及到的知识点
1.隐式类型转换
解析:
A [] == true
如果有一个操作数是布尔值,则在比较相等性之前,将其转换为数值;
- [] == Number(true) => [] == 1
- [].toString() == 1 => ” == 1
- Number(”) == 1 => 0 == 1
- false
B !![]
- Boolean([]) => true
- !true => false
- !false => true
C NaN == NaN
如果有一个操作数是 NaN,无论另一个操作数是什么,相等操作符都返回 false;
- false
D null == undefined
null 和 undefined 是相等的。
- true
5.下面的代码将返回:
Number(null);
A Null
B 0
C undefined
D 1
点击查看答案
答案:B
点击查看涉及到的知识点
1.Number函数的用法
解析:
- Number(null) => 0
- Number(undefined) => NaN
- Number(
123a
) => NaN
6.假设有如下代码,那么a(10)的返回结果是?( )
function a(a)
{
a^=(1<<4)-1;
return a;
}
复制代码
A 5
B 10
C 15
D 16
点击查看答案
答案:A
点击查看涉及到的知识点
1.二进制转换
2.左移运算符
3.异或运算符
解析:
涉及到异或、二进制转换、
- a^=(1<<4)-1 => a = a ^ ((1<<4) -1);
- 带入参数 a = 10 ^((1<<4) -1);
- ((1<<4) -1)
- 1<<<4 转换为二进制 10000
- 10000 转换为十进制 => 2⁴ => 16
- ((1<<4) -1) => 15
- 10 ^ 15
- 10转化为二进制 => 1010
- 15转化为二进制 => 1111
- 10^15 => 101
- 101 =>转化为10进制 2²+1 => 5
- 返回5
Tips:
二进制转换为十进制:
除二取余,然后倒序排列,高位补零
例:
10转化为2进制
1. 10%2 = 0
2. 5%2 = 1
3. 2%2 = 0
4. 1 = 1
倒序排列:
1010
复制代码
7.假设val已经声明,可定义为任何值。则下面js代码有可能输出的结果为:
console.log('Value is ' + (val != '0') ? 'define' : 'undefine');
复制代码
A Value is define
B Value is undefine
C define
D undefine
E Value is define 或者 Value is undefine
F define 或者 undefine
G 其它选项都有可能
点击查看答案
答案:C
点击查看涉及到的知识点
1.运算符优先级
解析:
考察运算符优先级,+优先级高于三目运算,上面代码等价于
('Value is ' + (val != '0')) ? 'define' : 'undefine'
复制代码
8.运行以下程序,y和z的最终结果为:
<script>
var m= 1, j = k = 0;
function add(n) {
return n = n+1;
}
y = add(m);
function add(n) {
return n = n + 3;
}
z = add(m);
</script>
复制代码
A 2,4
B 4,4
C 2,2
D 报异常
点击查看答案
答案:B
点击查看涉及到的知识点
1.函数提升
2.值传递
解析:
- 同名函数会相互覆盖,由于函数存在函数提升,后定义的函数会覆盖之前定义的函数,所以y,z调用的都是第二个add函数。
- 传入函数的m因为是基本类型,在函数内修改不会影响外部的变量
结尾:
在错题中寻找自己的知识薄弱点,巩固并完善自己的知识体系,建议收藏,经常看看,避免遗忘~
复制代码