ES6新特性_Symbol基本使用

ES6新特性_Symbol基本使用

本文主要介绍,ES6新特性,Symbol基本使用,ES6引入了一种新的原始数据类型Symbol, 表示独一无二的值。它是javascript语言的第七种数据类型,是一种类似于字符串的数据类型。特点:1. Symbol的值是唯一的,用来解决命名冲突的问题 2. Symbol的值不能与其它数据进行运算 3. Symbol定义的对象属性不能使用for...in循环遍历,但是可以使用Reflect.ownKeys来获取对象的所有键名。
一、创建Symbol
let s = Symbol();
console.log(s, typeof s); // Symbol() 'symbol'

// fujuhao.com 只是symbol的描述字符串
let s2 = Symbol("fujuhao.com");
let s3 = Symbol("fujuhao.com");
console.log(s2 === s3); // false

// Symbol.for 创建
let s4 = Symbol.for("fujuhao.com");
console.log(s4, typeof s4); // Symbol(fujuhao.com) 'symbol'
let s5 = Symbol.for("fujuhao.com");
console.log(s4 === s5); // true
    
二、不能与其它数据进行运算
let res = s + 100; // Uncaught TypeError: Cannot convert a Symbol value to a number
let res = s > 100; // Uncaught TypeError: Cannot convert a Symbol value to a number
let res = s + s; // Uncaught TypeError: Cannot convert a Symbol value to a number
三、Symbol的使用场景

主要就给对象添加属性或方法,如果这个对象的数据很大,不知道里面是否有已经存在这个方法时,我们就可以使用Symbol来添加, game对象里面有up,down方法,如果我们想给game增加up,down方法,一般的写法就会覆盖原本的方法。

let game = {
    up: ()=>{
        console.log('原本的up方法');
    },
    down: ()=>{
        console.log('原本的down方法');
    }
}
// 覆盖了原来的方法
game.up = ()=>{}
game.down = ()=>{}

// 此时我们就可以使用symbol来解决这个问题
let methods = { 
    up: Symbol(),
    down: Symbol()
};
game[methods.up] = ()=>{
    console.log('我是通过symbol增加的up方法');
}
game[methods.down] = ()=>{
    console.log('我是通过symbol增加的down方法');
}
console.log(game)
 
// 另外一种添加方式,可直接写在对象里如:
let game = {
    up: ()=>{
        console.log('原本的up方法');
    },
    down: ()=>{
        console.log('原本的down方法');
    },
    [Symbol('这里是symbol的描述')]: function(){
        console.log("这里添加的up方法");
    },
    [Symbol('这里是symbol的描述')]: function(){
        console.log("这里添加的down方法");
    },
};
console.log(game);
四、Symbol的内置值

除了定义自己使用Symbol值以外, ES6还提供了11个内置的Symbol值,指向语言内部使用的方法。

内置属性

介绍

Symbol.hasInstance

当其它对象使用instanceof运算符,判断是否为该对象的实例时,会调用这个方法

Symbol.isConcatSpreadable

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

Symbol.unscopables

该对象指定了使用with关键字时,哪些属性会被with环境排除

Symbol.match

当执行str.match(myObject)时,如果该属性存在,会调用它,返回该方法的返回值

Symbol.replace

当该对象被str.replace(myObject)方法调用时,会返回该方法的返回值

Symbol.search

当该对象被str.search(myObject)方法调用时,会返回该方法的返回值

Symbol.split

当该对象被str.split(myObject)方法调用时,会返回该方法的返回值

Symbol.iterator

对象进行for...of循环时,会调用Symbol.iterator方法,返回该对象的默认遍历器

Symbol.toPrimitive

该对象被转为原始类型的值时,会调用这个方法,返回该对象对应的原始类型值

Symbol.toStringTag

在该对象上面调用toString方法时,返回该方法的返回值

Symbol.species

创建衍生对象时,会使用该属性

测试: Symbol.hasInstance
let s6 = {
    // 检测类型
    [Symbol.hasInstance]: (params)=>{
         console.log('我已被调用...')
        // console.log('params:',params)
        // 这里可对进行检测,检测结果返回true/false,外面打印的就是true/false
        // return true; // true / false
    }
}
let s7 = {}; 
// 使用instanceof, 就会触发Symbol.hasInstance
console.log(s7 instanceof s6);
测试: Symbol.isConcatSpreadable
let arr1 = [1,2,3];
let arr2 = [4,5,6];
console.log(arr1.concat(arr2)); // [1, 2, 3, 4, 5, 6]

// 设置arr2不展开
arr2[Symbol.isConcatSpreadable] = false;
console.log(arr1.concat(arr2)); // [1, 2, 3, Array(3)]

其它内置属性,可以自行测试...

Loading...