揭开Symbol的神秘面纱

一,Symbol的基本概念

es6新发布的第七种jS数据类型,前六种是:undefined、null、布尔值(Boolean)、字符串(String)、数值(Number)、对象(Object)

二,和其他基本类型的转化

可以显示的转化为字符串

let sym = Symbol('My symbol');
String(sym) // 'Symbol(My symbol)'
sym.toString() // 'Symbol(My symbol)'
复制代码

隐式的转化为布尔值,注意不能隐式转化为字符串

!sym1 //输出false
1 + sym1 // error:Cannot convert a Symbol value to a number
'' + sym1  //error:Cannot convert a Symbol value to a string
复制代码

三, Symbol()和Symbol.for()的对比

  • Symbol.for()会被登记在全局环境中供搜索,不会每次调用就返回一个新的 Symbol类型的值,而是会先检查给定的key是否已经存在,如果不存在才会新建一个值
  • 比如,如果你调用Symbol.for("描述信息")30 次,每次都会返回同一个 Symbol值,但是调用Symbol("描述信息")30 次,会返回 30 个不同的 Symbol 值。
  • 这里Symbol.keyFor方法返回一个已登记的 Symbol 类型值的key。
let s1 = Symbol.for("foo");
Symbol.keyFor(s1) // "foo"

let s2 = Symbol("foo");
Symbol.keyFor(s2) // undefined
复制代码

四, 实用的内置Symbol值

1,可以作为对象的私有属性-Symbol.hasInstance

var obj = {};

obj[Symbol("a")] = "a";
obj[Symbol.for("b")] = "b";
obj["c"] = "c";
obj.d = "d";

for (var i in obj) {
   console.log(i); // c d
}
复制代码

symbol 键直接跳过Symbol 作为属性名,该属性不会出现在for...in、for...of循环中,也不会被Object.keys()、Object.getOwnPropertyNames()、JSON.stringify()返回。但是,它也不是私有属性,有一个Object.getOwnPropertySymbols方法,可以获取指定对象的所有 Symbol 属性名。

const objectSymbols = Object.getOwnPropertySymbols(obj);

objectSymbols
// [Symbol(c), Symbol(d)]
复制代码

总结:可以用for in一些方法遍历对象获取非Symbol值的key,如果要想获取到Symbol值的属性名,需要通过Object.getOwnPropertySymbols方法。

2,对象的遍历-Symbol.iterator

通过Symbol.iterator来访问对象默认的迭代器,

3,连接一个类数组的对象-Symbol.isConcatSpreadable

let collection = {
    0: "Hello",
    1: "world",
    length: 2,
    [Symbol.isConcatSpreadable]: true
};

let messages = [ "Hi" ].concat(collection);

console.log(messages); //Hi Hello world
console.log(typeof messages); //object
复制代码

3,关于正则表达式

4, 关于字符串的拓展

  • Symbol.match- String.prototype.match()用于比较字符串
"/bar/".startsWith(/bar/); 

// Throws TypeError, 因为 /bar/ 是一个正则表达式

var re = /foo/;
re[Symbol.match] = false;
"/foo/".startsWith(re); // true
"/baz/".endsWith(re);   // false
复制代码
  • Symbol.replace- 用于String.prototype.replace()替换字符串
String.prototype.replace(searchValue, replaceValue)
// 等同于searchValue[Symbol.replace](this, replaceValue) 
复制代码
  • Symbol.search- 用于String.prototype.search()查找字符串
- String.prototype.search(regexp)
// 等同于
regexp[Symbol.search](this)

class MySearch {
  constructor(value) {
    this.value = value;
  }
  [Symbol.search](string) {
    return string.indexOf(this.value);
  }
}
'foobar'.search(new MySearch('foo')) // 0
复制代码
  • Symbol.split- 用于String.prototype.split()分割字符串
String.prototype.split(separator, limit)
// 等同于
separator[Symbol.split](this, limit)
复制代码

4,关于instanceof的拓展,构造一个1~100之间的函数

function SpecialNumber() {
    // ...
}
Object.defineProperty(SpecialNumber, Symbol.hasInstance, {
    value: function(v) {
        return (v instanceof Number) && (v >=1 && v <= 100);
    }
});

let two = new Number(2),
    zero = new Number(0);
console.log(two instanceof SpecialNumber);    // true
console.log(zero instanceof SpecialNumber);   // false
复制代码

五,其他的内置的 Symbol 值

除了定义自己使用的 Symbol 值以外,ES6 还提供了 11 个内置的 Symbol 值,指向语言内部使用的方法。上面已经提到比较实用的几个值,下面是其他的内置Symbol值。

  1. Symbol.match
  2. Symbol.prototype
  3. Symbol.replace
  4. Symbol.species
  5. Symbol.toPrimitive
  6. Symbol.toStringTag
  7. Symbol.unscopables

如有错误,不吝赐教(⊙o⊙)…

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值