0
点赞
收藏
分享

微信扫一扫

【JS错题锦集】记录一下常考易错知识点

you的日常 2022-02-21 阅读 34

在这里插入图片描述

前阵子在刷牛客网的js选择题库,后来一个多月没刷,感觉很多知识点又忘记了,所以整理一下自己觉得重要、易错的题~本文中涉及的题均来自牛客网题库,题解参考牛客网答友或搜索到的资料。掺杂了些CSS和HTML的题,见谅,可以根据目录挑选自己想看的题。如果有解释不当的地方,还望指教

1. 关于this指针的指向
2. prototype和__proto__
3. call与apply对比
4. 强制转换、隐式转换
4.1 双等号==
4.2 Boolean类型转换
4.3 加号与减号
4.4 API强制类型转换
4.5 new String 与 ’ ’
5. API使用
5.1 map函数
5.2 parseInt函数
6.立即执行函数
7.ES5的变量提升
8.JS对象转基本类型
9.W3C标准盒模型
10. 其他
10.1 margin塌陷问题
10.2 promise的all方法
10.3 浏览器渲染流程与页面加载过程
10.4 HTML语义化
10.5 position定位
10.6 回流和重排
10.7 CSS的引入
10.8 Javascript的引入(未写待更)
10.9 Javascript的相关概念
10.10 a标签——链接
10.11 定义函数
10.12 for循环条件表达式和遍历
10.13 运算符优先级


1.关于this指针的指向

分析:this指针是函数体内自带的一个对象指针;也可以理解成,this出现在某个函数中。在ES5的语法,this指针指向的简单判断规则是:哪个对象拥有了这个函数,this就是这个对象的指代

结合例子分析能更好地理解题意,具体可以查看我的这篇文章

有时我们会遇到这种情况:我们需要使用外层函数的this环境,于是提前保存this对象,如:var vm = this;,到内层函数使用时,直接用预保存的vm变量即可
ES6的this机制就很好地改善了这个情况,我们可以直接在内层函数中使用this指针,无需预保存this对象,具体可以看我的这篇文章


var myObject = {
    foo: "bar",
    func: function() {
        var self = this;
        console.log(this.foo);   
        console.log(self.foo);   
        (function() {
            console.log(this.foo);   
            console.log(self.foo);   
        }());
    }
};
myObject.func();

把这题做对了,我就又是最靓的仔了!<( ̄︶ ̄)↗[GO!]

判断this指向的小技巧:

- 哪个对象拥有了这个函数,this就是这个对象的指代

程序的最后,运行的是myObject对象下的func方法,也就是myObject.func();,说明在func作用域下,this指代的是myObject对象

- 匿名函数的执行环境具有全局性
匿名函数里的this一般指向window

有了这两个知识点,我们就可以来做这道题了

var myObject = {
    foo: "bar",
    func: function() {
        var self = this; 
        // 此处的this指的是myObject,而self则保存了这this指向
        // 后续出现self,我们就知道,只是是指myObject
        console.log(this.foo);   // this指的是myObject,输出"bar"
        console.log(self.foo);   // self指的是myObject,输出"bar"
        (function() {			// 匿名函数,this指向window对象
            console.log(this.foo);   // this指的是window,输出undefined
            console.log(self.foo);   // self指的是myObject,输出"bar"
        }());
    }
};
myObject.func();

答案:C

2.prototype和__proto__

这个知识点,貌似比较深奥,也比较有争议。看了评论区各位大佬和网络的解答,觉得本人目前还没有能力理解透彻

此处贴上某位大佬的一个解答,建议点开详情看评论回复,here
还有一位大佬的良心解答,应该是比较完善的:here
呜呜呜,太强了,忍不住崇拜一下

在这里插入图片描述
大佬在最后贴心地总结了一下,截图如下:
在这里插入图片描述
式子再写一遍:

回到题目
在这里插入图片描述


这个知识点比较重要,所以把遇到的题都整理出来,便于加深理解

3.call与apply对比

