Rumah  >  Artikel  >  hujung hadapan web  >  Mengapa terdapat jenis Simbol? Bagaimana untuk menggunakan

Mengapa terdapat jenis Simbol? Bagaimana untuk menggunakan

青灯夜游
青灯夜游ke hadapan
2022-03-22 11:04:512685semak imbas

Apakah itu Simbol? Mengapa ada perkara sedemikian? Artikel berikut akan memperkenalkan anda kepada jenis Simbol dalam JavaScript dan bercakap tentang cara menggunakannya. Saya harap ia akan membantu anda!

Mengapa terdapat jenis Simbol? Bagaimana untuk menggunakan

Apakah Simbol? Mengapa ada perkara sedemikian?

Simbol (simbol) ialah jenis data baharu yang ditambahkan dalam ES6. Simbol ialah nilai primitif (jenis data asas), dan contoh Simbol adalah unik dan tidak boleh diubah. Ia dijana kerana ia digunakan untuk menandakan secara unik dan kemudian digunakan sebagai atribut objek dalam bentuk bukan rentetan untuk memastikan atribut objek menggunakan pengecam unik tanpa risiko konflik atribut. [Cadangan berkaitan: Tutorial pembelajaran javascript]

Penggunaan

1 Perlu dimulakan menggunakan fungsi Symbol(). Oleh kerana simbol itu sendiri adalah jenis primitif, operator jenis mengembalikan simbol pada simbol.

Fungsi Symbol() boleh menerima parameter rentetan untuk diterangkan, dan kemudian anda boleh menggunakan rentetan ini untuk nyahpepijat kod. Tetapi perlu diingat bahawa walaupun berbilang fungsi Symbol() menerima parameter yang sama, nilainya tidak sama.

let sym = Symbol();
console.log(typeof sym); // symbol

2 Gunakan pendaftaran simbol global
let genericSymbol = Symbol();
let otherGenericSymbol = Symbol();
let fooSymbol = Symbol("foo");
let otherFooSymbol = Symbol("foo");

console.log(genericSymbol == otherGenericSymbol); // false
console.log(fooSymbol == otherFooSymbol); // false

Jika anda perlu menggunakan contoh Simbol yang sama dalam berbilang tempat dalam kod, anda boleh menghantar aksara. rentetan, dan kemudian gunakan kaedah Symbol.for() untuk mencipta Simbol yang boleh diguna semula, serupa dengan mod tunggal Apabila menggunakan Symbol.for() buat kali pertama, ia akan mencari secara global berdasarkan parameter yang diluluskan. Sama ada sama. instance telah dibuat menggunakan Symbol.for(), jika ya, gunakan semula, jika tidak, buat tika baharu yang dicipta oleh

Symbol.for() dan Symbol() Perbezaan dalam keadaan :
let fooGlobalSymbol = Symbol.for("foo"); // 创建新符号
let otherFooGlobalSymbol = Symbol.for("foo"); // 重用已有符号
console.log(fooGlobalSymbol === otherFooGlobalSymbol); // true
Kejadian yang dibuat oleh Symbol() sentiasa unik dan tidak akan sama dengan kejadian lain hanya kerana parameter yang anda lalui adalah sama Walau bagaimanapun, jika tika yang dibuat oleh Symbol.for() mempunyai parameter yang sama, mereka akan menjadi sama, kerana mereka akan berkongsi contoh Simbol yang sama

3 Gunakan simbol sebagai atribut
let fooSymbol = Symbol("foo");
let otherFooSymbol = Symbol("foo");
console.log(fooSymbol == otherFooSymbol); // false

let fooGlobalSymbol = Symbol.for("foo"); // 创建新符号
let otherFooGlobalSymbol = Symbol.for("foo"); // 重用已有符号
console.log(fooGlobalSymbol === otherFooGlobalSymbol); // true

Atribut dalam objek biasanya dalam bentuk. strings , tetapi sebenarnya anda juga boleh menggunakan contoh Symbol sebagai atribut Kelebihannya ialah atribut baharu anda tidak akan menimpa sebarang atribut sebelumnya

Nota:
let s1 = Symbol("foo"),
  s2 = Symbol("bar"),
  s3 = Symbol("baz"),
  s4 = Symbol("qux");
