有学有练才叫学习:学而不思则罔,思而不学则殆:学而不习,纸上谈兵,习而不进,画地为牢!

JavaScript,ES6,原始数据类型Symbol(使用方式及场景代码案例)

javascript 炮渣日记 4周前 (11-10) 18次浏览 已收录 0个评论 扫描二维码

说明

ES6,引入了一种新的原始数据类型Symbol,表示独一无二的值。JavaScript语言的第七种数据类型,前六种是:undefined、null、布尔值(Boolean)、字符串(String)、数值(Number)、对象(Object)。

Symbol值通过Symbol函数生成。这就是说,对象的属性名现在可以有两种类型,一种是原来就有的字符串,另一种就是新增的 Symbol 类型。凡是属性名属于Symbol 类型,就都是独一无二的,可以保证不会与其他属性名产生冲突。

常见的使用场景:

作为对象属性名使用、替代常量来使用、定义类的私有属性/方法等。

代码案例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>原始数据类型Symbol</title>
</head>
<body>
	<script>
		// ====================================================================//
		// Symbol的特性
		// ====================================================================//
		// 作为属性名
		let id1 = Symbol("id");
		let id2 = Symbol("id");
		// 唯一性,即使是用同一个变量生成的值也不相等
		console.log("id1 == id2", id1 == id2);
		// 数据类型的另一特点是隐藏性,for···in,object.keys()不能访问
		let obj1 = {
		  [id1]: 'symbol1',
		  [id2]: 'symbol2',
		};
		for(let option in obj1){
			console.log(obj[option]); //空
		}

		let name1 = Symbol.for("name1");
		let name2 = Symbol.for("name2");
		console.log(Symbol.keyFor(name1));  // 'name1'
		console.log(Symbol.keyFor(name2));  // 'name2'
		// 属性名的遍历
		const o = {};
		let a = Symbol('a');
		let b = Symbol('b');
		o[a] = 'Hello';
		o[b] = 'World';
		const objectSymbols = Object.getOwnPropertySymbols(o);
		console.log(objectSymbols);
		// 作为属性名的写法
		let mySymbol = Symbol();
		// 第一种写法
		let a1 = {};
		a1[mySymbol] = 'Hello!';
		// 第二种写法
		let a2 = {
		  [mySymbol]: 'Hello!'
		};
		// 第三种写法
		let a3 = {};
		Object.defineProperty(a3, mySymbol, { value: 'Hello!' });
		// 以上写法都得到同样结果
		console.log("a1", a1[mySymbol]);
		console.log("a2", a2[mySymbol]);
		console.log("a3", a3[mySymbol]);
		// ====================================================================//
		// Symbol的使用场景==>使用Symbol来作为对象属性名(key)
		// ====================================================================//
		const ROLE_USER = Symbol();
		const ROLE_ADMIN = Symbol();
		let obj2 = {
			[ROLE_USER]:"普通用户",
			[ROLE_ADMIN]:"管理员",
		};
		console.log("obj2[PROP_NAME]", obj2[ROLE_USER]);  // obj2[PROP_NAME] 普通用户
		console.log("obj2[ROLE_ADMIN]", obj2[ROLE_ADMIN]); // obj2[ROLE_ADMIN] 管理员
		// ====================================================================//
		// Symbol的使用场景==>使用Symbol来替代常量
		// ====================================================================//
		const TYPE_AUDIO = Symbol()
		const TYPE_VIDEO = Symbol()
		const TYPE_IMAGE = Symbol()
		// 处理文件资源
		function handleFileResource(resource) {
		  switch(resource.type) {
			case TYPE_AUDIO:
			  console.log("TYPE_AUDIO",TYPE_AUDIO);
			  break
			case TYPE_VIDEO:
			  console.log("TYPE_VIDEO",TYPE_VIDEO);
			  break
			case TYPE_IMAGE:
			  console.log("TYPE_IMAGE",TYPE_IMAGE);
			  break
			default:
			  throw new Error('Unknown type of resource')
		  }
		}
		handleFileResource({type:TYPE_AUDIO});
		// ====================================================================//
		// Symbol的使用场景==>使用Symbol定义类的私有属性/方法
		// ====================================================================//
		const PASSWORD = Symbol()
		class Login {
		  constructor(username, password) {
			this.username = username;
			this[PASSWORD] = password;
		  }

		  checkPassword(password) {
			  return this[PASSWORD] === password;
		  }
		}
		let login = new Login("fuyue","a");
		console.log("登录情况:", login.checkPassword("a"));
		// ====================================================================//
		// Symbol的使用场景==>注册和获取全局Symbol
		// ====================================================================//
		let gs1 = Symbol.for('global_symbol_1')  // 注册一个全局Symbol
		let gs2 = Symbol.for('global_symbol_1')  // 获取全局Symbol
		console.log("是否一致:", gs1 === gs2);
	</script>
</body>
</html>
喜欢 (0)
炮渣日记
关于作者:
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址