什么是名称冲突,ES6 符号如何避免属性之间的名称冲突?



我试图更好地理解 ES6 中的符号,我已经阅读了这个答案:

https://stackoverflow.com/a/22280202/5591717

它们

现在被称为唯一符号,它们的唯一用途是避免属性之间的名称冲突。

名字冲突是否只意味着一个名字掩盖另一个名字?或者这是否也意味着无法重新声明某些内容的错误?

举个例子:

let color = Symbol('this is a color')
let apple = {
[color]: 'red'
}
console.log(apple[color]) //red
console.log(apple.color) //undefined 
apple[color] = 'black'
console.log(apple[color]) //black
console.log(apple.color) //undefined
apple.color = 'white'
console.log(apple[color]) //black
console.log(apple.color) //white

看起来属性可以被阴影化,即使它们是通过符号访问的。

它们还允许与符号名称同名的点表示法属性与不同的值共存。这就是避免名称冲突的意思吗?

这不是阴影:

在计算机编程中,当在特定范围(决策块、方法或内部类)中声明的变量与在外部作用域中声明的变量具有相同的名称时,就会发生变量阴影。据说这个外部变量是阴影的...

例如

const foo = 'foo';
(() => {
// entirely separate variable which shadows outer variable with same name
const foo = 'foo2';
})();

存储 Symbol 的变量名称对任何内容都没有影响(这很好 - 代码执行不应取决于使用的变量名称)。你可以把它命名为mySymbol而不是color,引擎将具有完全相同的输出:

let mySymbol = Symbol('this is a mySymbol')
let apple = {
[mySymbol]: 'red'
}
console.log(apple[mySymbol]) //red
console.log(apple.color) //undefined 
apple[mySymbol] = 'black'
console.log(apple[mySymbol]) //black
console.log(apple.color) //undefined
apple.color = 'white'
console.log(apple[mySymbol]) //black
console.log(apple.color) //white

当代码的完全独立的部分需要在对象上存储数据时,可以避免名称冲突。代码的不同部分可能彼此不知道,但他们希望确保一个使用的属性与另一个属性不同。这可以通过每个部分使用其自己的符号来实现,这使得两个代码部分不可能意外使用相同的属性名称,从而导致错误。例如:

// module1.js
const module1 = (() => {
const module1Sym = Symbol();
return (obj) => {
// put some data on obj which can be retrieved by this module later
obj[module1Sym] = 'module 1 data';
};
})();
// module2.js
const module2 = (() => {
const module2Sym = Symbol();
return (obj) => {
// put some data on obj which can be retrieved by this module later
obj[module2Sym] = 'module 2 data';
};
})();
const obj = {};
module1(obj);
module2(obj);

如果一个模块改用属性名称module1data,则可能会出现问题 - 如果另一个自称为模块 module1 的模块试图在对象上存储数据怎么办?然后,事情就会崩溃:

// module1Foo.js
const module1Foo = (() => {
return (obj) => {
// put some data on obj which can be retrieved by this module later
obj.module1Data = 'foo data';
};
})();
// module1Bar.js
const module1Bar = (() => {
return (obj) => {
// put some data on obj which can be retrieved by this module later
obj.module1Data = 'bar data';
};
})();
const obj = {};
module1Foo(obj);
module1Bar(obj);
// Uh oh, foo data got overwritten
console.log(obj);

以上是名称冲突的示例。两个模块意外使用了相同的属性名称。

最新更新