思维导图
通过下面的思维导图,我们先对JavaScript的对象有一些基本的了解。
下文记录一些以前不了解的知识点。
知识点
in操作符判断属性是否存在
除了直接访问属性,查看器是否存在,我们还可以用in
操作符来判断。
let user = { name: "John", age: 30 };
alert( "age" in user ); // true,user.age 存在
alert( "blabla" in user ); // false,user.blabla 不存在。
for-in
可以遍历对象,但不推荐使用
不推荐使用是因为,如果用法不正确,eslint
检查会报错。
eslint
有一条guard-for-in
规则,这条规则要求for-in
语句要包含一个if
判断来判断object
的key
是否存在,以避免一些意外的错误。
此规则的错误代码示例:
代码语言:javascript复制/*eslint guard-for-in: "error"*/
for (key in foo) {
doSomething(key);
}
复制代码
此规则的正确代码示例:
代码语言:javascript复制/*eslint guard-for-in: "error"*/
for (key in foo) {
if (Object.prototype.hasOwnProperty.call(foo, key)) {
doSomething(key);
}
}
for (key in foo) {
if ({}.hasOwnProperty.call(foo, key)) {
doSomething(key);
}
}
复制代码
当然除了加判断,也可以直接改用Object.keys
和forEach
。
currentValues= {hey:1212, git:1212, nmo:12121}
Object.keys(currentValues).forEach(function(key) {
yield put(setCurrentValue(key, currentValues[key]));
})
对象的顺序
整数属性会被进行排序。
代码语言:javascript复制let codes = {
"49": "Germany",
"41": "Switzerland",
"44": "Great Britain",
// ..,
"1": "USA"
};
for(let code in codes) {
alert(code); // 1, 41, 44, 49
}
其他属性则按照创建的顺序显示。
代码语言:javascript复制let user = {
name: "John",
surname: "Smith"
};
user.age = 25; // 增加一个
// 非整数属性是按照创建的顺序来排列的
for (let prop in user) {
alert( prop ); // name, surname, age
}
浅复制与深复制
Object.assign
用于浅复制和合并。
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)用于深复制。
代码语言:javascript复制var objects = [{ 'a': 1 }, { 'b': 2 }];
var deep = _.cloneDeep(objects);
console.log(deep[0] === objects[0]);
// => false
执行上下文this
推荐技术蛋老师的这两个视频:
函数作用域
this关键字
判断函数是否由new操作符生成
ES6,用new.target。
代码语言:javascript复制function User() {
alert(new.target);
}
// 不带 "new":
User(); // undefined
// 带 "new":
new User(); // function User { ... }
ES5,有另一种判断方法是this instanceof User
(如果读过vue2的源码,这个操作会有点印象,vue开始的地方