一般方法:(能/不能)能获取不可枚举属性,(能/不能)能获取symbol属性、(能/不能)获取原型链属性
<!DOCTYPE html>
<html lang="zh">
<script>
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
/**
* 注意ES6的class语法
* 方法都是不可枚举的
* 等价于
Object.defineProperty(Person.prototype, 'toString', {
configurable:true,
writable:true,
value() {
return '[object Person]';
},
});
*/
toString() {
return '[object Person]';
}
}
console.log(Object.getOwnPropertyDescriptor(Person.prototype, 'toString')); // configurable:true,writable:true,enumerable:false,
Person.prototype.toString2 = Person.prototype.toString;
const person = new Person('小白', 18);
Object.defineProperty(person, 'brief', {
value: 'hello',
});
const hiSymbol = Symbol('hi');
person[hiSymbol] = 'hi';
/**
* for...in...
* 1、只能获取可枚举属性
* 2、可以获取原型链上的属性
* 3、不能获取Symbol属性
*/
(function () {
const properties = [];
for (let i in person) {
properties.push(i);
}
console.log(properties); // ["name", "age", "toString2"] 原型链上的 toString2 也被遍历出来了
})();
/**
* Object.keys()
* 1、只能获取可枚举属性
* 2、只获取自身属性,不获取原型链的属性
* 3、不能获取Symbol属性
*/
(function () {
console.log(Object.keys(person)); // ["name", "age"]
})();
// 其实还有个规律,一般带有own的方法,都是获取自身的属性,不获取原型链上的属性
/**
* Object.getOwnPropertyNames()
* 1、获取所有属性,包括不可枚举属性
* 2、不获取原型链上的属性
* 3、不能获取Symbol属性
*/
(function () {
console.log(Object.getOwnPropertyNames(person)); // ["name", "age", "brief"] 可以看到brief这个属性也出来了
})();
/**
* Object.getOwnPropertyDescriptor()、Object.getOwnPropertyDescriptors()
* 1、获取所有属性,包括不可枚举属性
* 2、不获取原型链上的属性
* 3、不能获取Symbol属性(但是这里有点意思)
*/
(function () {
console.log(Object.getOwnPropertyDescriptor(person, 'brief')); // {value: "hello", writable: false, enumerable: false, configurable: false} 可以获取不可枚举属性brief
const propertyDescriptors = Object.getOwnPropertyDescriptors(person);
console.log(Object.keys(propertyDescriptors)); // ["name", "age", "brief"] 可以获取不可枚举属性brief
/* 关于Symbol */
console.log(propertyDescriptors); // 可以在控制台看到,propertyDescriptors对象里有 Symbol(hi) 属性,但是只能看看,并不能访问到
})();
/**
* 关于symbol属性,总结
* 目前只能使用 Object.getOwnPropertySymbols()获取所以symbol属性
* Object.getOwnPropertySymbols() 类似与 Object.getOwnPropertyNames(),都是返回数组,我感觉改名为 getOwnPropertySymbolNames 更合适...
*
* 不能在 for...in...、for...of...、Object.keys()、Object.getOwnPropertyNames()中获取
* 因为Object.getOwnPropertyDescriptor()、Object.getOwnPropertyDescriptors()这两个方法并不是获取属性的,它们的使用方式应该是,先获取属性名,然后才调用...
*/
(function () {
const symbolProperties = Object.getOwnPropertySymbols(person);
console.log(symbolProperties);
symbolProperties.forEach(item => {
// 这时候使用 Object.getOwnPropertyDescriptor()
console.log(Object.getOwnPropertyDescriptor(person, item)); // {value: "hi", writable: true, enumerable: true, configurable: true}
});
})();
// 其他
/**
* Object.assign()
* 1、只复制可枚举属性
* 2、只复制自身属性,不复制原型链的属性
* 3、可以复制symbol属性
*/
(function () {
const clone = Object.assign({}, person);;
console.log(clone === person); // false
console.log(clone.toString2); // undefined 没有复制person.prototype.toString2
console.log(clone.brief); // undefined 没有复制不可枚举属性
console.log(clone[hiSymbol]); // 'hi' 复制了symbol属性
})();
</script>
</html>
版权声明:本文为qq_39571197原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。