0%

分题型基础补全计划(三)—— JavaScript 篇

this 的指向问题

​ 作为一门一切皆为对象的语言,首先需要搞明白指针 this 的指向问题。以下为常见的两种指向情况:

作为构造函数调用

题型 1

1
2
3
4
5
6
7
8
9
var foo = "123";

function print() {
var foo = "456";
this.foo = "789";
console.log(foo);
}

print();

我的答案: 456

  • 通过 print () 函数,可以生成一个新对象。这时,this 就指这个新对象,this.foo 就作为这个新对象的成员

纯粹的函数调用

题型 2

1
2
3
4
5
6
7
8
9
10
11
var a = 5;

function test() {
a = 0;

alert(a);
alert(this.a);

var a;
alert(a);
}

我的答案: 弹出 0,5,0

  • 全局性调用,因此 this 就代表全局对象,this.a 则调用全局变量 a,故弹出结果为 5

其余详见:Javascript 的 this 用法 - 阮一峰的网络日志 (ruanyifeng.com),讲的很透彻

鼠标事件与键盘事件

题型:下列事件哪个不是由鼠标触发的事件()

A click

B contextmenu

C mouseout

D keydown

我的答案: D

鼠标事件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//1.鼠标点击左键触发
onclick
//2.鼠标经过触发
onmouseover
//3.鼠标离开触发
onmouseout
//4.获得鼠标焦点触发
onfocus
//5.失去鼠标触发
onblur
//6.鼠标移动触发
onmousemove
//7.鼠标弹起触发
onmouseup
//8.鼠标按下触发
onmousedown
//9.鼠标经过时触发,但是不会冒泡
onmouseenter
//10.鼠标离开时触发,但是不会冒泡
onmouseleave
鼠标事件对象
1
2
3
4
5
6
7
8
9
10
11
12
//1.返回鼠标相对于浏览器窗口可视区的X坐标
e.clientX
//2.返回鼠标相对于浏览器窗口可视区的Y坐标
e.clientY
//3.返回鼠标相对于文档页面的X坐标
e.pageX
//4.返回鼠标相对于文档页面的Y坐标
e.pageY
//5.返回鼠标相对于屏幕的X坐标
e.screenX
//6.返回鼠标相对于屏幕的Y坐标
e.screenY
* 禁用鼠标事件
1
2
3
4
5
6
7
8
//禁止鼠标右键菜单
document.addEventListener('contextmenu',function(e){
e.preventDefault();
})
//禁止鼠标选中
document.addEventListener('selectstart',function(e){
e.preventDefault();
})
键盘事件
1
2
3
4
5
6
//1.某个键盘按键被松开时触发
onkeyup
//2.某个键盘按键被按下时触发
onkeydown
//3.某个键盘被按下时触发,不识别功能键如ctrl、shift etc.
onkeypress

注:onkeypress 区分大小写,onkeydownonkeyup 不区分

作用域问题

题型:

<ul>

<li>click me</li>

<li>click me</li>

<li>click me</li>

<li>click me</li>

</ul>

运行如下代码:

1
2
3
4
5
6
7
var elements = document.getElementsByTagName("li");
var length = elements.length;
for (var i = 0; i < length; i++) {
elements[i].onclick = function () {
alert(i);
};
}

依次点击 4 个 li 标签,哪一个选项是正确的运行结果()

A 依次弹出 1, 2, 3, 4

B 依次弹出 0, 1, 2, 3

C 依次弹出 3, 3, 3, 3

D 依次弹出 4, 4, 4, 4

我的答案: D

  • 在《JavaScript 高级程序设计》有如下解释

    • 这是由于作用域链的这种配置机制引出的一个副作用,即闭包只能取得包含函数中任何变量的最后一个值。闭包所保存的是整个变量对象,而不是某个特殊的变量。
  • 回归具体问题,这里 alert (i) 中绑定的 i 实际上不是 i 的值,而是 i 本身。当循环结束后,因此执行 onclick 事件、执行 alert () 时,本身 onclick 绑定的 function 的作用域中没有变量 i,i 为 w 未定义的 (undefined),则解析引擎会寻找父级作用域,发现父级作用域中有 i,则取得的 i 对应值始终为 4。

