深入理解ES6 006【学习笔记】

Symbol和Symbol属性

6种原始数据类型:Symbol。私有名称原本是为了让开发者们创建非字符串属性名称而设计的,但是一般的技术无法检测这些属性的私有名称

创建Symbol

let firstName = Symbol();
let person = {}
person[firstName] = "Nicholas";
console.log(person[firstName]); // Nicholas 

new Symbol() 会报错,Symbol函数接受一个可选参数,其可以让你添加一段文本描述即将创建的Symbol,这段描述不可用于属性访问,但是建议你在每次创建Symbol时都添加一段描述,以便于阅读代码和调试Symbol程序

let firstName = Symbol('first name');
let person = {}
person[firstName] = "Nicholas"
console.log("first name" in person); // false
console.log(person[firstName]); //Nicholas
console.log(firstName) // "Symbol(first name)"

Symbol的描述被存储在内部的[[Description]]属性中,只有当调用Symbol的toString()方法才可以读取这个属性,在执行console.log时,隐式调用了firstName的toString()方法,所以它的描述会被打印到日志中,但是不能直接在代码里访问[[Description]]

使用typeof symbol 如果是会返回'symbol',所有使用计算属性名的地方,都可以使用Symbol。

Symbol的使用方法

我们之前都是在括号中使用Symbol,事实上,Symbol也可以用于可计算对象字面量属性、Object.defineProperty()方法和Object.defineProperties()方法的调用过程

let fristName = Symbol("first name");
// 使用一个可计算对象这字面量属性
let person = {
  [firstName]:"Nicholas"
}
// 将属性设置为只读
Object.defineProperty(person,firstName,{writable:false})

let lastName = Symbol('last name');

Object.defineProperties(person,{
  [lastName]:{
    value:"Zakas",
    writable:false
  }
})
console.log(person[firstName]) //Nicholas
console.log(person[lastName]) //Zakas

虽然在所有使用可计算属性名的地方,都可以使用Symbol来替代,但是为了在不同的代码片段间有效地共享这些Symbol,需要建立一个体系

Symbol共享体系

例如我们想在不同的对象类型,想使用同一个Symbol属性来表示一个独特的标识符。在很大的代码库或跨文件追踪Symbol非常困难且容易出错,出于这些原因ES6提供了一个可以随时访问全局Symbol注册表。使用Symbol.for(xxx) 只接受一个参数。要创建Symbol的字符串描述类似Symbol('xxx')Symbol.for(xxx)会去全局注册表中找有没有注册这个Symbol,有就返回,没有就创建一个并注册到全局表中,下次不用再新建一个了。

Symbol与类型转换

我上面的示例使用console.log()方法来输出Symbol的内容,它会调用Symbol的String()方法输出有用信息,如果你试图将一个Symbol和一个字符串拼接,会导致程序抛出错误。

let uid = Symbol.for("uid"),
desc = String(uid);
console.log(desc); // Symbol(uid)

Symbol的属性检索

Object.keys()Object.getOwnPropertyNames()方法可以检索对象中所有的属性名,后一个方法不考虑属性的可枚举性一律返回。这两个方法都支持Symbol属性。所以又推出了一个Object.getOwnPropertySymbols()方法返回一个包含所有Symbole自有属性的值。

let uid = Symbol.for("uid");
let object = {
  [uid]:"12345"
}
let symbols = Object.getOwnPropertySymbols(object);
console.log(symbols.length) // 1
console.log(symbols[0]) // "Symbol(uid)"
console.log(object[symbols[0]]) //12345

通过well-know Symbol暴露内部操作

  • Symbol.hasInstance
  • Symbol.isConcatSpreadable
  • Symbol.iterator
  • Symbol.match
  • Symbol.replace
  • Symbol.species
  • Symbol.split
  • Symbol.species
  • Symbol.toPrimitive
  • Symbol.toStringTag
  • Symbol.unscopables
obj instanceof Array;
// 等价于
Array[Symbol.hasInstance](obj)
// 本质上,es6只是将instanceof操作符重新定义为此方法的简写语法,现在引入调用后,就可以随意改变instanceof的运行方式了。
// 假设你想定义一个无实例的函数,就可以将Symbol.hasInstance的返回值硬编码为false
function MyObject(){
  // 空函数
}
Object.defindProperty(MyObject,Symbol.hasInstance,{
  value:function(v){
    return false
  }
})
let obj = new MyObject()
console.log(obj instanceof MyObject) // false

Symbol.isConcatSpreadable

js数组的concat方法被设计用于拼接两个数组,使用如下方法:

let color1 =["red","green"],
color2 = color1.concat(["blue","black"])
console.log(color2.length) // 4
console.log(color2) // ["red","green","blue","black"]

// color1与一个临时数组拼接成两个数组
// concat方法也可以接受非数组参数,此时该方法只会将这些参数逐一添加到数组末尾如下
let color1 =["red","green"],
color2 = color1.concat(["blue","black"],"brown")
console.log(color2.length) // 5
console.log(color2) // ["red","green","blue","black","brown"]
// 这个属性可以设置或阻止调用concat方法时是否展开

主题测试文章,只做测试使用。发布者:Walker,转转请注明出处:https://joyjs.cn/archives/4332

(0)
Walker的头像Walker
上一篇 2025年3月8日 12:51
下一篇 2025年3月8日 12:51

相关推荐

  • Nuxt3_扫盲 入门与原理介绍【学习笔记】

    Nuxt 3 入门与原理介绍 💡 什么是 Nuxt 3? Nuxt 3 是基于 Vue 3 和 Vite 打造的全栈前端框架,支持: 服务端渲染(SSR) 静态站点生成(SSG) 单页应用(SPA) 构建全栈应用(支持 API) Nuxt 3 是 Vue 的“加强版”,帮你简化项目结构和开发流程。 🔧 核心原理 功能 Nuxt 如何处理 ✅ 页面路由 自动根…

    个人 2025年4月6日
    1.5K00
  • TS珠峰 002【学习笔记】

    泛型 /* * @Author: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git &a…

    个人 2025年3月27日
    1.2K00
  • 向世界挥手,拥抱无限可能 🌍✨

    站得更高,看到更远 生活就像一座座高楼,我们不断向上攀登,不是为了炫耀高度,而是为了看到更广阔的风景。图中的两位女孩站在城市之巅,伸展双手,仿佛在迎接世界的无限可能。这不仅是一次俯瞰城市的旅程,更是对自由和梦想的礼赞。 勇敢探索,突破边界 每个人的生活都是一场冒险,我们生而自由,就该去探索未知的风景,去经历更多的故事。或许路途中会有挑战,但正是那些攀爬的瞬间…

    个人 2025年2月26日
    93700
  • 深入理解ES6 009【学习笔记】

    javascript中的类 function PersonType(name){ this.name = name; } PersonType.prototype.sayName = function(){ console.log(this.name) } var person = new PersonType("Nicholas") p…

    个人 2025年3月8日
    95600
  • 深入理解ES6 001【学习笔记】

    块级作用域绑定 之前的变量声明var无论在哪里声明的都被认为是作域顶部声明的,由于函数是一等公民,所以顺序一般是function 函数名()、var 变量。 块级声明 块级声明用于声明在指定块的作用域之外无法访问的变量。块级作用域存在于: 函数内部 块中(字符和{和}之间的区域) 临时死区 javascript引擎在扫描代码发现变量声明时,要么将它们提升至作…

    个人 2025年3月8日
    1.3K00

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信
欢迎🌹 Coding never stops, keep learning! 💡💻 光临🌹