Что такое конфликты имен и как символы ES6 предотвращают конфликты имен между свойствами? - PullRequest
1 голос
/ 19 июня 2019

Я пытаюсь лучше понять символы в 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

Похоже, что свойства могут быть скрыты, даже если они доступны через символы.

И они также позволяют свойствам точечной нотации с тем же именем, что и имя символа, сосуществовать с другим значением.Это то, что подразумевается под избеганием столкновений имен?

1 Ответ

4 голосов
/ 19 июня 2019

Это не теневое копирование:

В компьютерном программировании теневое копирование происходит, когда переменная, объявленная в определенной области (блок принятия решений, метод или внутренний класс), имеет то же имя, что и объявленная переменнаяво внешнем объеме.Эта внешняя переменная называется затененной ...

например,

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

Имя переменной, в которой хранится символ, ни на что не влияет (что хорошо - код выполнение не должно зависеть от того, какие имена переменныхиспользуемый).Вы могли бы назвать его 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);

Выше приведен пример столкновения имен.Два модуля случайно использовали одно и то же имя свойства.

...