JS
1 var let const 區(qū)別
變量提升和暫時(shí)性死區(qū)
console.log(a); // undefined
var a = 10;
console.log(b); // ReferenceError
let b = 20;
console.log(c); // ReferenceError
const c = 30;
作用域
var // 全局作用域 函數(shù)作用域
let // 塊級(jí)作用域
const // 塊級(jí)作用域
重復(fù)聲明
var a = 10;
var a = 20; // 20
let b = 10;
let b = 20; // SyntaxError
const c = 10;
const c = 20; // SyntaxError
2 es6 數(shù)組的擴(kuò)展
將其他數(shù)據(jù)結(jié)構(gòu)轉(zhuǎn)成真正的數(shù)組
let set = new Set([1, 2, 2, 3]);
let arr = [...set]; // [1, 2, 3]
Array.from()將類(lèi)數(shù)組和可遍歷對(duì)象轉(zhuǎn)成數(shù)組
let arrayLike = {
'0': 1,
'1': 2,
'2': 3,
length: 3,
};
Array.from(arrayLike, x => x * x); // [1, 4, 9]
Array.prototype.flat()
[1, [2, [3, 4], 5], 6].flat() // [1, 2, [3, 4], 5, 6]
[1, [2, [3, 4], 5], 6].flat(2) // [1, 2, 3, 4, 5, 6]
Array.prototype.flatMap()相當(dāng)于先map后flat
[1, 2, 3].flatMap(x => [x, x * 2]) // [1, 2, 2, 4, 3, 6]
3 es6 對(duì)象的擴(kuò)展
Object.setPrototypeOf()和super
const a = {name: 'wqd'};
const b = {
getName() {
return super.name;
}
};
Object.setPrototypeOf(b, a); // 設(shè)置a為b的原型對(duì)象
b.getName(); // 'wqd'
對(duì)象屬性的遍歷
| 方法名 | 適用范圍 |
|---|---|
| for in | 自身和繼承的可枚舉屬性(非Symbol) |
| Object.keys() | 自身的可枚舉屬性(非Symbol) |
| Object.getOwnPropertyNames() | 自身的(含不可枚舉)(非Symbol) |
| Object.getOwnPropertySymbols() | 自身Symbol |
| Reflect.ownKeys() | 自身(含Symbol)(含不可枚舉) |
Object.is()
Object.is(+0, -0) // false
Object.is(NaN, NaN) // true
4 Promise
三種狀態(tài)
pendingfulfilledrejected
方法
Promise.all()
Promise.race()
Promise.allSettled()
Promise.resolve()
Promise.reject()
5 Generator
next方法的參數(shù)會(huì)作為上一個(gè)yield的返回值
function* foo(x) {
var y = 2 * (yield(x + 1));
var z = yield(y / 3);
return x + y + z;
}
var x = foo(5);
x.next(); // {value: 6, done: false}
x.next(12); // {value: 8, done: false}
x.next(13); // {value: 42, done: true}
通過(guò)添加
Generator函數(shù)使普通對(duì)象可遍歷
function* f(obj) {
let x = Reflect.ownKeys(obj);
for (let i of x) {
yield [i, obj[i]];
}
}
const obj = {name: 'wqd', year: 1996};
for (let [key, value] of f(obj)) {
console.log(`${key}: ${value}`);
}
// name: wqd
// year: 1996
6 異步解決方案
| 方法 | 分析 |
|---|---|
| 回調(diào)函數(shù) | 回調(diào)地獄 |
| Promise | 鏈?zhǔn)秸{(diào)用但代碼不簡(jiǎn)潔語(yǔ)義化不強(qiáng) |
| Generator | 將異步代碼以同步的形式進(jìn)行編寫(xiě) |
| async/await | 簡(jiǎn)潔語(yǔ)義化強(qiáng) |
7 Proxy 代理
get()
function createArray(...elements) {
let handler = {
get(target, propKey, receiver) {
let index = Number(propKey);
if (index < 0) {
propKey = String(target.length + index);
}
return Reflect.get(target, propKey, receiver);
}
};
let target = [];
target.push(...elements);
return new Proxy(target, handler);
}
let arr = createArray('a', 'b', 'c');
console.log(arr[-1]); // 'c'
set()
let validator = {
set(obj, prop, value) {
if (prop === 'age') {
if (!Number.isInteger(value)) {
throw new TypeError('不是數(shù)字');
}
if (value > 200) {
throw new RangeError('超出范圍');
}
}
obj[prop] = value;
}
};
let person = new Proxy({}, validator);
person.age = 100;
console.log(person.age); // 100
person.age = 'wqd'; // TypeError
person.age = 300; // RangeError
8 Module
導(dǎo)入導(dǎo)出復(fù)合寫(xiě)法
export { foo, bar } from 'module'
// 等同于
import { foo, bar } from 'module'
export { foo, bar }
9 數(shù)組方法
| 修改原數(shù)組 | 不修改原數(shù)組 |
|---|---|
push unshift splice pop shift
|
concat slice some every forEach filter map
|
10 深淺拷貝
淺拷貝
function shallowClone(obj) {
const newObj = {};
for(let prop in obj) {
if(obj.hasOwnProperty(prop)) {
newObj[prop] = obj[prop];
}
}
return newObj;
}
深拷貝
JSON.stringify()會(huì)忽略undefinedSymbolfunction
const obj = {
a: "A",
b: undefined,
c: function() {},
d: Symbol("A"),
};
const newObj = JSON.parse(JSON.stringify(obj));
console.log(newObj); // {a: 'A'}
11 原型和原型鏈
function Person(name) {
this.name = name;
this.age = 18;
this.sayName = function() {
console.log(this.name);
}
}
const person = new Person("person");
// true
person.__proto__ === Person.prototype
Person.__proto__ === Function.prototype
Person.prototype.__proto__ === Object.prototype
Object.__proto__ === Function.prototype
Object.prototype.__proto__ === null
Function.__proto__ === Function.prototype
12 實(shí)現(xiàn)繼承的方式
原型鏈繼承
function Parent() {
this.name = "a";
this.arr = [1, 2, 3];
}
function Child() {
this.type = "b";
}
Child.prototype = new Parent();
// 潛在問(wèn)題
let a = new Child();
let b = new Child();
a.arr.push(4);
console.log(a.arr, b.arr); // 同為 [1, 2, 3, 4]
構(gòu)造函數(shù)繼承 只繼承父類(lèi)的實(shí)例屬性和方法
function Parent() {
this.name = "a";
}
Parent.prototype.getName = function () {
return this.name;
}
function Child() {
Parent.call(this);
this.type = "b";
}
let child = new Child();
console.log(child); // {name: 'a', type: 'b'}
console.log(child.getName()); // TypeError
組合繼承 重復(fù)執(zhí)行會(huì)有額外性能開(kāi)銷(xiāo)
function Parent() {
this.name = "a";
this.arr = [1, 2, 3];
}
Parent.prototype.getName = function () {
return this.name;
}
function Child() {
Parent.call(this);
this.type = "b";
}
Child.prototype = new Parent();
Child.prototype.constructor = Child;
let a = new Child();
let b = new Child();
a.arr.push(4);
console.log(a.arr, b.arr); // [1, 2, 3, 4] [1, 2, 3]
console.log(a.getName(), b.getName()); // "a" "a"
原型式繼承 淺拷貝
let parent = {
name: "a",
arr: [1, 2, 3],
getName: function () {
return this.name;
}
};
let person = Object.create(parent);
寄生式繼承
let parent = {
name: "a",
arr: [1, 2, 3],
getName: function () {
return this.name;
}
};
function clone(obj) {
let clone = Object.create(obj);
clone.getArr = function () {
return this.arr;
};
return clone;
}
let person = clone(parent);
寄生組合式繼承
function clone(parent, child) {
child.prototype = Object.create(parent.prototype);
child.prototype.constructor = child;
}
function Parent() {
this.name = "a";
this.arr = [1, 2, 3];
}
Parent.prototype.getName = function () {
return this.name;
}
function Child() {
Parent.call(this);
this.type = "b";
}
clone(Parent, Child);
Child.prototype.getType = function () {
return this.type;
}
let person = new Child();
13 this綁定規(guī)則 優(yōu)先級(jí)從高到低
new綁定 顯式綁定 隱式綁定 默認(rèn)綁定