let o = {
  [s1]: "foo val",
};
// 这样也可以:o[s1] = 'foo val';
console.log(o);
// {Symbol(foo): foo val}
Object.defineProperty(o, s2, { value: "bar val" });
console.log(o);
// {Symbol(foo): foo val, Symbol(bar): bar val}
Object.defineProperties(o, {
  [s3]: { value: "baz val" },
  [s4]: { value: "qux val" },
});
console.log(o);
// {Symbol(foo): foo val, Symbol(bar): bar val,
// Symbol(baz): baz val, Symbol(qux): qux val}
Buat tika Symbol. Apabila digunakan sebagai atribut objek, jika simbol ditukar tanpa mengisytiharkan pembolehubah untuk penerimaan pada permulaan, maka semua atribut simbol objek mesti dilalui untuk mencari kunci atribut yang sepadan:

4. Simbol terbina dalam yang biasa digunakan
let o = {
  [Symbol("foo")]: "foo val",
  [Symbol("bar")]: "bar val",
};
console.log(o);
// {Symbol(foo): "foo val", Symbol(bar): "bar val"}
let barSymbol = Object.getOwnPropertySymbols(o).find(symbol => symbol.toString().match(/bar/));
console.log(barSymbol);
// Symbol(bar)

ES6 juga memperkenalkan beberapa simbol terbina dalam yang biasa digunakan (simbol yang terkenal) untuk mendedahkan tingkah laku dalaman bahasa yang boleh diakses oleh Pembangun. mengatasi atau mensimulasikan tingkah laku ini. Jika atribut lalai ini diubah suai, hasil pelaksanaan akhir beberapa operasi boleh diubah. Sebagai contoh, gelung for-of menggunakan sifat Symbol.iterator pada objek yang berkaitan, jadi anda boleh menukar tingkah laku for-of apabila melelaran objek dengan mentakrifkan semula nilai Symbol.iterator pada objek tersuai.

5. Symbol.asyncIterator

sebenarnya adalah Penjana yang mengembalikan Janji, biasanya digunakan untuk menunggu

6. hasInstance

Mengikut spesifikasi ECMAScript, simbol ini sebagai atribut mewakili "kaedah yang mengembalikan AsyncIterator lalai objek. Digunakan oleh pernyataan menunggu-menunggu." Dalam erti kata lain, simbol ini mewakili fungsi yang melaksanakan API lelaran tak segerak.

Harta ini ditakrifkan pada prototaip Fungsi. Kita semua tahu bahawa pengendali instanceof boleh digunakan untuk menentukan sama ada contoh objek kepunyaan pembina tertentu. Prinsipnya ialah operator instanceof akan menggunakan fungsi Symbol.hasInstance untuk menentukan hubungan

Jika anda mentakrifkan semula sifat Symbol.hasInstance bagi sesuatu fungsi, anda boleh membenarkan kaedah instanceof mengembalikan sesuatu yang tidak dijangka

function Foo() {}
let f = new Foo();
console.log(f instanceof Foo); // true
class Bar {}
let b = new Bar();
console.log(b instanceof Bar); // true

Symbol.isConcatSpreadabl
class Bar {}
class Baz extends Bar {
  static [Symbol.hasInstance]() {
    return false;
  }
}
let b = new Baz();
console.log(Bar[Symbol.hasInstance](b)); // true
console.log(b instanceof Bar); // true
console.log(Baz[Symbol.hasInstance](b)); // false
console.log(b instanceof Baz); // false

Harta ini ditakrifkan pada prototaip Array

Mengikut spesifikasi ECMAScript, simbol ini sebagai atribut mewakili " Nilai Boolean, jika benar, bermakna objek harus meratakan elemen tatasusunannya menggunakan Array.prototype.concat()". Kaedah Array.prototype.concat() dalam ES6 akan Pilih cara menyambung objek seperti tatasusunan (susunan semu) ke dalam contoh tatasusunan berdasarkan jenis objek yang diterima. Jadi mengubah suai nilai Symbol.isConcatSpreadable boleh mengubah suai tingkah laku ini.

Symbol.isConcatSpreadable Kesan sepadan

false:

Tambah keseluruhan objek pada tatasusunan

