最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

一文詳解JavaScript內(nèi)置Symbol方法(含示例)

 更新時間:2025年09月28日 08:30:44   作者:excel  
ES6 引入的 Symbol 類型,除了能自定義唯一標(biāo)識符外,還定義了一批 內(nèi)置 Symbol(Well-known Symbols) ,這些是語言層面的鉤子(hooks),允許開發(fā)者 改變對象在特定場景下的默認(rèn)行為,本文給大家全面解析 JavaScript 內(nèi)置 Symbol 方法,需要的朋友可以參考下

一、概念層

ES6 引入的 Symbol 類型,除了能自定義唯一標(biāo)識符外,還定義了一批 內(nèi)置 Symbol(Well-known Symbols) ,這些是語言層面的“鉤子(hooks)”,允許開發(fā)者 改變對象在特定場景下的默認(rèn)行為。

常見的內(nèi)置 Symbol 有:

  • 轉(zhuǎn)換與類型相關(guān)Symbol.toPrimitive、Symbol.toStringTag
  • 作用域控制Symbol.unscopables
  • 正則相關(guān)Symbol.match、Symbol.replace、Symbol.search、Symbol.split
  • 迭代協(xié)議Symbol.iterator、Symbol.asyncIterator
  • 其它對象行為Symbol.hasInstance、Symbol.isConcatSpreadableSymbol.species

二、原理層(核心作用)

1. Symbol.toPrimitive

  • 控制對象被轉(zhuǎn)為原始值時的行為。
  • 觸發(fā)場景:+、Number(obj)String(obj)。

2. Symbol.toStringTag

  • 控制 Object.prototype.toString.call(obj) 的結(jié)果標(biāo)簽。
  • 默認(rèn):"[object ClassName]",可自定義。

3. Symbol.unscopables

  • 控制 with 語句中哪些屬性被屏蔽。
  • 值為對象 { prop: true } → 屬性不可見。

4. Symbol.match

  • 定義對象在 str.match(obj) 中的行為。
  • 默認(rèn):正則對象調(diào)用 RegExp.prototype[Symbol.match]。

5. Symbol.replace

  • 定義對象在 str.replace(obj, replacement) 中的行為。
  • 默認(rèn):正則對象調(diào)用 RegExp.prototype[Symbol.replace]。

6. Symbol.search

  • 定義對象在 str.search(obj) 中的行為。

7. Symbol.split

  • 定義對象在 str.split(obj) 中的行為。

8. Symbol.iterator

  • 定義對象的默認(rèn)迭代器,使其可被 for...of、解構(gòu)、... 展開使用。

9. Symbol.asyncIterator

  • 定義對象的異步迭代器,支持 for await...of

10. Symbol.hasInstance

  • 控制 obj instanceof Class 的行為。

11. Symbol.isConcatSpreadable

  • 控制數(shù)組/類數(shù)組對象在 concat 時是否展開。

12. Symbol.species

  • 控制派生對象的方法(如 map、filter)返回的構(gòu)造函數(shù)。

三、對比層(表格總結(jié))

Symbol作用觸發(fā)場景默認(rèn)行為
toPrimitive對象轉(zhuǎn)原始值+、Number()、String()調(diào)用 valueOftoString
toStringTag控制 Object.prototype.toString 輸出調(diào)試、類型檢查類名
unscopables屏蔽 with 中屬性with(obj)ES6 隱藏新 API
match自定義匹配str.match(obj)正則匹配
replace自定義替換str.replace(obj, fn)正則替換
search自定義搜索str.search(obj)正則搜索
split自定義分割str.split(obj)正則分割
iterator默認(rèn)迭代器for...of、...數(shù)組迭代
asyncIterator異步迭代器for await...of異步序列
hasInstance控制 instanceofobj instanceof Foo構(gòu)造函數(shù)原型鏈檢查
isConcatSpreadable控制 concat 展開[1,2].concat(obj)數(shù)組默認(rèn)展開
species控制派生返回類型arr.map()原構(gòu)造函數(shù)

四、實踐層(代碼示例 + 注釋)

1. Symbol.toPrimitive

const user = {
  name: "Alice",
  age: 25,
  [Symbol.toPrimitive](hint) {
    if (hint === "number") return this.age;
    if (hint === "string") return this.name;
    return `${this.name}, ${this.age}`;
  }
};

