React Arrow Конвенция Плохая практика [дубликат]

Когда ES6 теперь широко поддерживается, лучший ответ на этот вопрос изменился. ES6 предоставляет ключевые слова let и const для этого точного обстоятельства. Вместо того, чтобы возиться с закрытием, мы можем просто использовать let для установки переменной области цикла таким образом:

var funcs = [];
for (let i = 0; i < 3; i++) {          
    funcs[i] = function() {            
      console.log("My value: " + i); 
    };
}

val затем укажет на объект, специфичный для этого конкретного поворота цикл, и вернет правильное значение без дополнительной записи закрытия. Это явно значительно упрощает эту проблему.

const аналогично let с дополнительным ограничением на то, что имя переменной не может отскочить к новой ссылке после первоначального присваивания.

Поддержка браузера теперь предназначена для тех, кто ориентирован на последние версии браузеров. const / let в настоящее время поддерживается в последних версиях Firefox, Safari, Edge и Chrome. Он также поддерживается в узле, и вы можете использовать его в любом месте, используя инструменты построения, такие как Babel. Вы можете увидеть рабочий пример здесь: http://jsfiddle.net/ben336/rbU4t/2/

Документы здесь:

Остерегайтесь, однако, что поддержка IE9-IE11 и Edge до Edge 14 let, но получим неверное (они не создают новый i каждый раз, поэтому все вышеперечисленные функции будут записывать 3, как если бы мы использовали var). Edge 14, наконец, получает это право.

35
задан JordanHendrix 18 May 2016 в 02:19
поделиться

3 ответа

Я думаю, что это также может иметь какое-то отношение к неожиданному поведению, которое может возникнуть из-за неявного предоставления лексического имени тому, что вы можете ожидать анонимной функцией.

Скажем, например, кто-то понял функцию стрелки:

(x) => x+2;

Чтобы иметь регулярную функцию, эквивалентную:

function(x) {
  return x+2;
}

Было бы довольно легко ожидать этот код:

let foo = (x) => x+2;

Чтобы быть эквивалентом:

let foo = function(x) {
  return x+2;
}

Если функция остается анонимной и неспособна ссылаться на себя, чтобы делать такие вещи, как рекурсия.

Итак, если тогда, в нашем блаженном невежестве, у нас было что-то вроде этого:

let foo = (x) => (x<2) ? foo(2) : "foo(1)? I should be a reference error";
console.log(foo(1));

Он успешно выполнялся, потому что эта функция явно не была анонимной:

let foo = function foo(x) {
  return (x<2) ? foo(2) : "foo(1)? I should be a reference error";
}  

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

Например:

let foo = {
  bar: function() {}
} 

// Will surprisingly transpile to..

var foo = {
  bar: function bar() {}
}; 


// But doing something like:

var foo = {
  bar: function(x) {
    return (x<2) ? bar(2) : 'Whats happening!?';
  }
}

console.log(foo.bar(1));

// Will correctly cause a ReferenceError: bar is not defined

Вы можете проверить «скомпилированный просмотр» на этом быстром DEMO , чтобы увидеть, как Babel фактически транслирует, чтобы поддерживать поведение анонимной функции.


Короче говоря, быть явным с тем, что вы делаете, - это, как правило, хорошая идея, потому что вы точно знаете, чего ожидать от вашего кода. Отказ от использования неявных имен функций, скорее всего, является стилистическим выбором в поддержку этого, а также остается кратким и простым.

И, вероятно, подъем. Но эй, веселая прогулка.

21
ответ дан Brad Colthurst 23 August 2018 в 21:23
поделиться

РЕДАКТИРОВАТЬ # 2: найти причину AirBnbs в их Руководстве по стилю Javascript

Не забудьте назвать выражение - анонимные функции могут затруднить поиск проблема в стеке вызовов ошибки ( Обсуждение )

Исходный ответ ниже

MDN имеет хорошее отклонение от того, как function name inference работает, включая два предупреждения:

Замечания

Существует нестандартное поведение вывода <function>.name в следующих двух сценариях:

  1. при использовании интерпретаторов сценариев

Интерпретатор сценария установит свойство имени функции только в том случае, если функция не имеет собственного свойства с именем name. ..

  1. при использовании js tooling

Будьте осторожны при использовании преобразований Function.name и исходного кода, таких как выполняемые с помощью компрессоров (minifiers) JavaScript или обфускаторов

....

В несжатом версия запускается в правдивую ветвь, а logs «foo» - это экземпляр «Foo», тогда как в сжатой версии он ведет себя по-разному и переходит в else-ветку. Поэтому, если вы полагаетесь на Function.name, как в приведенном выше примере, убедитесь, что ваш конвейер сборки не меняет имена функций или не предполагает, что функция имеет определенное имя.

Что такое выражение имени функции?

Свойство name возвращает имя функции или (до реализации ES6) пустую строку для анонимных функций

function doSomething() {}

console.log(doSomething.name); // logs "doSomething"

Функции, созданные с помощью синтаксиса new Function (...) или просто Function (...), имеют свойство name для пустой строки. В следующих примерах создаются анонимные функции, поэтому имя возвращает пустую строку

var f = function() {};
var object = {
  someMethod: function() {}
};

console.log(f.name == ''); // true
console.log(object.someMethod.name == ''); // also true

Браузеры, которые реализуют функции ES6, могут вывести имя анонимной функции из ее синтаксической позиции . Например:

var f = function() {};
console.log(f.name); // "f"

Мнение

Лично я предпочитаю (стрелка) функции, назначенные переменной по трем основным причинам:

Во-первых, я не ever используют function.name

Во-вторых, смешение лексической области именных функций с назначением немного ослабляет:

// This...
function Blah() {
   //...
}
Blah.propTypes = {
 thing: PropTypes.string
}
// ...is the same as...
Blah.propTypes = {
 thing: PropTypes.string
}
function Blah() {
   //...
}

// ALTERNATIVELY, here lexical-order is enforced
const Blah = () => {
   //...
}
Blah.propTypes = {
    thing: PropTypes.string
}

И, в-третьих, все вещи, Я предпочитаю функции стрелок:

  • сообщают читателю, что нет this, no arguments и т. д.
  • выглядит лучше (imho)
  • (в прошлый раз я смотрел, функции стрелок были немного быстрее)

EDIT: моментальные снимки памяти

Я слушал Podcast и гость рассказал о ситуации, когда ему приходилось иметь дело с ограничениями использования функций стрелок с профилированием памяти, я раньше был в в той же самой ситуации.

В настоящее время снимки памяти не будет включать имя переменной - так что вы можете найти преобразование функций стрелок в именованные функции только для подключения профилировщика памяти , Мой опыт был довольно прост, и я до сих пор доволен функциями стрелок.

Плюс я использовал только снимки памяти один раз, поэтому я чувствую себя комфортно, когда по-умолчанию чувствую «инструмент» для (субъективной) ясности.

16
ответ дан Ashley Coolman 23 August 2018 в 21:23
поделиться

Это связано с тем, что:

const Listing = ({ hello }) => (
  <div>{hello}</div>
);

имеет выведенное имя листинга, хотя похоже, что вы его именовали, вы на самом деле не:

Пример

// we know the first three ways already...

let func1 = function () {};
console.log(func1.name); // func1

const func2 = function () {};
console.log(func2.name); // func2

var func3 = function () {};
console.log(func3.name); // func3

что об этом?

const bar = function baz() {
    console.log(bar.name); // baz
    console.log(baz.name); // baz
};

function qux() {
  console.log(qux.name); // qux
}
5
ответ дан JordanHendrix 23 August 2018 в 21:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: