美文网首页
阮一峰ES6教程读书笔记(八)Symbol的方法

阮一峰ES6教程读书笔记(八)Symbol的方法

作者: 前端艾希 | 来源:发表于2019-09-20 22:50 被阅读0次

    1. Symbol.for(),Symbol.keyFor()

    有时候我们希望能够重用一个Symbol值,这时候我们可以使用Symbol.for(),该方法能够接受一个参数,然后会在一个“登记表”中搜索使用该参数作为描述的Symbol值是否存在,如果存在,则返回已经存在的Symbol值,如果不存在就用该参数作为描述生成一个新的Symbol值。该方法和Symbol()方法的区别是,该方法会将生成的Symbol登记在全局环境中,而Symbol()不会。

    let s1 = Symbol('a')
    let s2 = Symbol.for('a')
    let s3 = Symbol.for('a')
    
    s1 === s2 // false
    s2 === s3 // true
    

    通过上面的代码我们可以发现,尽管s1是以字符a作为描述的s2是通过在全局登记中搜索以字符a作为描述的Symbol值,但是s1s2不相等说明搜索失败,s2是重新生成的Symbol值,即Symbol()生成的值并没有登记,s2s3相等,说明s3是搜索到已经存在的Symbol值。

    使用Symbol.keyFor()可以返回一个已经登记的Symbol值的描述,即key

    let s1 = Symbol.for("foo");
    Symbol.keyFor(s1) // "foo"
    
    let s2 = Symbol("foo");
    Symbol.keyFor(s2) // undefined 
    

    因为s2未登记,所以该方法无法查询到其key

    2. 内置的Symbol方法

    2.1 Symbol.hasInstance

    对象的Symbol.hasInstance属性其实指向的是一个内部的方法,当其他对象使用instanceof运算符时会自动调用该方法:

    class MyClass {
      [Symbol.hasInstance](foo) {
        return foo instanceof Array;
      }
    }
    
    [1, 2, 3] instanceof new MyClass() // true
    

    2.2 Symbol.isConcatSpreadable

    对象的Symbol.isConcatSpreadable属性等于一个布尔值,表示该对象用于Array.prototype.concat()时,是否可以展开。

    let arr1 = ['c', 'd'];
    ['a', 'b'].concat(arr1, 'e') // ['a', 'b', 'c', 'd', 'e']
    arr1[Symbol.isConcatSpreadable] // undefined
    
    let arr2 = ['c', 'd'];
    arr2[Symbol.isConcatSpreadable] = false;
    ['a', 'b'].concat(arr2, 'e') // ['a', 'b', ['c','d'], 'e']
    
    let arr3 = ['c', 'd'];
    arr2[Symbol.isConcatSpreadable] = true;
    ['a', 'b'].concat(arr2, 'e') // ['a', 'b', ['c','d'], 'e']
    

    通过上面的代码我们可以发现,Arry默认是可以展开的,并且Symbol.isConcatSpreadable的默认值为undefined,当该属性值为true时数组也可以展开,只有当该属性值为false的时候表示调用concat的时候数组不能被展开。

    2.3 Symbol.match

    对象的Symbol.match属性,指向一个函数。当执行str.match(myObject)时,如果该属性存在,会调用它,返回该方法的返回值。

    String.prototype.match(regexp)
    // 等同于
    regexp[Symbol.match](this)
    
    class MyMatcher {
      [Symbol.match](string) {
        return 'hello world'.indexOf(string);
      }
    }
    
    'e'.match(new MyMatcher()) // 1
    

    2.4 Symbol.replace

    对象的Symbol.replace属性,指向一个方法,当该对象被String.prototype.replace方法调用时,会返回该方法的返回值。

    String.prototype.replace(searchValue, replaceValue)
    // 等同于
    searchValue[Symbol.replace](this, replaceValue)
    下面是一个例子。
    
    const x = {};
    x[Symbol.replace] = (...s) => console.log(s);
    
    'Hello'.replace(x, 'World') // ["Hello", "World"]
    

    Symbol.replace方法会收到两个参数,第一个参数是replace方法正在作用的对象,上面例子是Hello,第二个参数是替换后的值,上面例子是World

    参考链接

    作者:阮一峰
    链接:http://es6.ruanyifeng.com/#docs/destructuring

    相关文章

      网友评论

          本文标题:阮一峰ES6教程读书笔记(八)Symbol的方法

          本文链接:https://www.haomeiwen.com/subject/xpksuctx.html