如何解决?
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
//1、利用块级域
for(var i=0; i < 10; i++) {
setTimeout(function() {
console.log(i);
}, 1000);
}
//2、利用自执行函数传参
for(var i=0; i < 10; i++) {
(function(i) {
setTimeout(function() {
console.log(i);
}, 1000);
})(i);
}
//3、利用设置延时的第三个参数传递
for(var i=0; i < 10; i++) {
setTimeout(function(j) {
console.log(j);
}, 1000, i);
}
//4、利用promise
for(var i=0; i < 10; i++) {
new Promise((resolve, reject) => {
var j = i;
setTimeout(function() {
console.log(j)
}, 1000);
})
}
//5、利用async函数
async function foo() {
for(var i=0; i < 10; i++) {
let result = await new Promise((resolve, reject) => {
setTimeout(function() {
resolve(i);
}, 1000); // 每隔1s打印数字 0 - 9
});
console.log(result);
}
}
foo();

js 中的原始类型

题型:关于 javascript 的原始类型(primitive type),错误的是

A 有 5 种 primitive type,分别是 Undefined、Null、Boolean、Number 和 String。

B var sTemp = “test string”;alert (typeof sTemp); 结果为 string

C var oTemp;alert (oTemp == undefined) 为 true

D alert (null == undefined); 结果为 false

我的答案: D

六大原始类型
  • 数字类型 number

  • 字符串类型 string

  • 布尔类型 boolean

  • 空值 null

  • 未定义 undefined

  • 独一无二类型 (ES6 新增) symbol:引入以防止属性名的冲突

注:其他类型均为引用类型(Object)

最大值的求法

题型:下面求 a 中最大值正确的是 ()

A Math.max(a)

B Array.max(a)

C Math.max.call(null,a)

D Math.max.apply(null,a)

我的答案: D

Math.max
返回一组数中的最大值
Math.max.apply

​ 返回一个对象(如:数组)中的最大值

* 标准事件模型 IE9+

题型:w3c 制定的 javascript 标准事件模型,以下正确的顺序以及描述是?

A 事件捕获 > 事件冒泡

B 事件捕获 -> 事件处理 -> 事件冒泡

C 事件冒泡 -> 事件处理

D 事件处理 -> 事件捕获 -> 事件冒泡

我的答案: B

异步执行调用

题型:以下语句的执行结果是什么?

1
2
3
4
5
6
7
8
9
console.log("one");

setTimeout(function () {
console.log("two");
}, 0);

console.log("three");

console.log("four");

我的答案: “one” “three” “four” “two”

  • 这是由于 setTimeout () 方法是异步执行的。当调用该方法时,会把函数参数与函数体中的内容放入消息队列,直到当前主程序执行完成后,再予以调用

浮点数运算问题

题型:写一个求和的函数 sum,达到下面的效果

1
2
3
4
5
6
7
8
// Should equal 15
sum(1, 2, 3, 4, 5);
// Should equal 0
sum(5, null, -5);
// Should equal 10
sum('1.0', false, 1, true, 1, 'A', 1, 'B', 1, 'C', 1, 'D', 1, 'E', 1, 'F', 1, 'G', 1);
// Should equal 0.3, not 0.30000000000000004
sum(0.1, 0.2);

我的答案:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function sum() {

var add = 0;

for (var i = 0; i < arguments.length; i++) {

if (!(typeof arguments[i] == "boolean")) {

if (!isNaN(arguments[i])) {

add += Number(arguments[i]);

}

}

}

alert(Math.round(add * 10) / 10);

}
  • 为什么 1+2≠3?因为 js 采用的是 IEEE754 标准处理浮点数,视作双精度数,结果为结果是 0.30000000000000004(计组内容)