0. 准备知识
Symbol.toStringTag
Symbol.toStringTag
是一个内置 symbol,它通常作为对象的属性键使用,对应的属性值应该为字符串类型
,这个字符串用来表示该对象的自定义类型标签
,通常只有内置的 Object.prototype.toString()
方法会去读取这个标签并把它包含在自己的返回值
里。
说白了,就是希望自己创建的对象能有自己的标签类型[Object Xxxx]
。
例如,有许多JS对象类型没有toStringTag
属性,但还是能通过toString
识别特定返回的方法。
Object.prototype.toString.call('foo'); // "[object String]"
Object.prototype.toString.call([1, 2]); // "[object Array]"
Object.prototype.toString.call(3); // "[object Number]"
Object.prototype.toString.call(true); // "[object Boolean]"
Object.prototype.toString.call(undefined); // "[object Undefined]"
Object.prototype.toString.call(null); // "[object Null]"
我们也想这样创建一个对象,用toString返回其类型标签,但是依然是[Object Object]
,咱没这待遇… 不过通过 Symbol.toStringTag
给了我们vip特权。
let obj = {
};
Object.defineProperty(obj,Symbol.toStringTag,{
value: 'MyTagOY'});
console.log( Object.prototype.toString.call( obj ) ) // [object MyTagOY]
class MyTag {
get [Symbol.toStringTag](){
return 'MyTagOY'
}
}
console.log( Object.prototype.toString.call( new MyTag() ) ) // [object MyTagOY]
Object.create(proto)
方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__。
参数 proto:新创建对象的原型对象
。
Object.create(null)
创建一个非常纯洁的对象,可以自己定义自己的hasOwnProperty
、toString
等方法。使用for...in
遍历对象时,不需要在对原型属性进行检查了。
Object.create()
的原理:
if( typeof Object.create != 'function' ){
Object.create = function(proto){
function F(){
}; // 构造函数
F.prototype = proto;
return new F();
}
}
getter
defineProperty
方法会直接在一个对象上定义一个新的属性,或者修改一个对象的现有属性,并返回这个对象。
复习一下 Object.defineProperty(obj, prop, descriptor)
:
obj:要在其上定义属性的对象。prop:要定义或修改的属性的名称。descriptor:属性描述符。
对于描述符:
configurable
:属性是否可配置。默认值为false。
let obj = {
};
Object.defineProperty(obj,'name',{
value: 1
})
// 1. 试图去删除name属性时,属性是不可删除的。
console.log( delete obj.name ) ; console.log( Reflect.deleteProperty(o,'name') );
// 2. 试图再次去修改value, 会报错。
Object.defineProperty(obj,'name',{
value: 2
})
// TypeError: Cannot redefine property: key
// 3. 配置writable为true后,可以修改值,注意writable只可以单向从true变为false,相反会报错。
Object.defineProperty(obj,'name',{
value: 1,
writable: true
});
Object.defineProperty(obj,'name',{
value: 2
writable: false
})
console.log(obj.name) // 2
// 4. 我们从value + writable这种数据描述符,转换到get + set这种存取描述符,也会报错。
Object.defineProperty(o, 'name', {
value: 1,
writable: true
})
console.log(o.key) // 1
Object.defineProperty(o, 'name', {
get(){
return '2'
}
})
//5. 从一个存取描述符,转换到另一个存取描述符,也是报错的。
Object.defineProperty(o, 'name', {
get () {
return 1;
}
})
console.log