看起来有点绕,别担心,绕着绕着就出去了??仔细看题就好~
前面已经讲到,在ES5语法中,this指向的判断规则是:哪个对象拥有了这个函数,this就指向这个对象
而call和apply就是用于:改变this指向为自己特定的对象,并且这两个方法是非继承而来的(Function.prototype.call()和Function.prototype.apply()),每个函数都包含这两个方法,这是两个方法的基本概念~

apply语法:fun.apply([thisObj [,argArray] ]);
call语法:fun.call([thisObj[,arg1 [,arg2 [,...,argn]]]]);

使用了apply和call之后,this指向了thisObj,即第一个参数均是要特定的this对象,是传入给当前函数(对象)的对象
apply的第二个参数是一个数组,call则是一个个列出参数的

在这里插入图片描述
这是官方给出的两者区别~

到此,我们已经可以解题了,答案选C,apply和call接收不同的参数在于后面的参数,apply接收数组,call逐个接收;第一个参数的用法是一致的,都是this指向


var obj = {};
obj.log = console.log;
obj.log.call(console,this);

分析:

  • 将console.log的功能复制给obj.log,因此后者功能也是输出;

  • call将log方法的执行权给了window.console,要求它输出this,所以绕了个弯,求的是

    console.log(this); // 输出window对象

答案:B
评论区有大佬提到了严格模式,放上官网链接:here

4.强制转换、隐式转换

4.1 双等号==

