基础回顾(四)

Author Avatar
Silas Shen 3月 01, 2020

对象复制的方法

// 浅拷贝
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:
    }
  }