JavaScript之旅(2) | 青训营

66 阅读3分钟

这是我参与「第四届青训营」笔记创作活动的的第5天

代码风格

嵌套层级

for (let i = 0; i < 10; i++) {
    if (cond) { 
        ... // <- 又一层嵌套 
    } 
}
for (let i = 0; i < 10; i++) { 
    if (!cond) *continue*; 
    ... // <- 没有额外的嵌套 
}

函数位置

先调用代码,再在末尾写函数

对象

对象创建

let user = new Object();  // “构造函数” 的语法 
let user = {};            // “字面量” 的语法

方括号

对于多词属性的定义和使用必须使用 [ ]
优势在于可以通过变量访问属性

let user = { name: "John", age: 30 }; 
let key = prompt("What do you want to know about the user?", "name"); 
// 访问变量 
alert( user[key] ); // John(如果输入 "name")

在方括号中可以使用更复杂的表达式

let fruit = 'apple'; 
let bag = { [fruit + 'Computers']: 5 // bag.appleComputers = 5 
};

"in"操作符

使用in可以检查一个对象是否有这个属性,就算属性是undefined

let obj = { test: undefined }; 
alert( obj.test ); // 显示 undefined,所以属性不存在? alert( "test" in obj ); // true,属性存在!

"for...in"循环

for (key in object) {
// 对此对象属性中的每个键执行的代码 
}

如果属性名有整数,则按整数排序,否则按照创建顺序来排序

普通克隆和合并

  1. 使用for in克隆
for (let key in user) { 
clone[key] = user[key]; 
}
  1. 使用Object.assign方法 Object.assign(dest, [src1, src2, src3...]) dest为目标对象,src为需要添加的对象,所有src的属性都会添加到dest
    调用返回的结果为dest,相同属性会覆盖

深度克隆

当对象中的某一个属性为对象时,在浅克隆的的时候,两个对象的属性中的对象还是为同一个对象(听起来有点绕)

let user = {
    name: "John", 
    sizes: { 
        height: 182,
        width: 50 
} 
}; 

let clone = Object.assign({}, user);

alert( user.sizes === clone.sizes ); // true,同一个对象 

// user 和 clone 分享同一个 sizes 
user.sizes.width++; // 通过其中一个改变属性值 alert(clone.sizes.width); // 51,能从另外一个获取到变更后的结果

所以需要深度克隆,使用拷贝循环来检查对象的属性是否为对象,如果是则继续拷贝。
可以使用lodash库的_.cloneDeep(obj)

垃圾回收

当一个对象没有指向,或者无法到达时,它会被js的垃圾回收器删除

this

在函数中使用this指向当前调用的对象, this的值实在代码运行时计算出出来的 ()=>{}箭头函数没有自己的this,使用后会指定外层非箭头函数的对象

可选链

在调用对象时,使用 ?. 的方式调用,会更安全,不会报错而是返回undefined

let user = {}; // user 没有 address 属性 
alert( user?.address?.street ); // undefined(不报错)
  1. 不要过度使用,会导致代码很难调试修复 user?.address?.street
  2. 使用 ?. 必须在已经声明的变量使用,不然会报错
  3. 短路效应user?.sayHi(x++); 当user不存在时,后面的代码是不会执行的
  4. 其他用法
userAdmin.admin?.();   // 函数调用
alert( user1?.[key] ); // 安全读取属性
delete user?.name;     // 安全删除 

symbol

表示唯一表示符

  1. 使用Symbol()来创建
  2. 每一个symbol都是唯一,尽管使用相同标签
let id1 = Symbol("id"); 
let id2 = Symbol("id"); 
alert(id1 == id2); // false
  1. 使用symbol创建的对象属性,会被隐藏起来 在for...in循环会被跳过 Object.keys(obj)会忽略 Object.assign会复制symbol属性
  2. 全局symbol 使用Symbol.for(key) 通过key读取一个symbol,如果不存在则创建,存在则两个symbol相同
  3. Symbol.keyFor 与for相反,读取一个symbol返回一个key
  4. 系统symbol