사양에 따르면 객체 속성 키는 숫자나 부울이 아닌 문자열 유형 또는 기호 유형만 가능하며 문자열과 기호 두 가지 유형만 있습니다.
우리는 일반적으로 속성 문자열을 비교합니다. 이제 기호 유형이 제공하는 이점을 살펴보겠습니다.
"Symbol" 값은 주어진 이름을 가진 고유 식별자를 나타냅니다. 이 유형의 값은 다음과 같이 생성할 수 있습니다: Symbol(name)
: Symbol(name)
:
// id is a symbol with the name "id" let id = Symbol("id");
Symbols确保唯一,即使我们使用相同的名称,也会产生不同的值。举例,这里有两个symbol使用相同的名称,两种不相等:
let id1 = Symbol("id"); let id2 = Symbol("id"); alert(id1 == id2); // false
如果你熟悉Ruby或其他语言,也有相同类型的symbol,不要被误导,Javascript的symbol是不同的。
symbol允许创建对象的隐藏属性,这样其他代码不会偶尔访问或覆盖。
举例,如果我们想存储对象user的“identifier”,我们可以创建id的symbol:
let user = { name: “John” };
let id = Symbol(“id”);
user[id] = "ID Value"; alert( user[id] ); // we can access the data using the symbol as the key
现在让我们想像假设另外的脚本想给user对象添加自己的“id”属性,为其自有的目的。可能是另外其他的Javascript库,所以完全相互不清楚彼此。
没有问题,能够创建自己的Symbol("id")
。
代码如下:
// ... let id = Symbol("id"); user[id] = "Their id value";
这是没有冲突的,因为symbol总是不同的,即使有相同的名称。注意如果我们使用字符串“id”代替symbol实现相同目的,那么会有冲突:
let user = { name: "John" }; // our script uses "id" property user.id = "ID Value"; // ...if later another script the uses "id" for its purposes... user.id = "Their id value" // boom! overwritten! it did not mean to harm the colleague, but did it!
如果我们在一个直接量对象中使用symbol,我们需要使用方括号:
let id = Symbol("id"); let user = { name: "John", [id]: 123 // not just "id: 123" };
因为我们需要名称为“id”的symbol变量值,不是字符串“id”。
symbol属性不参与for..in循环,举例:
let id = Symbol("id"); let user = { name: "John", age: 30, [id]: 123 }; for(let key in user) alert(key); // name, age (no symbols) // the direct access by the symbol works alert( "Direct: " + user[id] );
这时一般隐藏概念的一部分,如果其他脚本或库,也不期望访问symbol属性。
相反,Object.assign同时拷贝字符属性和symbol属性。
let id = Symbol("id"); let user = { [id]: 123 }; let clone = Object.assign({}, user); alert( clone[id] ); // 123
这两者没有矛盾,规范就是这么设计的,其思想是当我们克隆对象或合并对象,通常希望symbol属性也被拷贝。
其他类型的属性键被强制转换成字符串:
对象中的键只能使用字符串或symbol,其他类型强制被转成字符串。
let obj = { 0: "test" // same as "0": "test" } // both alerts access the same property (the number 0 is converted to string "0") alert( obj["0"] ); // test alert( obj[0] ); // test (same property)
通常,所有symbol是不同的,但有时我们想相同名词的symbol是相同的。举例,我们应用不同部分想访问名词为”id“的symbol,当然需要是相同的。
可以通过全局symbol注册实现,我们能先创建,然后访问他们,并且保证通过相同名词重复访问获得相同的symbol。
在注册中创建或读取,使用语法为:symbol.for(name)
,举例:
// read from the global registry let name = Symbol.for("name"); // if the symbol did not exist, it is created // read it again let nameAgain = Symbol.for("name"); // the same symbol alert( name === nameAgain ); // true
在注册中symbol称为全局symbol,如果我们有应用范围的symbol,代码都可以访问,可以使用全局symbol。
其他编程语言,想Ruby,每个名词有单个symbol,在javascript中,我们知道,正是全局symbol。
对全局symbol,不仅有Symbol.for(name)
,根据名称返回symbol,也有相反的调用:Symbol.keyFor(name)
,功能相反:根据全局symbol返回名称。
举例:
let sym = Symbol.for("name"); let sym2 = Symbol.for("id"); // get name from symbol alert( Symbol.keyFor(sym) ); // name alert( Symbol.keyFor(sym2) ); // id
Symbol.keyfor内部实现,使用全局symbol注册,根据symbol查找symbol名称。
所以对非全局的symbol不其作用,如果不是全局symbol,则找不到,返回undefined。
举例:
alert( Symbol.keyFor(Symbol.for("name")) ); // name, global symbol alert( Symbol.keyFor(Symbol("name2")) ); // undefined, non-global symbol
非全局symbol,名称仅用于调试目的。
在Javascript内部存在很多系统symbol,我们能使用他们调整对象的各个方面。
这里列出一些常用的symbol:
Symbol.hasInstance
Symbol.isConcatSpreadable
Symbol.iterator
Symbol.toPrimitive
…
举例:Symbol.toPrimitive
用于对象转基本类型时描述对象,如果你继续深入学习Javascript,其他的你也会逐步熟悉。
symbol是基本类型,实现唯一标识
通过调用symbol(name)
rrreee
예를 들어 객체 사용자의 "식별자"를 저장하려는 경우 id 기호를 만들 수 있습니다.
사용자 = { 이름: "John" }; Let id = Symbol("id");문제 없습니다. 자신만의 Symbol("id")
를 만들 수 있습니다.
동일한 이름이라도 기호가 항상 다르기 때문에 충돌이 없습니다. 동일한 목적을 달성하기 위해 기호 대신 문자열 "id"를 사용하면 충돌이 발생합니다.
rrreee리터럴 개체에서 기호를 사용하는 경우 대괄호를 사용해야 합니다.
rrreee🎜 왜냐하면 문자열 "id"가 아닌 "id"라는 기호 변수의 값이 필요하기 때문입니다. 🎜🎜기호는 for...in에 의해 무시됩니다. 🎜🎜symbol 속성은 for..in 루프에 참여하지 않습니다. 예: 🎜rrreee🎜 이때 다른 스크립트나 라이브러리가 그렇지 않으면 일반적으로 개념의 일부가 숨겨집니다. 기호 속성에 액세스할 것으로 예상됩니다. 🎜반대로 Object.asset는 문자 속성과 기호 속성을 모두 복사합니다. 🎜rrreee🎜둘 사이에는 모순이 없습니다. 이것이 사양이 설계된 방식입니다. 객체를 복제하거나 병합할 때 일반적으로 기호 속성도 복사되기를 원한다는 것입니다. 🎜🎜다른 유형의 속성 키는 강제로 문자열로 변환됩니다. 🎜🎜객체의 키는 문자열이나 기호만 사용할 수 있으며 다른 유형은 강제로 문자열로 변환됩니다. 🎜rrreee🎜전역 기호🎜🎜보통 모든 기호는 다르지만 때로는 동일한 명사를 가진 기호가 동일해지기를 원할 때도 있습니다. 예를 들어, 애플리케이션의 다른 부분에서 "id"라는 명사가 있는 기호에 액세스하려면 당연히 동일해야 합니다. 🎜이는 전역 기호 등록을 통해 달성할 수 있으며, 이를 먼저 생성한 후 액세스할 수 있으며 동일한 명사에 대한 반복 액세스를 통해 동일한 기호를 얻을 수 있습니다. 🎜🎜등록에서 생성하거나 읽으면 사용 구문은 다음과 같습니다.symbol.for(name)
, 예: 🎜rrreee🎜등록의 기호는 애플리케이션이 있는 경우 전역 기호라고 합니다. 넓은 기호, 코드에 액세스할 수 있고 전역 기호를 사용할 수 있습니다. 🎜🎜Ruby와 같은 다른 프로그래밍 언어에서는 각 명사가 단일 기호를 갖습니다. JavaScript에서는 이것이 전역 기호라는 것을 알고 있습니다. 🎜🎜Symbol.keyFor🎜🎜전역 기호의 경우 이름에 따라 기호를 반환하는 Symbol.for(name)
뿐만 아니라 반대 호출인 Symbol.keyFor도 있습니다. (name)
, 함수는 반대입니다. 전역 기호에 따라 이름을 반환합니다. 🎜예: 🎜rrreee🎜Symbol.key는 내부 구현용으로 전역 기호 등록을 사용하고 기호를 기반으로 기호 이름을 검색합니다. 🎜따라서 비전역 기호에는 영향을 미치지 않습니다. 전역 기호가 아니면 찾을 수 없으며 정의되지 않은 값이 반환됩니다. 🎜🎜예: 🎜rrreee🎜비 전역 기호, 이름은 디버깅 목적으로만 사용됩니다. 🎜🎜시스템 기호🎜🎜Javascript에는 많은 시스템 기호가 있으며 이를 사용하여 객체의 다양한 측면을 조정할 수 있습니다. 🎜다음은 일반적으로 사용되는 기호입니다. 🎜Symbol.toPrimitive
는 객체를 기본 유형으로 변환할 때 설명하는 데 사용됩니다. Javascript를 계속 깊이 있게 배우면 점차 다른 객체에도 익숙해질 것입니다. . 🎜🎜Summary🎜symbol(name)
🎜🎜🎜🎜을 호출하여 기호를 생성합니다. us 해당 기호를 아는 사람만 접근할 수 있는 필드를 만듭니다. 🎜🎜🎜🎜기호는 for..in 결과에 나타나지 않습니다. 🎜🎜🎜🎜기호(이름)를 사용하여 만든 기호는 항상 달라요, 이름이 같아도. 동일한 이름을 가진 기호를 동일하게 하려면 전역 등록🎜🎜🎜🎜symbol.for(name)을 사용하여 지정된 이름의 전역 기호를 반환하고 여러 호출을 사용하여 동일한 기호를 반환합니다.🎜🎜🎜🎜Javascript에는 시스템이 있습니다. Symbol.* 을 통해 액세스되는 기호. 이를 사용하여 일부 내장 동작을 수정할 수 있습니다. 🎜기술적으로 기호는 100% 숨겨지지 않으며 기호를 포함하여 객체의 모든 키를 반환하는 내장 메서드 Object.getOwnPropertySymbols(obj)
可以获得所有的symbol。
也有一个方法Reflect.ownKeys(obj)
가 있습니다.
그래서 실제로 숨겨진 것은 아닙니다. 그러나 대부분의 라이브러리 내장 메서드와 구문 구성은 숨겨져 있다는 공통 규칙을 따르며, 누군가 위 메서드를 명시적으로 호출하면 자신이 수행하는 작업을 완전히 이해할 수 있습니다.
위 내용은 Javascript의 Symbol 유형에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!