>  기사  >  웹 프론트엔드  >  JavaScript의 기호 유형, 숨겨진 속성 및 전역 레지스트리에 대한 자세한 설명

JavaScript의 기호 유형, 숨겨진 속성 및 전역 레지스트리에 대한 자세한 설명

WBOY
WBOY앞으로
2022-06-02 11:50:342780검색

이 글에서는 javascript에 대한 관련 지식을 제공합니다. 여기서는 기호 유형에 대한 설명을 포함하여 기호 유형, 숨겨진 속성 및 전역 레지스트리와 관련된 문제를 주로 소개하며, 다른 질문이 있는 경우 기호는 암시적으로 문자열로 변환되지 않습니다. , 아래에서 살펴보겠습니다. 모든 사람에게 도움이 되기를 바랍니다.

JavaScript의 기호 유형, 숨겨진 속성 및 전역 레지스트리에 대한 자세한 설명

【관련 권장 사항: javascript 비디오 튜토리얼, web front-end

Symbol 소개

Symbol 유형은 JavaScript의 특수 유형입니다. 유형, 특히 모든 Symbol 유형 값이 서로 다르다는 점에서 그렇습니다. "Symbol"을 사용하여 고유한 값을 나타낼 수 있습니다. 다음은 Symbol 개체를 생성하는 예입니다. Symbol类型是JavaScript中的一种特殊的类型,特殊在所有的Symbol类型值都互不相同。我们可以使用“Symbol”来表示唯一的值,下面是创建Symbol对象的案例:

let id = Symbol();

这样我们就创建了一个Symbol类型的值,并把这个值存储在了变量id中。

Symbol类型的描述

我们在创建一个Symbol类型变量的时候,可以在参数中传入一些秒属性的字符串,用于描述这个变量的用途信息。
例如:

let id1 = Symbol('狂拽酷炫吊炸天的小明的id');
let id2 = Symbol('低调奢华有内涵的婷婷的id');

Symbol类型在任何时候都是不同的,即使他们拥有相同的描述信息,描述只是一个标签,除此之外就没有别的用途了,例如:

let id1 = Symbol('id');
let id2 = Symbol('id');
console.log(id1==id2);//false

这个标签存在的意义,个人认为和Symbol不能直观的看到内部具体值的特性有关,通过添加一个描述信息,让我们对变量的用途有更直观的了解。

Symbol不会隐式转字符串

JavaScript中的大多数类型都可以直接转换成字符串类型输出,所以我们不能直观的看到它的值到底是什么,例如我们可以直接用alert(123)把数字123转换成字符串弹出。
但是Symbol类型比较特殊,它不能直接转换,例如:

let id = Symbol();
alert(id);//报错,不能把Symbol类型转为字符串

JavaScript中的Symbol类型不能转成字符串是由于其内在的防治语言混乱的“语言保护”机制,因为字符串和Symbol在本质上有着区别,不应该将其中一个转换成另一个。

试想一下,如果Symbol可以转为字符串,那么它就变成了一个生成独一无二字符串的函数,就不再具备独立数据类型的必要。

如果我们真的想知道Symbol变量的值,我们可以使用.toString()方法,如下所示:

let id = Symbol('this is identification');
console.log(id.toString());//Symbol(this is identification);

或者使用.description属性,获取描述信息:

let id = Symbol('加油,奥利给');
console.log(id.description);//加油,奥利给”

Symbol类似作为对象的属性键

根据JavaScript的规范,只有两种类型的值可以作为对象的属性键:

  1. 字符串
  2. Symbol

如果使用其他类型,则会隐式的转为字符串类型。对象的键在前面的章节有详细的介绍,这里不再重复。

创建Symbol键

Symbol作为键值有两种方法:
例1:

let id = Symbol('id');
let user = {};
user[id] = 'id value';//添加Symbol键
console.log(user[id]);//id value

例2:

let id = Symbol('id');
let user = {
	[id]:'id value',//注意这里的方括号	
};
console.log(user[id]);

以上两个案例展示了在对象中插入Symbol类型作为键的用法,需要注意的是,在访问属性时需要使用obj[id]而不是obj.id,因为obj.id代表的是obj[‘id’]

如果我们使用Symbol作为对象的键会有什么效果呢?

for…in中被跳过

Symbol非常明显的一个特征是,如果对象中使用Symbol作为键,那么使用for…in语句是访问不到Symbol类型的属性的。

举个例子:

let id = Symbol('id');
let user = {
	name : 'xiaoming',
	[id] : 'id',
};
for (let key in user) console.log(user[key]);

执行以上代码,得到以下结果:

> xiaoming

可以发现,[id]对象的值没有被打印出来,说明在对象属性列表中,使用for … in会自动忽略Symbol类型的键。

同样的,Object.keys(user)也会忽略所有的Symbol类型的键。

