11.Symbol

 

Symbol 基本使用

ES6 引入了一种新的原始数据类型 Symbol,表示独一无二的值。它是 JavaScript 语言的第七种数据类型,是一种类似于字符串的数据类型。

Symbol 特点

  1. Symbol 的值是唯一的,用来解决命名冲突的问题
  2. Symbol 值不能与其他数据进行运算
  3. Symbol 定义的对象属性不能使用 for…in 循环遍历 ,但是可以使用 Reflect.ownKeys 来获取对象的所有键名
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
//创建Symbol
let s1 = Symbol();
console.log(s1);
// Symbol()
console.log(typeof s1);
// symbol

// 添加标识的 Symbol
let s2 = Symbol("token");
let s3 = Symbol("token");
console.log(s2);
// Symbol(token)
console.log(typeof s2)
// symbol
console.log(s2 === s3);
// false

// 使用 Symbol for 定义
let s4 = Symbol.for("a1");
let s5 = Symbol.for("a1");
console.log(s4);
// Symbol(a1)
console.log(typeof s4);
// symbol
console.log(s4 === s5);
// true

//不能与其他数据进行运算
// let result = s5 + "123";
// Uncaught TypeError: Cannot convert a Symbol value to a string
let result = s5 + s5;
// Uncaught TypeError: Cannot convert a Symbol value to a number

JavaScript数据类型:

  • undefined
  • string symbol
  • object
  • null number
  • boolean

注: 遇到唯一性的场景时要想到 Symbol

使用 Symbol 创建对象属性

使用Symbol为对象添加属性,可以避免对对象原有的同名属性产生意外影响,使用Symbol方式为对象添加属性,比较安全,避免直接修改对象的属性值的风险

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
// 案例一
let game = {
name:'俄罗斯方块',
up: function(){},
down: function(){}
};

// 直接使用game.up=的方式,如果对象原本就存在up属性,则会直接修改原对象的up属性的值
let method = {
up: Symbol("up"),
down: Symbol("down")
}

game[method.up] = function() {
console.log("this is up");
}
game[method.down] = function() {
console.log("this is down");
}
console.log(game);
// {name: '俄罗斯方块', up: ƒ, down: ƒ, Symbol(up): ƒ, Symbol(down): ƒ}
console.log(game[method.up]);
// ƒ () { console.log("this is up"); }
console.log(game[Symbol("up")]);
// undefined

// 案例二
let youxi = {
name: "race",
[Symbol("left")]: function() {
console.log("turn left");
},
[Symbol("right")]: function() {
console.log("turn right");
}
}
console.log(youxi);
// {name: 'race', Symbol(left): ƒ, Symbol(right): ƒ}
console.log(youxi[Symbol("left")]);
// undefined

Symbol 内置值

除了定义自己使用的 Symbol 值以外, ES6 还提供了 11 个内置的 Symbol 值,指向语言内部使用的方法。 可以称这些方法为魔术方法,因为它们会在特定的场
景下自动执行。

1.Symbol.hasInstance

1
2
3
4
5
6
7
8
9
10
11
12
class Person {
static [Symbol.hasInstance](param) {
console.log(param); // {name: 'simpleObj'}
console.log("detect the type"); // detect the type
}
}

let obj = {
name: "simpleObj"
};
console.log(obj instanceof Person);
// false
1
2
3
4
5
6
7
8
9
10
11
12
13
class Person {
static [Symbol.hasInstance](param) {
console.log(param); // {name: 'simpleObj'}
console.log("detect the type"); // detect the type
return true;
}
}

let obj = {
name: "simpleObj"
};
console.log(obj instanceof Person);
// true
1
2
3
4
5
6
7
8
9
10
class Person {
static [Symbol.hasInstance](param) {
console.log(param); // Person {}
console.log("detect the type"); // detect the type
}
}

let testObj = new Person();
console.log(testObj instanceof Person);
// false
1
2
3
4
5
6
7
8
9
10
11
class Person {
static [Symbol.hasInstance](param) {
console.log(param); // Person {}
console.log("detect the type"); // detect the type
return true;
}
}

let testObj = new Person();
console.log(testObj instanceof Person);
// true

2.Symbol.isConcatSpreadable

1
2
3
4
5
6
7
8
9
10
11
/**
* Symbol.isConcatSpreadable整体作为对象的属性
*/
const arr1 = [1,2,3];
const arr2 = [4,5,6];
console.log(arr1.concat(arr2));
// (6) [1, 2, 3, 4, 5, 6]

arr2[Symbol.isConcatSpreadable] = false;
console.log(arr1.concat(arr2));
// (4) [1, 2, 3, Array(3)]
number item description
1 Symbol.hasInstance 当其他对象使用 instanceof 运算符,判断是否为该对象的实例时,会调用这个方法
2 Symbol.isConcatSpreadable 对象的 Symbol.isConcatSpreadable 属性等于的是一个布尔值,表示该对象用于 Array.prototype.concat()时,是否可以展
3 Symbol.species 创建衍生对象时,会使用该属性
4 Symbol.match 当执行 str.match(myObject) 时,如果该属性存在,会调用它,返回该方法的返回值。
5 Symbol.replace 当该对象被 str.replace(myObject)方法调用时,会返回该方法的返回值。
6 Symbol.search 当该对象被 str.search(myObject)方法调用时,会返回该方法的返回值。
7 Symbol.split 当该对象被 str. split (myObject)方法调用时,会返回该方法的返回值。
8 Symbol.iterator 对象进行 for…of 循环时,会调用 Symbol.iterator 方法,返回该对象的默认遍历器
9 Symbol.toPrimitive 该对象被转为原始类型的值时,会调用这个方法,返回该对象对应的原始类型值。
10 Symbol. toStringTag 在该对象上面调用 toString 方法时,返回该方法的返回值
11 Symbol. unscopables 该对象指定了使用 with 关键字时,哪些属性会被 with 环境排除。