console.log(+user);        // 25
console.log(`${user}`);    // "Alice"
console.log(user + "!");   // "Alice, 25!"

2. Symbol.toStringTag

class Car {
  get [Symbol.toStringTag]() {
    return "SuperCar";
  }
}

console.log(Object.prototype.toString.call(new Car())); 
// [object SuperCar]

3. Symbol.unscopables

const obj = {
  a: 1,
  b: 2,
  [Symbol.unscopables]: { b: true }
};

with (obj) {
  console.log(a); // 1
  // console.log(b); // ReferenceError: b is not defined
}

4. Symbol.match

const matcher = {
  [Symbol.match](str) {
    return str.includes("JS") ? ["JS Found!"] : null;
  }
};

console.log("I love JS".match(matcher)); // ["JS Found!"]
console.log("Hello".match(matcher));     // null

5. Symbol.replace

const replacer = {
  [Symbol.replace](str, replacement) {
    return str.split("bad").join(replacement);
  }
};

console.log("bad code, bad style".replace(replacer, "good"));
// "good code, good style"

6. Symbol.search

const searcher = {
  [Symbol.search](str) {
    return str.indexOf("needle");
  }
};

console.log("Find the needle in haystack".search(searcher)); 
// 9

7. Symbol.split

const splitter = {
  [Symbol.split](str) {
    return str.split(" ").reverse();
  }
};

console.log("one two three".split(splitter)); 
// ["three", "two", "one"]

8. Symbol.iterator

const range = {
  from: 1, to: 3,
  *[Symbol.iterator]() {   // 生成器定義迭代器
    for (let i = this.from; i <= this.to; i++) yield i;
  }
};

console.log([...range]); // [1, 2, 3]

9. Symbol.asyncIterator

const asyncRange = {
  from: 1, to: 3,
  async *[Symbol.asyncIterator]() {
    for (let i = this.from; i <= this.to; i++) {
      await new Promise(r => setTimeout(r, 100)); // 模擬異步
      yield i;
    }
  }
};

(async () => {
  for await (const num of asyncRange) {
    console.log(num); // 1, 2, 3
  }
})();

10. Symbol.hasInstance

class Even {
  static [Symbol.hasInstance](x) {
    return typeof x === "number" && x % 2 === 0;
  }
}

console.log(2 instanceof Even); // true
console.log(3 instanceof Even); // false

11. Symbol.isConcatSpreadable

const arr = [1, 2];
const obj = { 0: "a", 1: "b", length: 2, [Symbol.isConcatSpreadable]: true };

console.log(arr.concat(obj)); // [1, 2, "a", "b"]

12. Symbol.species

class MyArray extends Array {
  static get [Symbol.species]() {
    return Array; // 派生方法返回普通數(shù)組
  }
}

const a = new MyArray(1, 2, 3);
const b = a.map(x => x * 2);

console.log(b instanceof MyArray); // false
console.log(b instanceof Array);   // true

五、拓展層

正則相關(guān) Symbol(match/replace/search/split)

  • 讓對象偽裝成正則,或者實現(xiàn)特殊文本處理邏輯。
  • 比如寫一個“敏感詞替換器”。

與 Proxy 結(jié)合

  • 可以在代理對象里攔截這些 Symbol 鉤子,動態(tài)修改行為。

類庫設(shè)計

  • toPrimitivetoStringTag 常用于類庫,使自定義對象更自然地融入 JS 語法。

六、潛在問題

  • 可讀性下降:過度使用 Symbol 鉤子會讓對象行為難以預(yù)測。
  • 調(diào)試難度增加:如 toPrimitive 的隱式觸發(fā),可能導(dǎo)致詭異結(jié)果。
  • 兼容性unscopableswith 相關(guān),而 with 本身不推薦使用。

? 總結(jié)

  • 轉(zhuǎn)換類toPrimitive、toStringTag、unscopables
  • 正則類match、replacesearch、split
  • 迭代類iterator、asyncIterator
  • 對象行為類hasInstanceisConcatSpreadable、species

這些內(nèi)置 Symbol 就像“魔法鉤子”,能讓對象在不同語境下展現(xiàn)出完全不同的行為。