这样的特性能带来非常有用的效果,例如我们可以创建只能自己能用的属性。

虽然我们没有办法直接获取到Symbol键,但是Object.assign方法能够复制所有的属性:

let id = Symbol();
let obj = {
    [id] : '123'
}

let obj2 = Object.assign({},obj);
console.log(obj2[id]);

这并不影响Symbol的隐藏属性,因为复制后的对象仍然无法获取Symbol

let tool = {//张三写好了的Tool
    usage : "Can do anything",
}

let name = Symbol("My tool obj");
tool[name] = "This is my tool";
console.log(tool[name]);
이 방법으로 Symbol유형의 값을 생성합니다. > 넣고 이 값은 변수 id에 저장됩니다. 🎜

기호 유형 설명

🎜 Symbol 유형 변수를 생성할 때 매개변수에 초 속성이 포함된 일부 문자열을 전달할 수 있습니다. 이 변수의 목적을 설명하십시오.
예: 🎜
let tool = {//张三写好了的Tool
    usage : "Can do anything",
}

tool.usage = "Boom Boom";
console.log(tool.usage);
🎜Symbol 유형은 언제든지 다릅니다. 동일한 설명 정보가 있어도 설명은 레이블일 뿐이며 다른 목적은 없습니다. 예: 🎜
let id1 = Symbol.for('id');//注册表内没有名为id的Symbol,创建并返回
let id2 = Symbol.for('id');//注册表内已有名为id的Symbol,直接返回
console.log(id1===id2);//true
🎜이 태그의 의미는 Symbol이 내부 특정 값을 직관적으로 볼 수 없다는 점과 관련이 있습니다. 설명 정보를 추가하면 변수 학습을 보다 직관적으로 이해할 수 있습니다. . 🎜

기호는 암시적으로 문자열로 변환되지 않습니다.

🎜 JavaScript의 대부분의 유형은 문자열 유형 출력으로 직접 변환될 수 있으므로 직관적으로 할 수 없습니다 예를 들어 alert(123)를 직접 사용하여 숫자 123을 문자열로 변환하고 팝업으로 표시할 수 있습니다.
그러나 Symbol 유형은 특별하며 직접 변환할 수 없습니다. 예: 🎜
let id = Symbol.for('id');//注册表内没有名为id的Symbol,创建并返回
let name = Symbol.keyFor(id);
console.log(name);//id
🎜 JavaScriptSymbol 유형은 변환할 수 없습니다. 문자열은 언어 혼동을 방지하기 위한 고유한 "언어 보호" 메커니즘으로 인해 발생합니다. 문자열과 Symbol은 본질적으로 다르기 때문에 서로 변환하면 안 됩니다. 🎜🎜Symbol을 문자열로 변환할 수 있다면 고유한 문자열을 생성하는 함수가 되며 독립적인 데이터 유형이 필요하지 않다고 상상해 보세요. 🎜🎜Symbol 변수의 값을 정말로 알고 싶다면 다음과 같이 .toString() 메서드를 사용할 수 있습니다: 🎜
let id = Symbol('id');//局部Symbol
let name = Symbol.keyFor(id);
console.log(name);//undefined
🎜또는 를 사용하세요. 설명 속성, 설명 정보 가져오기: 🎜rrreee🎜Symbol은 객체의 속성 키와 유사합니다🎜🎜 JavaScript의 사양에 따르면 두 가지 유형의 값만 사용할 수 있습니다. 객체의 속성 키로 사용됩니다: 🎜
  1. String
  2. Symbol
🎜다른 유형이 사용되면 암시적으로 문자열 유형으로 변환됩니다. 객체 키는 이전 장에서 자세히 소개되었으며 여기서는 반복하지 않습니다. 🎜

기호 키 만들기

🎜 Symbol을 키 값으로 사용하는 방법에는 두 가지가 있습니다.
예 1:🎜rrreee🎜예 2 :🎜 rrreee🎜위의 두 사례는 Symbol 유형을 객체에 키로 삽입하는 방법을 보여줍니다. 속성에 액세스할 때 obj[id]를 사용해야 한다는 점에 유의하세요. <code>obj.idobj['id']를 나타내기 때문에 obj.id 대신 입니다. 🎜🎜Symbol을 객체의 키로 사용하면 어떤 효과가 있을까요? 🎜

for...in을 건너뜁니다

