84669 人が学習中
152542 人が学習中
20005 人が学習中
5487 人が学習中
7821 人が学習中
359900 人が学習中
3350 人が学習中
180660 人が学習中
48569 人が学習中
18603 人が学習中
40936 人が学習中
1549 人が学習中
1183 人が学習中
32909 人が学習中
これらは抽出された 2 行のコードです var name = Symbol('test') 変換できないというメッセージが表示され続けます。キーワードは予約されていますか?それとも他の理由でしょうか? var name1 = Symbol('test') を変更するとコンパイルできるのはなぜですか? その他の通常の var s1 s2 もコンパイルできます。
var name = Symbol('test')
var name1 = Symbol('test')
var s1 s2
この質問は非常に興味深いもので、私はこれまで気付かなかったのですが、情報を調べてみると、多くのことが偶然に重なって、この問題が現れました。正確に言うと、浏览器的默认行为和JavaScript的隐式类型变换トラブルでした。
浏览器的默认行为
隐式类型变换
ステップバイステップで行きましょう、まず第一に、var和letの違いは何ですか?
var
let
var声明的变量会被提升至当前函数作用域顶端,如果是在全局那么这个变量将会成为window的一个属性。 而对于let声明的变量,它会将变量提升至当前块级作用域,并且如果是在全局,当前变量也不会成为windowのプロパティ。
window
つまり、全体像としては次のようなことが起こります:
では、name为名的变量和别的变量有什么区别? 上面我们知道了,var name = 'test1';实际上可以等同于window.name = 'test1',很容易就能想到,nameは固定の予約語なのでしょうか?
name
var name = 'test1';
window.name = 'test1'
仕様を見ると、それは本当です。 window.name属性表示的是当前窗口上下文的名称。下面是windowのいくつかのインターフェース:
window.name
ここの最後の行の name 属性にはプレフィックス readonly がありません。これは、読み取りおよび書き込み可能であり、データ型が DOMString であることを示しています。 >。 name属性在这里的最后一行,没有readonly的前缀,说明它是可读可写的,它的数据类型则是DOMString。 DOMString是指UTF-16的字符串,在JavaScript中它会直接映射到StringDOMString は UTF-16 文字列を指し、JavaScript の String に直接マッピングされます。
readonly
DOMString
String
それで私たちがwindow.name赋值的时候,这个值会被强制转换为Stringを与えるとき。
試してみましょう:
ここに来たらもうおわかりでしょう、var name = Symbol('test');的错误,应该是Symbol变量在做类型转换的时候出了问题。而实际报的错误也证实了我们的猜测:TypeError: Cannot convert a Symbol value to a string。
var name = Symbol('test');
Symbol
TypeError: Cannot convert a Symbol value to a string
しかし、それは正しくないようです。 Symbol 変数は次のように文字列に変換できます。 リーリー
。 Symbol
暗黙的に変換される場合、最初に内部の ToPrimitive インターフェイスを呼び出して元の値を取得し、次に ToString 関数を呼び出して文字列に変換します。ここでの ToString 関数はその内部抽象メソッドであり、公開された Symbol.prototype.toString() と同じものではないことに注意してください。 Symbol被隐式的转换时,它会首先调用其内部的ToPrimitive接口,拿到其原始值,然后在其中再调用ToString函数转换为字符串。注意,这里的这个ToString函数是其内部的抽象方法,和暴露在外的Symbol.prototype.toString()
ToPrimitive
ToString
Symbol.prototype.toString()
コンソールで試してみました。確かに非常に素晴らしいバグですが、あなたもそうするでしょう
その後、バグが再び消えていることに気づき、驚きました。 。ブラウザが構文を解析する方法に関係があると思いますが、私はこれらのことを理解していません。
name は window の一意の属性です。変数を変更しようとしても、エラーは発生しません。 。 。
name は window の一意の属性です。グローバル環境で name 変数に割り当てられた値は自動的に文字列に変換されますが、Symbol タイプは直接文字列に変換できないため、エラーが報告されます。
できます
わかるでしょう。
この質問は非常に興味深いもので、私はこれまで気付かなかったのですが、情報を調べてみると、多くのことが偶然に重なって、この問題が現れました。正確に言うと、
浏览器的默认行为
和JavaScript的隐式类型变换
トラブルでした。ステップバイステップで行きましょう、まず第一に、
var
和let
の違いは何ですか?var
声明的变量会被提升至当前函数作用域顶端,如果是在全局那么这个变量将会成为window
的一个属性。而对于
let
声明的变量,它会将变量提升至当前块级作用域,并且如果是在全局,当前变量也不会成为window
のプロパティ。つまり、全体像としては次のようなことが起こります:
リーリーでは、
name
为名的变量和别的变量有什么区别?上面我们知道了,
var name = 'test1';
实际上可以等同于window.name = 'test1'
,很容易就能想到,name
は固定の予約語なのでしょうか?仕様を見ると、それは本当です。
リーリーwindow.name
属性表示的是当前窗口上下文的名称。下面是window
のいくつかのインターフェース:ここの最後の行の
name
属性にはプレフィックスreadonly
がありません。これは、読み取りおよび書き込み可能であり、データ型がDOMString
であることを示しています。 >。name
属性在这里的最后一行,没有readonly
的前缀,说明它是可读可写的,它的数据类型则是DOMString
。DOMString
是指UTF-16的字符串,在JavaScript中它会直接映射到String
DOMString
は UTF-16 文字列を指し、JavaScript のString
に直接マッピングされます。それで私たちが
window.name
赋值的时候,这个值会被强制转换为String
を与えるとき。試してみましょう:
リーリーここに来たらもうおわかりでしょう、
var name = Symbol('test');
的错误,应该是Symbol
变量在做类型转换的时候出了问题。而实际报的错误也证实了我们的猜测:TypeError: Cannot convert a Symbol value to a string
。しかし、それは正しくないようです。
これは決まり文句ですが、JavaScript の暗黙的な型変換と明示的なキャストは、一部の変数では異なります。残念ながら、これがここに当てはまりますSymbol
変数は次のように文字列に変換できます。 リーリー。
Symbol
暗黙的に変換される場合、最初に内部の
変数については、ToPrimitive
インターフェイスを呼び出して元の値を取得し、次にToString
関数を呼び出して文字列に変換します。ここでのToString
関数はその内部抽象メソッドであり、公開されたSymbol.prototype.toString()
と同じものではないことに注意してください。Symbol
被隐式的转换时,它会首先调用其内部的ToPrimitive
接口,拿到其原始值,然后在其中再调用ToString
函数转换为字符串。注意,这里的这个ToString
函数是其内部的抽象方法,和暴露在外的Symbol.prototype.toString()
ToString
を呼び出すときにエラーが報告されます。詳細については説明しません。興味がある場合は、ToString (引数) の仕様を読んでください。コンソールで試してみました。確かに非常に素晴らしいバグですが、あなたもそうするでしょう
リーリーその後、バグが再び消えていることに気づき、驚きました。 。ブラウザが構文を解析する方法に関係があると思いますが、私はこれらのことを理解していません。
name は window の一意の属性です。変数を変更しようとしても、エラーは発生しません。 。 。
name は window の一意の属性です。グローバル環境で name 変数に割り当てられた値は自動的に文字列に変換されますが、Symbol タイプは直接文字列に変換できないため、エラーが報告されます。
できます
リーリーわかるでしょう。