이것은 추출된 두 줄의 코드입니다 var name = Symbol('test')
一直提示 无法转换,是关键字保留?还是其他原因?
为什么换一个var name1 = Symbol('test')
却可以通过编译?
其他普通的var s1 s2
컴파일도 가능합니다.
三叔2017-06-26 10:57:19
이 질문은 꽤 흥미롭습니다. 한번도 눈치 채지 못했습니다. 정보를 살펴 보니 우연히 많은 것들이 합쳐졌는데이 문제가 나타났습니다. 정확히 말하면 浏览器的默认行为
和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
은 JavaScript의 String
에 직접 매핑되는 UTF-16 문자열을 나타냅니다.
그래서 우리가 줄 때 window.name
赋值的时候,这个值会被强制转换为String
.
한번 시도해 볼 수 있습니다:
으아악여기에 오시면 아마 짐작하실 수 있을 거예요, var name = Symbol('test');
的错误,应该是Symbol
变量在做类型转换的时候出了问题。而实际报的错误也证实了我们的猜测:TypeError: Cannot convert a Symbol value to a string
.
그러나 이는 잘못된 것 같습니다. Symbol
변수는 문자열로 변환될 수 있습니다. 예:
글쎄, 이것은 진부한 표현입니다. JavaScript의 암시적 유형 변환과 명시적 캐스트는 일부 변수에 따라 다릅니다. 불행하게도 여기서는 Symbol
.
Symbol
被隐式的转换时,它会首先调用其内部的ToPrimitive
接口,拿到其原始值,然后在其中再调用ToString
函数转换为字符串。注意,这里的这个ToString
函数是其内部的抽象方法,和暴露在外的Symbol.prototype.toString()
암시적으로 변환되면 먼저 내부 ToPrimitive
인터페이스를 호출하여 원래 값을 가져온 다음 ToString
함수를 호출하여 문자열로 변환합니다. 여기서 ToString
함수는 내부 추상 메서드이며 노출된 Symbol.prototype.toString()
과 동일하지 않습니다.
Symbol
变量而言,当其调用ToString
변수의 경우 ToString
을 호출하면 오류가 보고됩니다. 자세한 내용은 다루지 않겠습니다. 관심이 있는 경우 ToString(인수) 사양을 직접 읽어보세요.
仅有的幸福2017-06-26 10:57:19
방금 콘솔에서 사용해 보았는데 정말 놀라운 버그입니다. 하지만 여러분은 그렇게 될 것입니다
으아악그러다가 BUG가 또 없어진 걸 보고 깜짝 놀랐습니다. . 브라우저가 구문을 구문 분석하는 방법과 관련이 있는 것 같지만 이러한 사항을 이해하지 못합니다.
欧阳克2017-06-26 10:57:19
name은 window의 고유 속성입니다. 전역 환경에서 name 변수에 할당된 모든 값은 자동으로 문자열로 변환됩니다. 그러나 Symbol 유형은 직접 문자열로 변환할 수 없으므로 오류가 보고됩니다.
할 수 있어요
으아악알겠습니다.