Symbol原始数据类型
JavaScript(ES6引入)语言的第七种数据类型,是一种类似于字符串的数据类型,一种新的原始数据类型 Symbol,表示独一无二的值。
Symbol特点:
1、Symbol的值是唯一的,用来解决命名冲突的问题;
2、Symbol值不能与其他数据进行运算;
3、Symbol定义的对象属性不能使用for…in循环遍历 ,但是可以使用Reflect.ownKeys来获取对象的所有键名。
Symbol内置值:
ES6还提供了11个内置的Symbol值,指向语言内部使用的方法,可以称这些方法为魔术方法,因为它们会在特定的场景下自动执行。
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环境排除。
其它参考:ES6原始数据类型Symbol
代码案例
案例一:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Symbol,原始数据类型,表示独一无二的值</title>
</head>
<body>
<script>
//创建Symbol
let symbol = Symbol();
console.log(symbol, typeof symbol); // Symbol() 'symbol'
let symbol2 = Symbol('小奋斗');
let symbol3 = Symbol('小奋斗');
console.log(symbol2===symbol3); // false
//Symbol.for 创建
let symbol4 = Symbol.for('小奋斗');
let symbol5 = Symbol.for('小奋斗');
console.log(symbol4===symbol5); // true
// 不可运算
// console.log(symbol + 100); // Uncaught TypeError: Cannot convert a Symbol value to a number
// console.log(symbol > 100);
// console.log(symbol + symbol);
// USONB you are so niubility
// u undefined
// s string symbol
// o object
// n null number
// b boolean
</script>
</body>
</html>
案例二:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Symbol创建对象属性</title>
</head>
<body>
<script>
// 向对象中添加方法 up down
let game = {
name: 'CS-Game',
up: function () { return "up"; },
down: function () { return "down"; }
};
//声明一个对象
let methods = {
up: Symbol(),
down: Symbol()
};
game[methods.up] = function () {
console.log("methods.up");
return "game[methods.up]";
}
game[methods.down] = function () {
console.log("methods.down");
return "game[methods.down]";
}
console.log(game); // {name: 'CS-Game', up: ?, down: ?, Symbol(): ?, Symbol(): ?}
console.log(game.up()); // up
console.log(game.down()); // down
console.log(game[methods.up]()); // game[methods.up]
console.log(game[methods.down]()); // game[methods.down]
// Symbol创建对象属性
let one = [Symbol('one')];
let two = [Symbol.for('two')];
let game2 = {
name: "俄罗斯方块",
one: function () {
console.log("1111111111");
return "one result";
},
two: function () {
console.log('2222222222');
return "two result";
}
}
console.log(game2) // {name: '俄罗斯方块', one: ?, two: ?}
console.log(game2.one()); // one result
console.log(game2.two()); // two result
</script>
</body>
</html>
案例三:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Symbol内置属性</title>
</head>
<body>
<script>
class Person{
static [Symbol.hasInstance](param){
console.log(param);
console.log("我被用来检测类型了");
return false;
}
}
let o = {};
console.log(o instanceof Person); // false
const arr = [1,2,3];
const arr2 = [4,5,6];
// 表示该对象用于Array.prototype.concat()时,是否可以展开
arr2[Symbol.isConcatSpreadable] = false;
console.log(arr.concat(arr2)); // [1, 2, 3, Array(3)]
const arr3 = [4,5,6];
console.log(arr.concat(arr3)); // [1, 2, 3, 4, 5, 6]
</script>
</body>
</html>