🎜Symbol아주 분명한 특징은 Symbol이 개체 As에서 사용되는 경우입니다. 키인 경우 for...in 문을 사용하여 Symbol 유형의 속성에 액세스할 수 없습니다. 🎜🎜예: 🎜rrreee🎜위 코드를 실행하면 다음과 같은 결과가 나타납니다.🎜rrreee🎜[id] 개체의 값이 인쇄되지 않는 것을 확인할 수 있습니다. 객체 속성 목록에서 for … in을 사용하면 Symbol 유형의 키가 자동으로 무시됩니다. 🎜🎜마찬가지로 Object.keys(user)Symbol 유형의 모든 키를 무시합니다. 🎜🎜이러한 기능은 매우 유용한 효과를 가져올 수 있습니다. 예를 들어 우리 자신만 사용할 수 있는 속성을 만들 수 있습니다. 🎜🎜Symbol 키를 직접 얻을 수 있는 방법은 없지만 Object.sign 메서드는 모든 속성을 복사할 수 있습니다. 🎜rrreee🎜이는 Symbol code>의 숨겨진 속성은 복사된 개체가 여전히 <code>Symbol 키를 얻을 수 없기 때문입니다. 🎜

隐藏自定义属性

由于Symbol既不能直接转为字符串,我们没有办法直观的获得它的值,又不能通过for … in获得对象的Symbol属性,也就是说,如果没有Symbol变量本身,我们就没有办法获得对象内部的对应属性。

因此,通过Symbol类型的键值,我们可以隐藏属性,这些属性只能我们自己访问,其他人都看不到我们的属性。

举个例子:

我们在开发的过程中,需要和同事“张三”合作,而这个张三创建了一个非常好用的工具ToolTool是一个对象类型,我们想白嫖张三的Tool,并在此基础上添加一些自己的属性。

我们就可以通过添加Symbol类型的键:

let tool = {//张三写好了的Tool
    usage : "Can do anything",
}

let name = Symbol("My tool obj");
tool[name] = "This is my tool";
console.log(tool[name]);

以上示例展示了如何在别人写好的对象上添加自己的属性,那么为什么要使用Symbol类型而不是常规的字符串呢?

原因如下:

  1. 对象tool是别人写好的代码,原则上我们不应该去修改别人的代码,这样会造成风险;
  2. 避免命名冲突,我们直接使用字符串很有可能会和别人原有的属性键冲突,造成严重的后果;
  3. 使用Symbol永远不会发生命名冲突,因为Symbol都是不同的;
  4. 别人无法访问Symbol类型的键,相当于不会和别人的代码冲突;

错误示范:
如果我们不使用Symbol类型,很可能出现以下情况:

let tool = {//张三写好了的Tool
    usage : "Can do anything",
}

tool.usage = "Boom Boom";
console.log(tool.usage);

以上代码由于重复使用”usage”,从而重写了原属性,会造成对象原功能异常。

Symbol全局注册表

所有的Symbol变量都是不同的,即使他们有用相同的标签(描述)。
有些时候,我们希望通过一个字符串名称(标签),访问同一个Symbol对象,例如我们在代码的不同地方访问相同的Symbol

JavaScript会维护一个全局的Symbol注册表,我们可以通过向注册表中插入Symbol对象,并为对象起一个字符串名称访问该对象。

向注册表插入或者读取Symbol对象需要使用Symbol.for(key)方法,如果注册表中有名为key的对象,就返回该对象,否则就插入新对象再返回。

举个例子:

let id1 = Symbol.for('id');//注册表内没有名为id的Symbol,创建并返回
let id2 = Symbol.for('id');//注册表内已有名为id的Symbol,直接返回
console.log(id1===id2);//true

我们通过Symbol.for(key)就能以全局变量的方式使用Symbol对象,并使用一个字符串标记对象的名字。

相反的,我们还可以使用Symbol.keyFor(Symbol)反向的从对象获取名称。

举个例子:

let id = Symbol.for('id');//注册表内没有名为id的Symbol,创建并返回
let name = Symbol.keyFor(id);
console.log(name);//id

Symbol.keyFor()函数只能用在全局Symbol对象上(使用Symbol.for插入的对象),如果用在非全局对象上,就会返回undefined

举个例子:

let id = Symbol('id');//局部Symbol
let name = Symbol.keyFor(id);
console.log(name);//undefined

系统Symbol

JavaScript有许多系统Symbol,例如:

  • Symbol.hasInstance
  • Symbol.iterator
  • Symbol.toPrimitive

它们各有用途,我们在后面的会逐步介绍道这些独特的变量。

总结

  1. Symbol对象的值是唯一的;
  2. Symbol可以添加一个标签,并通过标签在全局注册表中查询对象的实体;
  3. Symbol作为对象的键无法被for … in探测到;
  4. 我们可以通过Symbol到全局注册表访问全局的Symbol对象;

但是,Symbol并不是完全隐藏的,我们可以通过Object.getOwnPropertySymbols(obj)获取对象所有的Symbol,或者通过Reflect.ownKeys(obj)获取对象所有的键。

【相关推荐:javascript视频教程web前端

위 내용은 JavaScript의 기호 유형, 숨겨진 속성 및 전역 레지스트리에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 csdn.net에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제