0
点赞
收藏
分享

微信扫一扫

Symbol的属性方法续篇

Symbol.toPrimitive

对象的Symbol.toPrimitive属性,指向一个方法。该对象被转为原始类型的值时,会调用这个方法,返回该对象对应的原始类型值。Symbol.toPrimitive被调用时,会接受一个字符串参数,表示当前运算的模式,一共有三种模式。

  • Number:该场合需要转成数值
  • String:该场合需要转成字符串
  • Default:该场合可以转成数值,也可以转成字符串

let obj = {
  [Symbol.toPrimitive](hint) {
    switch (hint) {
      case 'number':
        return 123;
      case 'string':
        return 'str';
      case 'default':
        return 'default';
      default:
        throw new Error();
     }
   }
};

2 * obj // 246
3 + obj // '3default'
obj == 'default' // true
String(obj) // 'str'

Symbol的属性方法续篇_JSON

Symbol.toStringTag

对象的Symbol.toStringTag属性,用来设定一个字符串(设为其他类型的值无效,但不报错)。在目标对象上面调用Object.prototype.toString()方法时,如果Symbol.toStringTag属性存在,该属性设定的字符串会出现在toString()方法返回的字符串之中,表示对象的类型。也就是说,这个属性可以用来定制[object Object][object Array]object后面的那个大写字符串。

// 例一
({[Symbol.toStringTag]: 'Foo'}.toString())
// "[object Foo]"

// 例二
class Collection {
  get [Symbol.toStringTag]() {
    return 'xxx';
  }
}
let x = new Collection();
Object.prototype.toString.call(x) // "[object xxx]"

Symbol的属性方法续篇_symbol_02

ES6 新增内置对象的Symbol.toStringTag属性值如下。

JSON[Symbol.toStringTag]:'JSON'

Math[Symbol.toStringTag]:'Math'

Module 对象M[Symbol.toStringTag]:'Module'

ArrayBuffer.prototype[Symbol.toStringTag]:'ArrayBuffer'

DataView.prototype[Symbol.toStringTag]:'DataView'

Map.prototype[Symbol.toStringTag]:'Map'

Promise.prototype[Symbol.toStringTag]:'Promise'

Set.prototype[Symbol.toStringTag]:'Set'

%TypedArray%.prototype[Symbol.toStringTag]:'Uint8Array'等

WeakMap.prototype[Symbol.toStringTag]:'WeakMap'

WeakSet.prototype[Symbol.toStringTag]:'WeakSet'

%MapIteratorPrototype%[Symbol.toStringTag]:'Map Iterator'

%SetIteratorPrototype%[Symbol.toStringTag]:'Set Iterator'

%StringIteratorPrototype%[Symbol.toStringTag]:'String Iterator'

Symbol.prototype[Symbol.toStringTag]:'Symbol'

Generator.prototype[Symbol.toStringTag]:'Generator'

GeneratorFunction.prototype[Symbol.toStringTag]:'GeneratorFunction'

Symbol.unscopables

对象的Symbol.unscopables属性,指向一个对象。该对象指定了使用with关键字时,哪些属性会被with环境排除。

Array.prototype[Symbol.unscopables]
// {
//   copyWithin: true,
//   entries: true,
//   fill: true,
//   find: true,
//   findIndex: true,
//   includes: true,
//   keys: true
// }

Object.keys(Array.prototype[Symbol.unscopables])
// ['copyWithin', 'entries', 'fill', 'find', 'findIndex', 'includes', 'keys']

Symbol的属性方法续篇_Math_03

Symbol的属性方法续篇_JSON_04

上面代码说明,数组有 7 个属性,会被with命令排除。

// 没有 unscopables 时
class MyClass {
  foo() { return 1; }
}

var foo = function () { return 2; };

with (MyClass.prototype) {
  foo(); // 1
}

// 有 unscopables 时
class MyClass {
  foo() { return 1; }
  get [Symbol.unscopables]() {
    return { foo: true };
  }
}

var foo = function () { return 2; };

with (MyClass.prototype) {
  foo(); // 2
}

Symbol的属性方法续篇_字符串_05

上面代码通过指定Symbol.unscopables属性,使得with语法块不会在当前作用域寻找foo属性,即foo将指向外层作用域的变量。

举报

相关推荐

0 条评论