学习的时候是根据菜鸟教程学的。
<!DOCTYPE html>
<html>
<head>
<title>symbol 基本用法</title>
</head>
<body>
<p>概述:ES6引入了一种新的原始数据类型Symbol。表示独一无二的值,最大的用法是用来定义对象的唯一属性:</p>
<p>ES6的数据类型除了,Number、String、Boolean、Object、null、undefiend、还新增了Symbol</p>
<p>symbol函数栈不能使用new命令, 因为symbol是原始数据类型,不是对象。可以接受一个字符串作为参数,为新创建的Symbol提供描述。用来显示在控制台或者作为字符串的时候,便于区分。</p>
<script type="text/javascript">
let symbol = Symbol("KK");
consol.log(symbol);
consol.log(typeof(symbol));
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<title>symbol使用场景</title>
</head>
<body>
<p>作为属性名:由于每一个symbol都不相等,所以可以用来作为对象的属性,避免属性的重复。</p>
<p>symbol作为对象属性名时,不能用 . 运算符,要用方括号。因为 . 运算符后面是字符串,所以取到的是symbol的属性,而不是Symbol的值sy属性</p>
<script type="text/javascript">
let symbol = Symbol("s1");
// 写法一
let Person = {};
Person[symbol] = "person1";
console.log(Person);
// 写法二
let Person1 = {
[symbol] : "主Id"
}
console.log(Person1);
// 写法三
let Person2 = {};
Object.defineProperty(Person2, symbol, {value: "AA"});
console.log(Person2);
//
let syObject = {}
syObject[symbol] = "YY";
console.log(syObject[symbol]);
console.log(syObject.sy);
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<title>symbol 注意点</title>
</head>
<body>
<p>Symbol 值作为属性名时,该属性是公有属性,可以在类的外部访问,但是不会出现在for...in、for...of 的循环中,也不会被Object.keys()、Object.getOwnPopertyNames()返回。如果要读取到一个对象的Symbol属性,可以通过Object.getOwnPropertySymbols()和Reflect.ownKeys()取到。</p>
<script type="text/javascript">
let sy = Symbol("they1");
let syObject = {};
syObject[sy] = "maoKK";
console.log(syObject);
for(let i in syObject){
console.log(i);
}
console.log(Object.keys(syObject));
console.log(Object.getOwnPropertySymbols(syObject));
console.log(Reflect.ownKeys(syObject));
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<title>symbol 定义常量</title>
</head>
<body>
<script type="text/javascript">
// 在es5 使用字符串表示常量,使用字符串不能保证常量的独特的,所以会出现分不清值的问题 。
const COLOR_RED = "red";
const COLOR_YELLOW = "yellow";
const COLOR_BLUE = "blue";
const MY_BLUE = "blue";
function getConstName(color){
switch (color){
case COLOR_RED:
return "COLOR_RED";
case COLOR_YELLOW:
return "COLOR_YELLOW";
case COLOR_BLUE:
return "COLOR_BLUE";
case MY_BLUE:
return "MY_BLUE";
default:
// throw new Exception("不能找到这个颜色!");
return "没有这个颜色……"
}
}
console.log(getConstName(COLOR_BLUE));
console.log(getConstName(MY_BLUE));
console.log(getConstName(COLOR_RED));
// 使用symbol定义局可以保证这一组常量的值都是唯一的,Symbol 的值是唯一的,所以不会出现相同值得常量,即可以保证 switch 按照代码预想的方式执行。
const SCOLOR_RED = Symbol("red");
const SCOLOR_YELLOW = Symbol("yellow");
const SCOLOR_BLUE = Symbol("blue");
const SMY_BLUE = Symbol("blue");
function getConstName1(color){
switch (color){
case SCOLOR_RED:
return "SCOLOR_RED";
case SCOLOR_YELLOW:
return "SCOLOR_YELLOW";
case SCOLOR_BLUE:
return "SCOLOR_BLUE";
case SMY_BLUE:
return "SMY_BLUE";
default:
// throw new Exception("不能找到这个颜色!");
return "没有这个颜色……"
}
}
console.log(getConstName1(SCOLOR_RED));
console.log(getConstName1(SMY_BLUE));
console.log(getConstName1(SCOLOR_BLUE));
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<title>symbol for</title>
</head>
<body>
<p>symbol类似于单例模式。 首先会在全局搜索被登记的symbol中是否有该字符串参数作为名称的的smbol值。如果有即返回该symbol值,若没有则新建并返回一个以该字符串参数为名称的symbol值,并登记在全局环境中搜索。</p>
<p>经测试,第一个为false,第二个为true,所以前面所说的都限制在同是symbol.for(),若一个是通过Symbol("KK")定义,一个是通过Symbol.for("PP")定义,则不可行。</p>
<p>Symbol.keyFor() 返回一个已登记的Symbol类型值的key,用来检测该字符串参数作为名称的Symbol值师傅已被登记。</p>
<p>同样的Symbol.keyFor() 也仅仅是针对Symbol.key()。</p>
<script type="text/javascript">
let sy1 = Symbol("yellow");
let sy2 = Symbol.for("yellow");
console.log(sy1 == sy2);
let sy3 = Symbol.for("yellow");
console.log(sy2 == sy3);
console.log("-----------------------");
console.log(Symbol.keyFor(sy3));
console.log(Symbol.keyFor(sy1));
</script>
</body>
</html>