>  기사  >  웹 프론트엔드  >  Javascript의 Symbol 유형에 대한 자세한 설명

Javascript의 Symbol 유형에 대한 자세한 설명

黄舟
黄舟원래의
2017-08-08 14:06:002874검색


Javascript의 Symbol 유형에 대한 자세한 설명

사양에 따르면 객체 속성 키는 숫자나 부울이 아닌 문자열 유형 또는 기호 유형만 가능하며 문자열과 기호 두 가지 유형만 있습니다.
우리는 일반적으로 속성 문자열을 비교합니다. 이제 기호 유형이 제공하는 이점을 살펴보겠습니다.

Symbols

"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

如果我们在一个直接量对象中使用symbol,我们需要使用方括号:

let id = Symbol("id");

let user = {
  name: "John",
  [id]: 123 // not just "id: 123"
};

因为我们需要名称为“id”的symbol变量值,不是字符串“id”。

Symbol 被 for…in 忽略

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是不同的,但有时我们想相同名词的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.keyFor

对全局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,名称仅用于调试目的。

系统symbol

在Javascript内部存在很多系统symbol,我们能使用他们调整对象的各个方面。
这里列出一些常用的symbol:

  • Symbol.hasInstance

  • Symbol.isConcatSpreadable

  • Symbol.iterator

  • Symbol.toPrimitive

举例:Symbol.toPrimitive用于对象转基本类型时描述对象,如果你继续深入学习Javascript,其他的你也会逐步熟悉。

总结

  • symbol是基本类型,实现唯一标识

  • 通过调用symbol(name)rrreee

    Symbols는 고유성을 보장하며 동일한 이름을 사용하더라도 다른 값을 생성합니다. 예를 들어, 여기에 같은 이름을 가진 두 개의 기호가 있지만 둘 다 동일하지 않습니다.
  • rrreee
  • Ruby나 다른 언어에 익숙하다면 동일한 유형의 기호도 있으므로 오해하지 마세요. Javascript 기호는 다릅니다.

    Hidden Properties
  • 기호를 사용하면 다른 코드가 때때로 해당 속성에 액세스하거나 덮어쓸 수 없도록 개체의 숨겨진 속성을 생성할 수 있습니다.

    예를 들어 객체 사용자의 "식별자"를 저장하려는 경우 id 기호를 만들 수 있습니다.

    사용자 = { 이름: "John" }; Let id = Symbol("id");
  • rrreee
  • 이제 다른 스크립트가 고유한 목적을 위해 사용자 개체에 고유한 "id" 속성을 추가하려고 한다고 가정해 보겠습니다. 다른 Javascript 라이브러리일 수 있으므로 서로를 전혀 알지 못합니다.

    문제 없습니다. 자신만의 Symbol("id")를 만들 수 있습니다.

  • 코드는 다음과 같습니다:
  • rrreee

    동일한 이름이라도 기호가 항상 다르기 때문에 충돌이 없습니다. 동일한 목적을 달성하기 위해 기호 대신 문자열 "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.hasInstance🎜🎜🎜🎜Symbol.isConcatSpreadable🎜🎜🎜🎜Symbol.iterator🎜🎜🎜🎜Symbol.toPrimitive🎜 🎜 🎜 🎜…🎜🎜
    🎜예: Symbol.toPrimitive는 객체를 기본 유형으로 변환할 때 설명하는 데 사용됩니다. Javascript를 계속 깊이 있게 배우면 점차 다른 객체에도 익숙해질 것입니다. . 🎜🎜Summary🎜
      🎜🎜symbol은 고유 식별을 구현하는 기본 유형입니다.🎜🎜🎜🎜symbol(name)🎜🎜🎜🎜을 호출하여 기호를 생성합니다. us 해당 기호를 아는 사람만 접근할 수 있는 필드를 만듭니다. 🎜🎜🎜🎜기호는 for..in 결과에 나타나지 않습니다. 🎜🎜🎜🎜기호(이름)를 사용하여 만든 기호는 항상 달라요, 이름이 같아도. 동일한 이름을 가진 기호를 동일하게 하려면 전역 등록🎜🎜🎜🎜symbol.for(name)을 사용하여 지정된 이름의 전역 기호를 반환하고 여러 호출을 사용하여 동일한 기호를 반환합니다.🎜🎜🎜🎜Javascript에는 시스템이 있습니다. Symbol.* 을 통해 액세스되는 기호. 이를 사용하여 일부 내장 동작을 수정할 수 있습니다. 🎜

기술적으로 기호는 100% 숨겨지지 않으며 기호를 포함하여 객체의 모든 키를 반환하는 내장 메서드 Object.getOwnPropertySymbols(obj)可以获得所有的symbol。
也有一个方法Reflect.ownKeys(obj)가 있습니다.

그래서 실제로 숨겨진 것은 아닙니다. 그러나 대부분의 라이브러리 내장 메서드와 구문 구성은 숨겨져 있다는 공통 규칙을 따르며, 누군가 위 메서드를 명시적으로 호출하면 자신이 수행하는 작업을 완전히 이해할 수 있습니다.

위 내용은 Javascript의 Symbol 유형에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.