题解中还有其他宝藏信息,整理如下~ ヾ(ω`)o:

4.2 Boolean类型转换

在这里插入图片描述

4.3 加号与减号

4.4 API强制类型转换

4.5 new String 与 ’ ’

5.API使用

5.1 map函数

以下代码执行后,array的结果是?

let array = [,1,,2,,3];
array = array.map((i)=>++i);

5.2 parseInt函数

第4点的那道题的题解中,有网友给出了parseInt函数的其他常考考点,此处截图出来:

在这里插入图片描述
其中提到的易考点:parseInt函数的第二个参数——数组的下标,经典题如下:

var arr = [1,2,3,2,5];
console.log(arr.map(parseInt));// [1, NaN, NaN, 2, NaN]

parseInt函数有三个参数,分别是:数组元素、该元素下标、数组本身
因此,这个过程其实是这样的:

arr.map( (i)=>parseInt(arr[i], i, arr) );
/*
计算过程如下,第三个参数是数组本身,此处省略不写:
parseInt(1,0) —— 十进制,1在0-9之间,输出1
parseInt(2,1) —— 进制小于2,返回NaN
parseInt(3,2) —— 二进制,但3不在0-1之间,输出NaN
parseInt(2,3) —— 三进制,2在0-2之间,输出2
parseInt(5,4) —— 四进制,5不在0-3之间,输出NaN
最终结果为:[1, NaN, NaN, 2, NaN]
*/

6. 立即执行函数

题目给的代码看起来不太方便,于是我把它们放到编辑器里,帮助看清括号的归属。
typeof是可以不需要括号的,就像这样:

在这里插入图片描述

题目里紧挨着typeof的括号应该是用于构成后面的立即执行函数的,因此,我把代码的排版改成这样:

output( typeof 
    (
    function() {
	output("Hello World!")
	}
    )()
);

答案:E

7. ES5的变量提升

(function() {

    var x=foo();

    var foo=function foo() {
        return "foobar"
    };
    return x;
})();

单选题2:写出下面代码的运行结果

var a,b;
(function(){
    alert(a);
    alert(b);
    var a=b=3;
    alert(a);
    alert(b);
})();
alert(a);
alert(b);
var a,b;
(function(){
	var a;
    alert(a); // 此处的a是局部变量a,未初始化,为undefined
    alert(b); // 此处的b是全局变量b,未初始化,为undefined
    a=b=3; // 全局b=3,局部a=3
    alert(a); // 输出3
    alert(b); // 输出3
})();
alert(a); // 全局a,为undefined
alert(b); // 全局b,为3

因此,答案选A

8.JS对象转基本类型

9.W3C标准盒模型



<style>
	#container {
		width: 200px;
		height: 200px;
		padding: 20px;
		margin: 20px;
		border: solide 10px black;
	}
</style>

<div id="container">content</div>

官网链接:here
因此,本题中的container.clientWidth = width + padding * 2 = 200 + 20 * 2 = 240

答案:B


10.其他

刷题的时候出现频率不那么高,但觉得很有必要学习和拓展的知识点,暂时放在”其他“中

10.1 margin塌陷问题

<div style="width: 100px; height: 100px; margin-bottom: 100px;"></div>
<div style="width: 100px; height: 100px; margin-top: 200px;"></div>

10.2 promise的all方法

10.3 浏览器渲染流程与页面加载过程


10.4 HTML语义化

10.5 position定位

10.6 回流和重绘

var obj = document.getElementById("test");

导致重绘Repaint的原因:

可能导致发生回流的情况(此处仅列出几个,具体请看文章):

  • 改变窗囗大小
  • 改变文字大小
  • 内容的改变,如用户在输入框中敲字
  • 操作class属性——比如,动态设置active,打开/ 关闭某个折叠目录
  • 脚本操作DOM——比如增加/删除某些DOM元素,导致整体的大小发生变化
  • 计算offsetWidth和offsetHeight ——虽然只是计算,但浏览器为了保证值的正确也会回流取得最新的值

因此,答案选择BC选项;D选项只会导致重绘,不满足题意

10.7 CSS的引入

<!--页面中使用CSS的方式主要有3种:
1.行内添加定义style属性值,
2.页面头部内嵌调用
3.外面链接调用,
其中外面引用有两种:link和@import。外部引用CSS两种方式link和@import的方式分别是:-->
<!--1、链接式  这个知识点也考过-->
<link type="text/css" rel="styleSheet"  href="CSS文件路径" />

<!--2、导入式-->
<style type="text/css">
  @import url("css文件路径");
</style>


/* @import最优写法:
@import的写法一般有下列几种:*/

@import 'style.css' //Windows IE4/ NS4, Mac OS X IE5, Macintosh IE4/IE5/NS4不识别
@import "style.css" //Windows IE4/ NS4, Macintosh IE4/NS4不识别
@import url(style.css) //Windows NS4, Macintosh NS4不识别
@import url('style.css') //Windows NS4, Mac OS X IE5, Macintosh IE4/IE5/NS4不识别
@import url("style.css") //Windows NS4, Macintosh NS4不识别

/* 由上分析知道,
@import url(style.css) 和@import url("style.css")是最优的选择,兼容的浏览器最多。
从字节优化的角度来看@import url(style.css)最值得推荐 */

10.8 Javascript的引入

10.9 Javascript相关概念

10.10 a标签——链接

另一位答友给出了自创的记忆口诀:驴哈(LVHA),哈哈哈哈,这口诀太6了,获得评论区一致好评 (o゜▽゜)o☆

答案:C

10.11 定义函数

10.12 for循环条件表达式和遍历

var k = 0;
for(var i=0,j=0; i<10,j<6; i++,j++){
    k += i + j;
}
console.log(k)

10.13 运算符优先级

A. Value is define
B. Value is undefine
C. define
D. undefine
E.Value is define 或者 Value is undefine
F.define 或者 undefine
G.其它选项都有可能

分析:

  • 三目运算符 truex:y,当问号前面的式子结果为true时,获得 / 执行x——冒号前的操作;否则获得 / 执行y——冒号后的操作
  • 加号"+“的优先级大于三目运算符”",因此,式子先执行" 'Value is ’ + (val != ‘0’)"
  • 只要不是空字符串,转换成boolean,均为true
  • 不论(val != ‘0’)的结果如何," 'Value is ’ + (val != ‘0’)“转为boolean都会是true,因此执行冒号前的操作,整个式子结果为"define”

答案:C

举报

相关推荐

0 条评论