本系列是《你不知道的 JS》第二版的读书笔记,本笔记属于 Get Started 一书的第三章,书籍传送门:click me
我们经常使用 spread 操作符(...),比如在进行数组浅拷贝的时候:a = [...[1, 2, 3]]; spread 操作符的作用是 consuming iterators,也就是只要是个 iterator ,就可以使用这个操作符。for...of 也是用来遍历 iterator 的。
除了数组外,常见的可以生成 iterator 的还有 Map、Set、 String。
const map = new Map();
map.set('a', 1);
map.set('b', 2);
for (let [key, value] of map) {
console.log(`${key}: ${value}`)
} // a: 1 b: 2
const str = 'hello world';
console.log([...str]);
// ["h", "e", "l", "l", "o", " ", "w", "o", "r", "l", "d"]
const set = new Set();
set.add(1);
set.add(2);
for (let value of set) {
console.log(value)
} // 1 2
另外,经过一些扩展,我们还可以在对象中使用它:
const iteratorObj = {
a: 1,
b: 2,
c: 3,
[Symbol.iterator]() {
const keys = Object.keys(obj);
const len = keys.length;
let step = 0;
const iterator = {
next() {
if (len === 0) {
return { value: undefined, done: true };
} else if (step === len) {
return { value: obj[keys[len - 1]], done: true };
}
return { value: obj[keys[step++]], done: false };
}
};
return iterator;
}
};
for (let v of iteratorObj) {
console.log(v) // 1, 2, 3
}
console.log(...iterator) // 1, 2, 3
面试中,老是被问闭包是什么,现在有标准答案了:
Closure is when a function remembers and continues to access variables from outside its scope, even when the function is executed in a different scope.
When a function makes reference to variables from an outer scope, and that function is passed around as a value and executed in other scopes, it maintains access to its original scope variables; this is closure.
闭包是一个函数,尽管它不在当前作用域执行,依然可以继续访问在它作用域外部的变量。另外还有一点值得主要:闭包的外围不一定只是函数,还可能是 for 循环。
JS 中的 this 功能非常强大,但又非常令人困扰,很多人理解 this 是指向函数本身、指向实例,这都是不对的。this 是动态的,最好被定义为指向执行上下文(excution context)。
Object.create(null) 创建了一个没有原型链的对象(standalone object),某些时候很有用。
关于 this,还有一个很令我困惑的示例:
var homework = {
topic: 'CSS',
study() {
console.log(`Please study ${ this.topic }`);
}
};
var jsHomework = Object.create(homework);
jsHomework.topic = "JS";
jsHomework.study();
你猜最后一行输出什么?
Please study JS
没有输出 CSS 会不会让你感觉比较奇怪?事实上,尽管我们通过原型链调用的 study 方法委托到父类身上,但是 this 却指向被保留了下来。(method calls on objects which delegate through the prototype chain still maintain the expected this)。
对比而言,Java 就不会了,这算是 JS 的一个特色:
// Homework.java
public class Homework {
public String topic = "Maven";
public void study() {
System.out.println("Please study " + this.topic);
}
}
// JSHomework.java
public class JSHomework extends Homework {
public String topic = "Java";
public static void main(String[] args) {
JSHomework jsHomework = new JSHomework();
jsHomework.study();
}
}
// Please study Maven
以上就是本节笔记的全部内容。