在 ECMAScript 2015 中,我们认识了一种新的基本数据类型 Symbol(符号) 。在 ECMAScript 2019 中,Symbol 得到了更多的新概念、新特性以及更广泛的应用场景。本文主要介绍 ECMAScript 2019 中关于 Symbol 的新概念与用法,旨在帮助前端开发者更好地理解 Symbol,掌握它的使用方法,提高开发效率和代码质量。
Symbol 的定义和基本用法
Symbol 是 ECMAScript 6 中引入的一种新的基本数据类型,表示一个独一无二的值。它通过 Symbol() 函数创建一个独一无二的值,在使用时可以通过变量名来访问。
--- ---- - --------- --- ---- - --------- ---------------- --- ------ -- ----- --- --- - - ------- ------- -- ----------------------- -- --------- ----------------------- -- -------
在上面的代码中,我们创建了两个 Symbol 类型的变量 sym1 和 sym2,由于每个 Symbol 的值都是独一无二的,因此两个变量的值也不相等。使用 Symbol() 函数创建的值是不能通过文字或表达式来创建的,只能通过函数来创建。
Symbol 的新概念
在 ECMAScript 2019 中,Symbol 得到了更多的新概念,包括如下几种。
Symbol.hasInstance
Symbol.hasInstance 属性是一个函数,用来判断一个对象是否为另一个对象的实例。
----- --- - ------ ------------------------- - ------ --- ---------- ------ - - -------------- ---------- ----- -- ---- --- --- - --- --------------- ---------- ----- -- -----
在上面的代码中,我们创建了一个类 Foo,并定义了 Symbol.hasInstance 属性,通过该属性让 JavaScript 引擎在检查 obj instanceof Foo 时使用该函数进行判断。由于 [] 是一个数组,因此它是 Foo 的一个实例,而 obj 不是一个数组,因此它不是 Foo 的实例。
Symbol.asyncIterator
Symbol.asyncIterator 属性是一个函数,表示一个异步迭代器接口,用于定义异步遍历的行为。
----- --- - --- -- --- ----- -------- ------ - --- ----- ------ ----- -- ---- - ------------------- - - -------
在上面的代码中,我们通过 for await...of 循环遍历一个数组,并使用 Symbol.asyncIterator 属性来表示该数组是一个异步迭代器。
Symbol.match
Symbol.match 属性是一个函数,用于确定一个对象是否具有正则表达式的匹配能力。
----- --- - ------------------- - ------ ------------------ --- --- - - ------------------------------ -------- -- ---- --------------------------- -------- -- -----
在上面的代码中,我们创建了一个类 Foo,并定义了 Symbol.match 属性,通过该属性让 JavaScript 引擎在进行正则表达式匹配时使用该函数进行判断。由于 "foobar" 中包含 "foo",因此它符合 Foo 的匹配规则,而 "bar" 不包含 "foo",因此不符合匹配规则。
Symbol.replace
Symbol.replace 属性与 Symbol.match 属性相对应,用于将一个字符串中符合某种条件的文本替换成另一个文本。
----- --- - --------------------- ------------ - ------ ------------------- ------------- - - -------------------------------- ------ ---------- -- ----------
在上面的代码中,我们创建了一个类 Foo,并定义了 Symbol.replace 属性,通过该属性让 JavaScript 引擎在进行字符串替换时使用该函数进行判断。由于 "foobar" 中包含 "foo",因此它符合 Foo 的替换规则,替换成了 "hello",最终输出 "helloBar"。
Symbol.search
Symbol.search 属性用于确定一个对象是否可以被用作字符串匹配的目标。
----- --- - -------------------- - ------ ------------------- - - ------------------------------- -------- -- - ---------------------------- -------- -- --
在上面的代码中,我们创建了一个类 Foo,并定义了 Symbol.search 属性,通过该属性让 JavaScript 引擎在进行字符串搜索时使用该函数进行判断。由于 "foobar" 中包含 "foo",因此它符合 Foo 的匹配规则,搜索到了 "foo" 的位置 0,而 "bar" 不包含 "foo",因此没有搜索到。
Symbol.species
Symbol.species 属性是一个函数,用于创建导致派生对象的默认构造函数。它在 Array.prototype.map()、Array.prototype.filter()、Array.prototype.slice() 等方法里应用非常广泛。通过 Symbol.species 属性,我们可以指定一个函数,用于在方法调用时创建一个新的派生对象。
----- ------- ------- ----- - ------ --- ------------------ - ------ ------ - - ----- ------- - --- ---------- -- --- ----- -------- - ----------------- -- ----- - --- -------------------- ---------- --------- -- ----- -------------------- ---------- ------- -- ----
在上面的代码中,我们创建了一个 MyArray 类,继承了 Array 类,并定义了 Symbol.species 属性。Map 方法在对输出值类型的计算时,将使用这个符号属性来决定返回值的类型。而在MyArray 类中,我们通过 Symbol.species 属性指定了 Array 构造函数,因此 map 的返回值为一个新的 Array 对象。
Symbol 的应用场景
Symbol 的应用非常广泛,可以用于对象属性名、私有属性(使用 Symbol 的结果会使这个变量更像私有变量)、类方法及原型方法的定义等多个方面。下面列举一些常见的应用场景。
防止属性名冲突
在 JavaScript 中,对象的属性名都是字符串。如果多个对象的属性名相同,可能会导致冲突。而使用 Symbol,则可以保证属性名不会重复。
----- ---- - - ----------------- ------- -- ----- ---- - - ----------------- ------- -- ---------------- --- ------ -- -----
自定义迭代器
使用 Symbol.iterator 属性可以自定义迭代器。
----- ---------- - - ------------------- - --- - - -- ------ - ------ - -- -- - -- - ------ - ------ ---- ----- ----- -- - ---- - ------ - ------ ---------- ----- ---- -- - - -- - -- --- ------ ----- -- ----------- - ------------------- -
在上面的代码中,我们定义了一个 myIterable 对象,并在该对象上添加 Symbol.iterator 属性,表示该对象可以被迭代。使用 for...of 循环遍历该对象时,会逐个输出该对象的值。
私有属性实现
使用 Symbol 可以实现类似于私有属性的功能,因为使用 Symbol 的结果会使这个变量更像私有变量,无法被直接访问。
----- ---- - --------------- ----- ------ - ------------- - ---------- - ------ - --------- - ------ ----------- - - ----- ------ - --- --------- ------------------------------ -- --- ------------------------- -- ---------
在上面的代码中,我们通过 Symbol 键定义了一个私有属性,只能通过类中的方法来访问。
总结
在 ECMAScript 2019 中,Symbol 收到了更广泛的应用,如 Symbol.hasInstance、Symbol.asyncIterator、Symbol.match 等等。通过本文的讲解,了解了 Symbol 的新概念、用法和应用场景,相信对前端开发者来说都是非常有意义的。在实际开发中,合理使用 Symbol,可以帮助我们提高代码的可读性和可维护性。
来源:JavaScript中文网 ,转载请联系管理员! 本文地址:https://www.javascriptcn.com/post/64fe6bd095b1f8cacdd3225d