以上就是一文詳解JavaScript內(nèi)置Symbol方法(含示例)的詳細(xì)內(nèi)容,更多關(guān)于JavaScript內(nèi)置Symbol方法的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • js實現(xiàn)右鍵菜單功能

    js實現(xiàn)右鍵菜單功能

    這篇文章主要為大家詳細(xì)介紹了js實現(xiàn)右鍵菜單功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-11-11
  • js 自帶的sort() 方法全面了解

    js 自帶的sort() 方法全面了解

    下面小編就為大家?guī)硪黄猨s 自帶的sort() 方法全面了解。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-08-08
  • Bootstrap編寫一個兼容主流瀏覽器的受眾門戶式風(fēng)格頁面

    Bootstrap編寫一個兼容主流瀏覽器的受眾門戶式風(fēng)格頁面

    這篇文章主要介紹了Bootstrap編寫一個兼容IE8、谷歌等主流瀏覽器的受眾門戶式風(fēng)格頁面,感興趣的小伙伴們可以參考一下
    2016-07-07
  • Webpack性能優(yōu)化 DLL 用法詳解

    Webpack性能優(yōu)化 DLL 用法詳解

    本篇文章主要介紹了Webpack DLL 用法詳解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-08-08
  • js拖拽一些常見的思路方法整理

    js拖拽一些常見的思路方法整理

    這篇文章主要介紹了js拖拽一些常見的思路方法,需要的朋友可以參考下
    2014-03-03
  • JavaScript設(shè)計模式之裝飾者模式介紹

    JavaScript設(shè)計模式之裝飾者模式介紹

    這篇文章主要介紹了JavaScript設(shè)計模式之裝飾者模式介紹,通一個類來動態(tài)的對另一個類的功能對象進(jìn)行前或后的修飾,給它輔加一些額外的功能; 這是對一個類對象功能的裝飾,裝飾的類跟被裝飾的類,要求擁有相同的訪問接口方法(功能),需要的朋友可以參考下
    2014-12-12
  • 使用JS前端技術(shù)實現(xiàn)靜態(tài)圖片局部流動效果

    使用JS前端技術(shù)實現(xiàn)靜態(tài)圖片局部流動效果

    本文使用前端開發(fā)技術(shù),結(jié)合?SVG?和?CSS?來實現(xiàn)類似的液化流動效果,包含的知識點主要包括:mask-image?遮罩、feTurbulence?和?feDisplacementMap?濾鏡、filter?屬性、canvas?繪制方法、TimelineMax?動畫及input[type=file]?本地圖片資源加載,需要的朋友可以參考下
    2022-08-08
  • JavaScript數(shù)據(jù)類型檢測代碼分享

    JavaScript數(shù)據(jù)類型檢測代碼分享

    這篇文章主要向大家分享了一段JavaScript實現(xiàn)數(shù)據(jù)類型檢測的代碼,附上參數(shù)說明和使用說明,希望小伙伴們能夠喜歡
    2015-01-01
  • CSS(js)限制頁面顯示的文本字符長度

    CSS(js)限制頁面顯示的文本字符長度

    限制頁面顯示的字符長度,一直被眾多網(wǎng)友傾睬,本人也是一fans利用閑暇時間搜集整理了一些實用技巧,需要了解的朋友可以參考下
    2012-12-12
  • php析構(gòu)函數(shù)的具體用法小結(jié)

    php析構(gòu)函數(shù)的具體用法小結(jié)

    本篇文章主要是對php析構(gòu)函數(shù)的具體用法進(jìn)行了詳細(xì)的介紹,需要的朋友可以過來參考下,希望對大家有所幫助
    2014-03-03

最新評論

嘉峪关市| 江达县| 页游| 贡觉县| 磴口县| 长顺县| 满城县| 临沭县| 灌阳县| 襄汾县| 油尖旺区| 昔阳县| 新野县| 治多县| 镇平县| 德江县| 峡江县| 锡林浩特市| 三门县| 玉屏| 图片| 临高县| 巴东县| 阿巴嘎旗| 札达县| 莒南县| 柞水县| 远安县| 稻城县| 阿巴嘎旗| 阿拉善左旗| 全椒县| 津市市| 龙岩市| 新泰市| 多伦县| 高要市| 寿光市| 浦县| 莎车县| 镶黄旗|