备战校招第十一天

  • Object.keysfor...in 区别

  • 异步编程的几种方式

  • load 事件 和 DOMContentLoaded 事件区别

  • 箭头函数

  • for...offor...in


Object.keysfor...in 区别

Object.keys 不能遍历原型上的属性

for...in 可遍历原型链上的可枚举属性

1
2
3
4
5
6
7
8
9
10
11
12
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.hobbies = ["eat"];
let p = new Person();
// 不遍历原型上的属性
console.log(Object.keys(p)); // [ 'name', 'age' ]
// 可遍历原型链上的可枚举属性
for (let item in p) {
console.log(item); // name age hobbies
}

异步编程的几种方式

回调函数

比如:setTimeout、setInterval等

1
2
3
setTimeout(function() {
console.log('cb')
}, 1000)

事件监听

在dom中常用的 addEventListener

1
2
3
4
var btn = document.getElementById('btn')
btn.addEventListener(function() {
console.log('btn 被点击')
})

Promise

ES6 中新增特性,详情

1
2
3
4
5
6
7
8
9
10
11
12
13
function delay(ms = 0) {
return new Promise(function (resolve, reject) {
setTimeout(function () {
resolve()
}, ms)
})
}

console.log(1)
delay(1000).then(function() {
console.log(3)
})
console.log(2)

Generator

async/await

promise 的语法糖,将 promise 的代码稍作修改,得到以下代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function delay(ms = 0) {
return new Promise(function (resolve, reject) {
setTimeout(function () {
resolve()
}, ms)
})
}

async function callBack() {
let res = await delay(1000)
console.log(3)
}

console.log(1)
callBack()
console.log(2)

发布订阅

load 事件 和 DOMContentLoaded 事件区别

load 事件

下面代码具有相同含义,只是写法不同,具体查看文章,备战校招第九天 - DOM事件类 - DOM事件级别

1
2
3
4
5
6
7
8
window.addEventListener('load', (event) => {
console.log('page is fully loaded');
});

// 大家可能更熟这种写法
window.onload = function() {
console.log('page is fully loaded');
}

当整个页面所依赖的资源(样式表、图片、子框架等)加载完毕触发 load 事件。

DOMContentLoaded 事件

1
2
3
window.addEventListener("DOMContentLoaded", function() {
console.log(`window.addEventListener("DOMContentLoaded") 事件`);
})

当初始的HTML文档完全加载和解析完成,无需等待图片等资源加载完毕,就可以触发 DOMContetnLoaded 事件。注意:**DOMContentLoaded** 事件必须等待其所属script之前的样式表加载解析完成才会触发。

顺序

  • DOMContentLoaded 优先执行
  • load ,而load事件中的 window.onloadwindow.addEventListener("load") 两种写法,则是代码中哪个靠前,哪个先执行(按照顺序执行)

箭头函数

箭头函数相比函数表达式更加简洁,并且没有自己的thisconstructorargumentssupernew.target。主要适用在一些需要匿名函数的地方,且不需要用到构造函数。

写法简洁

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 1. 简单写法
var a = () => {
console.log("arrow function");
};

// 2. 如果只需要一个参数,则可以省略圆括号
var b = (arg1) => {
return arg1 + 1;
};

// 3. 若函数体内只有一句代码,还可以省略花括号
var c = (arg1, arg2) => arg1 + arg2;

// 剩下的都是按照这几种进行组合的方式,聪明的你一定知道如何做,想确定自己的想法,可以去参考下阮一峰老师的ES6入门书,链接在文章末尾

// 如若需要一行代码返回对象,需要用圆括号包起来,防止产生歧义致使没有产生理想的结果
var d = () => ({a: 1})

注意事项

  1. 没有自己的 this 指向,但在定义时就确定了this指向,而function 只有在运行时才会确定this指向。
  2. 如果使用 call、apply、bind 调用,只能传递参数,第一个参数this则会忽略。
  3. 没有构造函数,所以不能使用 new 来创建实例,否则会抛出一个异常(提示没有构造函数)。
  4. 没有 prototype 属性。
  5. 不可以使用yield命令,因此箭头函数不能用作 Generator 函数。
  6. 没有 arguements 对象,可以用 es6 rest参数 代替。

for...offor...in

for…of

  • 可迭代数组、类数组、String、Map、Set、arguements、DOM 集合等

  • 如果数组过大,执行效率低于传统for循环(for(let i=0; i<arr.length; i++))

  • 不会迭代原型上的属性。

  • 遍历对象需要可以和 Object.entries()结合使用。

1
2
3
4
5
6
7
8
9
10
const obj = {
a: 1,
b: 22,
c: 3,
d: 44,
};
for (const [key, value] of Object.entries(obj)) {
console.log("key :>> ", key);
console.log("value :>> ", value);
}

for…in

for...in语句以任意顺序遍历一个对象的除Symbol以外的可枚举属性。for…in迭代是无序的。

提示:for...in不应该用于迭代一个 Array,其中索引顺序很重要。

注意

  • for..in 会迭代原型上的可迭代属性,如若只需迭代自身属性,可以使用 getOwnPropertyNames()hasOwnProperty() 来确定属性是否为自身的属性。
  • 如果使用 for...in 迭代数组,效率远低于 for...of

两者区别

无论是for...in还是for...of语句都是迭代一些东西。它们之间的主要区别在于它们的迭代方式。

for...in 语句以任意顺序迭代对象的可枚举属性

for...of 语句遍历可迭代对象定义要迭代的数据。

参考

阮一峰老师的ES6入门