Ini adalah dua baris kod yang diekstrak var name = Symbol('test') 一直提示 无法转换,是关键字保留?还是其他原因? 为什么换一个var name1 = Symbol('test')却可以通过编译? 其他普通的var s1 s2Ia juga boleh disusun.
Persoalan ini agak menarik Saya tidak pernah menyedarinya Setelah melihat melalui maklumat, saya mendapati bahawa banyak perkara datang secara kebetulan, dan masalah ini muncul. Tepatnya, ia adalah 浏览器的默认行为和JavaScript的隐式类型变换menyusahkan.
Mari kita pergi langkah demi langkah, pertama sekali, apakah perbezaan antara var和let?
Atribut name dalam baris terakhir di sini tidak mempunyai awalan read only, menunjukkan bahawa ia boleh dibaca dan boleh ditulis, dan jenis datanya ialah DOMString. name属性在这里的最后一行,没有readonly的前缀,说明它是可读可写的,它的数据类型则是DOMString。 DOMString是指UTF-16的字符串,在JavaScript中它会直接映射到StringDOMString merujuk kepada rentetan UTF-16, yang dipetakan terus kepada String dalam JavaScript.
Jadi apabila kita memberi window.name赋值的时候,这个值会被强制转换为String.
Kita boleh mencubanya:
var name = { a:1, b:2 };
console.log(window.name); // [object Object]
var name = [0, 1, 2, 3];
console.log(window.name); // 0,1,2,3
Anda mungkin boleh meneka apabila anda tiba di sini, var name = Symbol('test');的错误,应该是Symbol变量在做类型转换的时候出了问题。而实际报的错误也证实了我们的猜测:TypeError: Cannot convert a Symbol value to a string.
Walau bagaimanapun, ia nampaknya tidak betul SymbolPembolehubah boleh ditukar kepada rentetan, contohnya:
let test = Symbol('test');
console.log(test.toString()); // Symbol(test)
console.log(String(test)); // Symbol(test)
Nah, ini adalah klise penukaran jenis tersirat JavaScript dan hantaran eksplisit adalah berbeza untuk beberapa pembolehubah. Malangnya, ini berlaku di sini Symbol.
Symbol被隐式的转换时,它会首先调用其内部的ToPrimitive接口,拿到其原始值,然后在其中再调用ToString函数转换为字符串。注意,这里的这个ToString函数是其内部的抽象方法,和暴露在外的Symbol.prototype.toString()Apabila ia ditukar secara tersirat, ia akan memanggil antara muka ToPrimitive dalamannya untuk mendapatkan nilai asalnya, dan kemudian memanggil fungsi ToString untuk menukarnya kepada rentetan. Ambil perhatian bahawa fungsi ToString di sini ialah kaedah abstrak dalamannya dan bukan perkara yang sama dengan Symbol.prototype.toString() yang terdedah.
Untuk pembolehubah Symbol变量而言,当其调用ToString, ralat akan dilaporkan apabila ia memanggil ToString Saya tidak akan pergi ke butiran lanjut Jika anda berminat, anda boleh membaca sendiri spesifikasi: ToString (argumen).
Saya baru sahaja mencubanya pada konsol, ia sememangnya BUG yang sangat menakjubkan, tetapi anda akan
var name = Symbol("test");
//改成
let name = Symbol("test"); //试试。。
Kemudian saya terkejut apabila mendapati bahawa BUG telah hilang semula. . Saya rasa ia ada kaitan dengan cara pelayar menghuraikan sintaks, tetapi saya tidak faham perkara ini.
nama ialah atribut unik tetingkap Sebarang nilai yang diberikan kepada pembolehubah nama dalam persekitaran global akan ditukar secara automatik kepada rentetan Walau bagaimanapun, jenis Simbol tidak boleh ditukar terus kepada rentetan, jadi ralat dilaporkan.
Persoalan ini agak menarik Saya tidak pernah menyedarinya Setelah melihat melalui maklumat, saya mendapati bahawa banyak perkara datang secara kebetulan, dan masalah ini muncul. Tepatnya, ia adalah
浏览器的默认行为
和JavaScript的隐式类型变换
menyusahkan.Mari kita pergi langkah demi langkah, pertama sekali, apakah perbezaan antara
Sifatvar
和let
?var
声明的变量会被提升至当前函数作用域顶端,如果是在全局那么这个变量将会成为window
的一个属性。而对于
let
声明的变量,它会将变量提升至当前块级作用域,并且如果是在全局,当前变量也不会成为window
.Jadi, dalam gambaran besar perkara seperti ini berlaku:
Kemudian, adakah
name
为名的变量和别的变量有什么区别?上面我们知道了,
var name = 'test1';
实际上可以等同于window.name = 'test1'
,很容易就能想到,name
perkataan simpanan tetap?Melihat melalui spesifikasi, memang benar. Beberapa antara muka
window.name
属性表示的是当前窗口上下文的名称。下面是window
:Atribut
name
dalam baris terakhir di sini tidak mempunyai awalanread only
, menunjukkan bahawa ia boleh dibaca dan boleh ditulis, dan jenis datanya ialahDOMString
.name
属性在这里的最后一行,没有readonly
的前缀,说明它是可读可写的,它的数据类型则是DOMString
。DOMString
是指UTF-16的字符串,在JavaScript中它会直接映射到String
DOMString
merujuk kepada rentetan UTF-16, yang dipetakan terus kepadaString
dalam JavaScript.Jadi apabila kita memberi
window.name
赋值的时候,这个值会被强制转换为String
.Kita boleh mencubanya:
Anda mungkin boleh meneka apabila anda tiba di sini,
var name = Symbol('test');
的错误,应该是Symbol
变量在做类型转换的时候出了问题。而实际报的错误也证实了我们的猜测:TypeError: Cannot convert a Symbol value to a string
.Walau bagaimanapun, ia nampaknya tidak betul
Symbol
Pembolehubah boleh ditukar kepada rentetan, contohnya:Nah, ini adalah klise penukaran jenis tersirat JavaScript dan hantaran eksplisit adalah berbeza untuk beberapa pembolehubah. Malangnya, ini berlaku di sini
Symbol
.Symbol
被隐式的转换时,它会首先调用其内部的ToPrimitive
接口,拿到其原始值,然后在其中再调用ToString
函数转换为字符串。注意,这里的这个ToString
函数是其内部的抽象方法,和暴露在外的Symbol.prototype.toString()
Apabila ia ditukar secara tersirat, ia akan memanggil antara mukaToPrimitive
dalamannya untuk mendapatkan nilai asalnya, dan kemudian memanggil fungsiToString
untuk menukarnya kepada rentetan. Ambil perhatian bahawa fungsiToString
di sini ialah kaedah abstrak dalamannya dan bukan perkara yang sama denganSymbol.prototype.toString()
yang terdedah.Untuk pembolehubah
Symbol
变量而言,当其调用ToString
, ralat akan dilaporkan apabila ia memanggilToString
Saya tidak akan pergi ke butiran lanjut Jika anda berminat, anda boleh membaca sendiri spesifikasi: ToString (argumen).Saya baru sahaja mencubanya pada konsol, ia sememangnya BUG yang sangat menakjubkan, tetapi anda akan
Kemudian saya terkejut apabila mendapati bahawa BUG telah hilang semula. . Saya rasa ia ada kaitan dengan cara pelayar menghuraikan sintaks, tetapi saya tidak faham perkara ini.
nama ialah atribut unik tetingkap Jika anda cuba menukar pembolehubah, anda tidak akan mendapat ralat. . .
nama ialah atribut unik tetingkap Sebarang nilai yang diberikan kepada pembolehubah nama dalam persekitaran global akan ditukar secara automatik kepada rentetan Walau bagaimanapun, jenis Simbol tidak boleh ditukar terus kepada rentetan, jadi ralat dilaporkan.
Anda boleh
Anda akan tahu.