基础回顾(四)
对象复制的方法
// 浅拷贝
const obj = { a: 1 };
const copyObj = Object.assign({}, obj);
// 问题1 => 不能复制原型链上和不可枚举的属性
const obj1 = Object.create({ value: 1}, {
bar: {
value: 2
},
baz: {
value: 3,
enumerable: true
}
});
const copyObj1 = Object.assign({}, obj1);
console.log(copyObj1) // { baz: 3 }
// 解决1 => 使用
const copyObj_1 = Object.create(
Object.getPrototypeOf(obj1),
Object.getOwnPropertyDescriptors(obj1)
)
console.log(copyObj_1) // {bar: 2, baz: 3}
// 问题2 => 如果原数组的属性值还是一个对象引用,会指向该引用
const obj2 = { a: { b: 1 } }
const copyObj2 = Object.assign({}, obj2);
obj2.a.b = 2;
console.log(copyObj2); // { a: { b: 2 }}
// 解决2 => 深拷贝
const copyObj3 = JSON.parse(JSON.stringify(obj2));
obj2.a.b = 3;
console.log(copyObj3); // { a: { b: 2 }}
for…in, for…of, forEach之间的区别
// 遍历对象中可枚举的属性,也包括继承来的可枚举的属性
// 可以是类数组对象或者是对象字面量,但不能是Set,Map对象
for (let prop in ['a', 'b', 'c'])
console.log(prop); // 0, 1, 2 (array indexes)
for (let prop in 'str')
console.log(prop); // 0, 1, 2 (string indexes)
for (let prop in {a: 1, b: 2, c: 3})
console.log(prop); // a, b, c (object property names)
for (let prop in new Set(['a', 'b', 'a', 'd']))
console.log(prop); // undefined => 属性值不可枚举
// 遍历对象中的属性值
// 可以是数组,字符串,Set,Map对象,但不能是对象字面量
for (let val of ['a', 'b', 'c'])
console.log(val); // a, b, c (array values)
for (let val of 'str')
console.log(val); // s, t, r (string characters)
for (let val of {a: 1, b: 2, c: 3})
console.log(prop); // TypeError (not iterable)
for (let val of new Set(['a', 'b', 'a', 'd']))
console.log(val); // a, b, d (Set values)
// forEach是Array原型上的方法
// 遍历数组中的元素,可以同时迭代数组对象的索引和属性值
['a', 'b', 'c'].forEach(
val => console.log(val) // a, b, c (array values)
);
['a', 'b', 'c'].forEach(
(val, i) => console.log(i) // 0, 1, 2 (array indexes)
);
计算字符串宽度的方法
function mesure(str, font = getComputedStyle(document.documentElement).font) {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
ctx.font = font;
return ctx.measureText(str).width;
}
扁平数组和树形结构的相互转换
手写一个promise
// 函数版
// 状态改变前的状态
this.status = "pending";
// 状态为resolved时
this.value = undefined;
// 状态为rejected时
this.reason = undefined;
function myPromise(executor) {
const resolve = value => {
if (this.status === "pending") {
this.value = value;
this.status = "resolved";
}
}
const reject = reason => {
if(this.status === "pending") {
this.reason = reason;
this.status = "rejected";
}
}
try {
executor(resolve, reject);
} catch (err) {
reject(err)
}
}
myPromise.prototype.then = (onFulfilled, onRejected) => {
switch(this.status) {
case "resolved":
onFulfilled(this.value);
break;
case "rejected":
onRejected(this.reason);
break;
default:
}
}