true: Tambah keseluruhan objek Tambahkan pasangan pada tatasusunan

8 Symbol.iterator
let initial = ["foo"];
let array = ["bar"];
console.log(array[Symbol.isConcatSpreadable]); // undefined
console.log(initial.concat(array)); // ['foo', 'bar']
array[Symbol.isConcatSpreadable] = false;
console.log(initial.concat(array)); // ['foo', Array(1)]
let arrayLikeObject = { length: 1, 0: "baz" };
console.log(arrayLikeObject[Symbol.isConcatSpreadable]); // undefined
console.log(initial.concat(arrayLikeObject)); // ['foo', {...}]

arrayLikeObject[Symbol.isConcatSpreadable] = true;
console.log(initial.concat(arrayLikeObject)); // ['foo', 'baz']
let otherObject = new Set().add("qux");
console.log(otherObject[Symbol.isConcatSpreadable]); // undefined
console.log(initial.concat(otherObject)); // ['foo', Set(1)]
otherObject[Symbol.isConcatSpreadable] = true;
console.log(initial.concat(otherObject)); // ['foo']

Menurut spesifikasi ECMAScript, simbol ini sebagai atribut mewakili "kaedah yang mengembalikan objek. Peulang lalai yang digunakan oleh bagi-bagi pernyataan"

该属性会返回一个 Generator 函数,for of 就会依次的去调用 next()方法,这就是为什么 for of 可以使用在某些对象身上。

class Emitter {
  constructor(max) {
    this.max = max;
    this.idx = 0;
  }
  *[Symbol.iterator]() {
    while (this.idx < this.max) {
      yield this.idx++;
    }
  }
}
function count() {
  let emitter = new Emitter(5);
  for (const x of emitter) {
    console.log(x);
  }
}
count();
// 0
// 1
// 2
// 3
// 4

9. Symbol.match

根据 ECMAScript 规范,这个符号作为一个属性表示“一个正则表达式方法,该方法用正则表达式去匹配字符串。由 String.prototype.match()方法使用”。

String.prototype.match()方法会使用以 Symbol.match 为键的函数来对正则表达式求值。所以更改一个正则表达式的 Symbol.match 属性,可以让 String.prototype.match()得到你想要的值

console.log(RegExp.prototype[Symbol.match]);
// ƒ [Symbol.match]() { [native code] }
console.log("foobar".match(/bar/));
// ["bar", index: 3, input: "foobar", groups: undefined]

class FooMatcher {
  static [Symbol.match](target) {
    return target.includes("foo");
  }
}
console.log("foobar".match(FooMatcher)); // true
console.log("barbaz".match(FooMatcher)); // false
class StringMatcher {
  constructor(str) {
    this.str = str;
  }
  [Symbol.match](target) {
    return target.includes(this.str);
  }
}
console.log("foobar".match(new StringMatcher("foo"))); // true
console.log("barbaz".match(new StringMatcher("qux"))); // false

11. Symbol.search

这个符号作为一个属性表示“一个正则表达式方法,该方法返回字符串中 匹配正则表达式的索引。由 String.prototype.search()方法使用”

12. Symbol.species

这个符号作为一个属性表示“一个函数值,该函数作为创建派生对象的构 造函数”。

13. Symbol.split

这个符号作为一个属性表示“一个正则表达式方法,该方法在匹配正则表 达式的索引位置拆分字符串。由 String.prototype.split()方法使用”。

14. Symbol.toPrimitive

这个符号作为一个属性表示“一个方法,该方法将对象转换为相应的原始 值。由 ToPrimitive 抽象操作使用”

15. Symbol.toStringTag

这个符号作为一个属性表示“一个字符串,该字符串用于创建对象的默认 字符串描述。由内置方法 Object.prototype.toString()使用”

16. Symbol.unscopables

这个符号作为一个属性表示“一个对象,该对象所有的以及继承的属性, 都会从关联对象的 with 环境绑定中排除

更多编程相关知识,请访问:编程视频!!

Atas ialah kandungan terperinci Mengapa terdapat jenis Simbol? Bagaimana untuk menggunakan. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:juejin.cn. Jika ada pelanggaran, sila hubungi admin@php.cn Padam