javascript技巧

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript技巧 > JavaScript内置Symbol方法

一文详解JavaScript内置Symbol方法(含示例)

作者:excel

ES6 引入的 Symbol 类型,除了能自定义唯一标识符外,还定义了一批 内置 Symbol(Well-known Symbols) ,这些是语言层面的钩子(hooks),允许开发者 改变对象在特定场景下的默认行为,本文给大家全面解析 JavaScript 内置 Symbol 方法,需要的朋友可以参考下

一、概念层

ES6 引入的 Symbol 类型,除了能自定义唯一标识符外,还定义了一批 内置 Symbol(Well-known Symbols) ,这些是语言层面的“钩子(hooks)”,允许开发者 改变对象在特定场景下的默认行为

常见的内置 Symbol 有:

二、原理层(核心作用)

1. Symbol.toPrimitive

2. Symbol.toStringTag

3. Symbol.unscopables

4. Symbol.match

5. Symbol.replace

6. Symbol.search

7. Symbol.split

8. Symbol.iterator

9. Symbol.asyncIterator

10. Symbol.hasInstance

11. Symbol.isConcatSpreadable

12. Symbol.species

三、对比层(表格总结)

Symbol作用触发场景默认行为
toPrimitive对象转原始值+Number()String()调用 valueOftoString
toStringTag控制 Object.prototype.toString 输出调试、类型检查类名
unscopables屏蔽 with 中属性with(obj)ES6 隐藏新 API
match自定义匹配str.match(obj)正则匹配
replace自定义替换str.replace(obj, fn)正则替换
search自定义搜索str.search(obj)正则搜索
split自定义分割str.split(obj)正则分割
iterator默认迭代器for...of...数组迭代
asyncIterator异步迭代器for await...of异步序列
hasInstance控制 instanceofobj instanceof Foo构造函数原型链检查
isConcatSpreadable控制 concat 展开[1,2].concat(obj)数组默认展开
species控制派生返回类型arr.map()原构造函数

四、实践层(代码示例 + 注释)

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; // 派生方法返回普通数组
  }
}

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

五、拓展层

正则相关 Symbol(match/replace/search/split)

与 Proxy 结合

类库设计

六、潜在问题

总结

这些内置 Symbol 就像“魔法钩子”,能让对象在不同语境下展现出完全不同的行为。

以上就是一文详解JavaScript内置Symbol方法(含示例)的详细内容,更多关于JavaScript内置Symbol方法的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文