оригинал:Рисовое путешествие avlutin.com/7-tips-to-also…
Переводчик: Front-end Xiaozhi
Ставь лайк и смотри, поиск в WeChat【Переезд в мир】Обратите внимание на этого человека, который не имеет большого фабричного прошлого, но имеет восходящий и позитивный настрой. эта статья
GitHub
GitHub.com/QQ449245884…Он был включен, статьи были классифицированы, и многие мои документы и учебные материалы были систематизированы.
Все говорили, что нет проекта для написания резюме, поэтому я помог вам найти проект, и это было с бонусом.【Учебник по строительству】.
Около 8 лет назад, когда оригинальный автор начал изучать JS, он столкнулся со странной ситуацией, когда обаundefined
значение, есть также нулевое значениеnull
. Какая очевидная разница между ними?Они оба вроде бы определяют null и, более того, сравниваютnull == undefined
Результат расчетаtrue
.
Большинство современных языков, таких как Ruby, Python или Java, имеют значение null (nil
илиnull
), что кажется разумным способом.
Для JavaScript интерпретатор возвращает значение при доступе к переменной или свойству объекта, которые не были инициализированы.undefined
. Например:
let company;
company; // => undefined
let person = { name: 'John Smith' };
person.age; // => undefined
с другой стороны,null
Указывает на отсутствующую ссылку на объект, сам JS не устанавливает для переменной или свойства объекта значениеnull
.
Некоторые собственные методы, такие какString.prototype.match()
, может вернутьсяnull
изображать недостающие предметы. Взгляните на пример ниже:
let array = null;
array; // => null
let movie = { name: 'Starship Troopers', musicBy: null };
movie.musicBy; // => null
'abc'.match(/[0-9]/); // => null
Из-за разрешающей природы JS разработчикам легко получить доступ к неинициализированным значениям, и я тоже допустил эту ошибку.
Часто эта опасная операция порождаетundefined
связанные ошибки, чтобы быстро завершить сценарий. Связанные распространенные сообщения об ошибках:
TypeError: 'undefined' is not a function
TypeError: Cannot read property '<prop-name>' of undefined
type errors
Разработчики JS могут понять иронию этой шутки:
function undefined() {
// problem solved
}
Чтобы снизить риск таких ошибок, необходимо понимать генерациюundefined
Случай. Что более важно, так это подавить его появление и предотвратить его распространение в приложении, тем самым повышая устойчивость кода.
Давайте подробно обсудимundefined
и его влияние на безопасность кода.
какого черта не определено
JS имеет 6 основных типов
- Boolean:
true
илиfalse
- Number:
1, 6.7, 0xFF
- String:
"Gorilla and banana"
- Symbol:
Symbol("name")
(starting ES2015) - Null:
null
- Undefined:
undefined
.
И отдельныйObject
Типы:{name: "Dmitri"}, ["apple", "orange"]
.
согласно сСпецификация ECMAScript, из 6 примитивных типов,undefined
это особая ценность, которая имеет своюUndefined
Типы.
Значение по умолчанию, когда переменная не назначается значение,
undefined
.
Стандарт четко определяет, что при доступе к неинициализированным переменным, несуществующим свойствам объекта, несуществующим элементам массива и т. д. вы получитеundefined
ценность . Например
let number;
number; // => undefined
let movie = { name: 'Interstellar' };
movie.year; // => undefined
let movies = ['Interstellar', 'Alexander'];
movies[3]; // => undefined
Общий поток приведенного выше кода:
- неинициализированная переменная
number
- несуществующее свойство объекта
movie.year
- или не существует фильмов элементов массива3
будет определяться какundefined
.
Спецификация ECMAScript определяетundefined
тип значения
Undefined typeявляется его уникальной ценностью
undefined
Тип значения.
в этом смысле,typeof undefined
Возвращает «неопределенную» строку
typeof undefined === 'undefined'; // => true
Конечноtypeof
Хороший способ проверить, что переменная содержитundefined
значение
let nothing;
typeof nothing === 'undefined'; // => true
2. Создайте неопределенные общие сценарии
2.1 Неинициализированные переменные
Объявленная переменная, которой не было присвоено значение (неинициализированная), по умолчанию имеет значениеundefined
.
let myVariable;
myVariable; // => undefined
myVariable
Объявлено, но еще не назначено, значение по умолчанию равноundefined
.
Эффективный способ решить проблему неинициализированных переменных — присвоить начальные значения везде, где это возможно. Чем меньше переменных находится в неинициализированном состоянии, тем лучше. В идеале можно объявитьconst myVariable ='Initial value'
Указание значения сразу после этого не всегда возможно.
Совет 1: Используйте const вместо var и пусть
На мой взгляд, одна из лучших функций ES6 — это использованиеconst
а такжеlet
Новый способ объявления переменных.const
а такжеlet
Имеет блочную область (в отличие от старой области действия функции)var
вместо этого) присутствуют перед строкой объявленияВременная мертвая зона.
Когда переменная получает значение один раз и навсегда, рекомендуется использоватьconst
объявление, которое создает неизменяемую привязку.
const
Приятной особенностью является то, что это должна быть переменнаяconst myVariable ='initial'
Задайте начальное значение. Переменная не подвергается воздействию неинициализированного состояния, и доступundefined
это невозможно.
В следующем примере проверяется функция, которая проверяет, является ли слово палиндромом:
function isPalindrome(word) {
const length = word.length;
const half = Math.floor(length / 2);
for (let index = 0; index < half; index++) {
if (word[index] !== word[length - index - 1]) {
return false;
}
}
return true;
}
isPalindrome('madam'); // => true
isPalindrome('hello'); // => false
length
а такжеhalf
Переменной присваивается значение один раз. объявить их какconst
Кажется разумным, поскольку эти переменные не меняются.
Если вам нужно повторно связать переменную (т.е. несколько назначений), применитеlet
утверждение. По возможности сразу присваивайте ему начальное значение, например,let index = 0
.
затем используйтеvar
Декларация, относительно ES6, рекомендуется полностью отказаться от ее использования.
var
Объявленные упоминания переменных поднимаются вверх всей области действия функции. Может быть объявлен где-то в конце области видимости функции.var
переменная, но доступ к ней возможен до объявления: значение соответствующей переменной равноundefined
.
Вместо этого используйтеlet
илиconst
Доступ к переменной невозможен до объявленной переменной. Это происходит потому, что переменная находится вВременная мертвая зона. Это хорошо, потому что тогда меньше возможностей получить доступundefined
стоимость.
использоватьlet
(вместо var) обновленный пример выше выдаетReferenceError
Ошибка, потому что переменная во временной мертвой зоне недоступна.
function bigFunction() {
// code...
myVariable; // => Throws 'ReferenceError: myVariable is not defined'
// code...
let myVariable = 'Initial value';
// code...
myVariable; // => 'Initial value'
}
bigFunction();
Совет 2: повышайте сплоченность
Связность описывает степень, в которой элементы модуля (пространства имен, классы, методы, блоки кода) связаны. Меру сплоченности часто называют высокой сплоченностью или низкой сплоченностью.
Предпочтение отдается высокой связности, поскольку она предполагает разработку элементов модуля таким образом, чтобы они фокусировались только на одной задаче, составляющей модуль.
-
Сосредоточенно и понятно: легче понять функцию модуля
-
Поддерживается и упрощается рефакторинг: изменения в модуле влияют на меньшее количество модулей.
-
Возможность повторного использования: сосредоточьтесь на одной задаче, что упрощает повторное использование модулей.
-
Тестируемость: модули, ориентированные на одну задачу, легче тестировать.
Высокая сплоченность и низкая связанность - это хорошо продуманные системные функции.
Сам код кода может рассматриваться как небольшой модуль, максимально возможен для достижения высокой сплоченности, необходимо использовать их как можно ближе к переменной положении блока кода.
Например, если переменная существует только для формирования области блока, не выставляйте эту переменную во внешнюю область блока, так как внешний блок не должен заботиться об этой переменной.
Классический пример ненужного увеличения времени жизни переменной — функцияfor
Использование петель:
function someFunc(array) {
var index, item, length = array.length;
// some code...
// some code...
for (index = 0; index < length; index++) {
item = array[index];
// some code...
}
return 'some result';
}
index
,item
а такжеlength
Переменные объявляются в начале тела функции, однако используются они только в конце, так что же в этом плохого?
Декларация сверхуfor
Переменные index и item в операторе не инициализированы, а значение равноundefined
. Они имеют неоправданно большое время жизни во всем диапазоне функций.
Лучшим подходом является максимальное перемещение этих переменных туда, где они используются:
function someFunc(array) {
// some code...
// some code...
const length = array.length;
for (let index = 0; index < length; index++) {
const item = array[index];
// some
}
return 'some result';
}
index
а такжеitem
переменные существуют только вfor
в рамках заявления,for
Снаружи это не имеет никакого смысла.length
Переменная также объявляется рядом с тем местом, где она используется.
Почему модифицированная версия лучше оригинальной? Есть несколько основных моментов:
-
переменная не раскрыта
undefined
состояние, поэтому нет доступаundefined
риски -
Перемещение переменных как можно ближе к тому месту, где они используются, повышает читабельность кода.
-
Высокосвязный реконструированный кодовый блок легче отделить и извлечь функцию, где это необходимо
2.2 Доступ к несуществующим свойствам
При доступе к несуществующему свойству объекта JS возвращает
undefined
.
Проиллюстрируем это на примере:
let favoriteMovie = {
title: 'Blade Runner'
};
favoriteMovie.actors; // => undefined
favoriteMovie
это один атрибутtitle
Объект. Использование средств доступа к свойствамfavoriteMovie.actors
получить доступ к несуществующему свойствуactors
будет рассчитываться какundefined
.
Доступ к несуществующему свойству сам по себе не приводит к ошибке, но возникают проблемы при попытке получить данные из значения несуществующего свойства. Распространенные ошибкиTypeError: Cannot read property <prop> of undefined
.
Слегка измените предыдущий фрагмент кода, чтобы проиллюстрироватьTypeError throw
:
let favoriteMovie = {
title: 'Blade Runner'
};
favoriteMovie.actors[0];
// TypeError: Cannot read property '0' of undefined
favoriteMovie
нет атрибутаactors
,такfavoriteMovie.actors
значениеundefined
. Поэтому, используя выражениеfavoriteMovie.actors[0]
доступundefined
Первый элемент значения выбрасываетTypeError
.
JS разрешает доступ к несуществующим свойствам, и эта функция разрешения доступа может сбивать с толку: свойства могут быть установлены или не установлены, и идеальный способ обойти это — ограничить объект, чтобы он всегда определял свойства, которые он содержит.
К сожалению, мы часто не можем контролировать объекты. Эти объекты могут иметь разные наборы свойств в разных сценариях, поэтому все эти сценарии необходимо обрабатывать вручную:
Затем реализуем функциюappend(array, toAppend)
, его основная функция добавляет новые элементы в начало и/или конец массива.toAppend
Параметр принимает объект со свойствами:
-
first: элемент вставляется в начало массива
-
last: элемент вставляется в конец массива.
Функция возвращает новый экземпляр массива без изменения исходного массива (т. е. это чистая функция).
append()
Первая версия, которая выглядит проще, выглядит так:
function append(array, toAppend) {
const arrayCopy = array.slice();
if (toAppend.first) {
arrayCopy.unshift(toAppend.first);
}
if (toAppend.last) {
arrayCopy.push(toAppend.last);
}
return arrayCopy;
}
append([2, 3, 4], { first: 1, last: 5 }); // => [1, 2, 3, 4, 5]
append(['Hello'], { last: 'World' }); // => ['Hello', 'World']
append([8, 16], { first: 4 }); // => [4, 8, 16]
из-заtoAppend
объект может быть опущенfirst
илиlast
свойство, поэтому оно должно быть провереноtoAppend
существуют ли эти свойства в . Если свойство не существует, значением метода доступа к свойству являетсяundefined
.
экзаменfirst
илиlast
Является собственностьюundefined
, при условииif(toappendix .first){}
и яf(toappendix .last){}
Подтвердить в:
Этот метод имеет недостаток,undefined
,false
,null
,0
,NaN
а также''
является ложным значением.
существуетappend()
В текущей реализации функции не разрешено вставлять элемент виртуального значения:
append([10], { first: 0, last: false }); // => [10]
0
а такжеfalse
является фиктивным. потому чтоif(toAppend.first){}
а такжеif(toAppend.last){}
на самом деле сfalsy
для сравнения, чтобы элементы не вставлялись в массив, функция возвращает исходный массив[10]
без какой-либо модификации.
Следующие советы объясняют, как правильно проверить наличие свойства.
Совет 3. Проверьте, существует ли свойство
JS предоставляет множество способов определить, имеет ли объект определенное свойство:
-
obj.prop!== undefined
: непосредственно сundefined
Сравнивать -
typeof obj.prop!=='undefined'
: Проверить тип значения свойства -
obj.hasOwnProperty('prop')
: Убедитесь, что объект имеет свои собственные свойства -
'prop' in obj
: Убедитесь, что объект имеет свои собственные свойства или унаследованные свойства.
Мое предложение состоит в том, чтобы использоватьin
оператора, его синтаксис короткий и лаконичный.in
Наличие оператора указывает на явное намерение проверить, имеет ли объект определенное свойство, не обращаясь к фактическому значению свойства.
obj.hasOwnProperty('prop')
также хорошее решение, оно лучше, чемin
Оператор немного длиннее и проверяется только в собственных свойствах объекта.
с участием иundefined
Сравнение оставшихся двух способов может сработать, но, на мой взгляд,obj.prop!== undefined
а такжеtypeof obj.prop!=='undefined'
выглядит многословным и странным и подвергает непосредственному обращениюundefined
подозрительный путь. .
давайте использоватьin
улучшения оператораappend(array, toAppend)
функция:
function append(array, toAppend) {
const arrayCopy = array.slice();
if ('first' in toAppend) {
arrayCopy.unshift(toAppend.first);
}
if ('last' in toAppend) {
arrayCopy.push(toAppend.last);
}
return arrayCopy;
}
append([2, 3, 4], { first: 1, last: 5 }); // => [1, 2, 3, 4, 5]
append([10], { first: 0, last: false }); // => [0, 10, false]
'first' in toAppend
(а также'last' in toAppend
) когда соответствующий атрибут существуетtrue
, иначеfalse
.in
Использование оператора решает вставку фиктивных элементов0
а такжеfalse
Эта проблема. сейчас на[10]
Добавление этих элементов в начало и конец[0,10,false]
.
Совет 4: деструктуризация доступа к свойствам объекта
При доступе к свойствам объекта иногда необходимо указать значение по умолчанию, если свойство не существует. можно использоватьin
и тернарный оператор для достижения этого.
const object = { };
const prop = 'prop' in object ? object.prop : 'default';
prop; // => 'default'
Использование синтаксиса тернарного оператора становится пугающим, когда количество проверяемых свойств увеличивается. Для каждого свойства приходилось создавать новую строку кода для обработки значения по умолчанию, что добавляло уродливую стену, полную похожих тернарных операторов.
Для более элегантного подхода можно использовать деструктурирование объектов ES6.
Деструктуризация объекта позволяет извлекать значения свойств объекта непосредственно в переменные и устанавливать значения по умолчанию, когда свойство не существует, избегая прямой обработкиundefined
Удобная грамматика.
На самом деле извлечение атрибутов теперь выглядит коротким и осмысленным:
const object = { };
const { prop = 'default' } = object;
prop; // => 'default'
Чтобы увидеть это в действии, давайте определим полезную функцию, заключающую строку в кавычки.quote(subject, config)
Принимает первый аргумент в виде строки для переноса. второй параметрconfig
является объектом со следующими свойствами:
-
char: завернутый символ, например.
'
(одинарные кавычки) или“
(двойные кавычки), по умолчанию”
. -
skipIfQuoted
: логическое значение для пропуска кавычек, если строка уже заключена в кавычки, по умолчаниюtrue
.
Используя преимущества деструктора объекта, реализуемquote()
function quote(str, config) {
const { char = '"', skipIfQuoted = true } = config;
const length = str.length;
if (skipIfQuoted
&& str[0] === char
&& str[length - 1] === char) {
return str;
}
return char + str + char;
}
quote('Hello World', { char: '*' }); // => '*Hello World*'
quote('"Welcome"', { skipIfQuoted: true }); // => '"Welcome"'
const {char = '", skipifquote = true} = config
Разрушение присваивания в одной строке изconfig
извлечение объектаchar
а такжеskipifquote
Атрибуты. еслиconfig
В объекте есть некоторые свойства, которые недоступны, тогда назначение деструктурирования установит значения по умолчанию:char
для'"'
,skipifquote
дляfalse
.
Эту функцию еще можно улучшить. Давайте переместим назначение деструктурирования непосредственно в раздел параметров. и дляconfig
Параметр устанавливает значение по умолчанию (пустой объект{}
), чтобы пропустить второй параметр, если достаточно значения по умолчанию.
function quote(str, { char = '"', skipIfQuoted = true } = {}) {
const length = str.length;
if (skipIfQuoted
&& str[0] === char
&& str[length - 1] === char) {
return str;
}
return char + str + char;
}
quote('Hello World', { char: '*' }); // => '*Hello World*'
quote('Sunny day'); // => '"Sunny day"'
Обратите внимание, что присваивание деструктуризации заменяет функциюconfig
параметр. Мне это нравится:quote()
Одну строку сократили.={}
Убедитесь, что в правой части назначения деструктурирования используется пустой объект, вообще не указывая второй параметр.
Деструктуризация объектов — это мощная функция, которая эффективно обрабатывает извлечение свойств из объектов. Мне нравится возможность указать значение по умолчанию, которое будет возвращаться, когда запрашиваемое свойство не существует. потому что это позволяет избежатьundefined
и вопросы связанные с ним.
Совет 5: Заполните объекты свойствами по умолчанию
Объекты, у которых отсутствуют некоторые свойства, можно заполнить значениями по умолчанию, если нет необходимости создавать переменные для каждого свойства наподобие присваивания деструктурирования.
ES6 Object.assign(target,source1,source2,...)
Копирует значения всех перечисляемых собственных свойств из одного или нескольких исходных объектов в целевой объект, и функция возвращает целевой объект.
Например, необходимо получить доступunsafeOptions
Свойство объекта, которое не всегда содержит полный набор свойств.
Чтобы избежатьunsafeOptions
Доступ к несуществующему свойству, внесем некоторые коррективы:
-
Определяет свойство, которое содержит значения свойств по умолчанию.
defaults
объект -
передача
Object.assign({},defaults,unsafeOptions)
строить новые объектыoptions
. новый объект изunsafeOptions
Получает все свойства, но отсутствующие свойства отdefaults
приобретение объекта.
const unsafeOptions = {
fontSize: 18
};
const defaults = {
fontSize: 16,
color: 'black'
};
const options = Object.assign({}, defaults, unsafeOptions);
options.fontSize; // => 18
options.color; // => 'black'
unsafeOptions
содержит толькоfontSize
Атрибуты.defaults
Свойства определения объектаfontSize
а такжеcolor
значение по умолчанию для .
Object.assign()
Возьмите первый аргумент в качестве целевого объекта{}
. целевой объект изunsafeOptions
исходный объект получаетfontSize
Стоимость имущества. и людиdefaults
приобретение объектаcolor
значение атрибута, потому чтоunsafeOptions
не содержитcolor
Атрибуты.
Перечисление последовательности исходного объекта очень важно: задняя обложка перед свойством исходного объекта свойство исходного объекта.
теперь безопасно доступенoptions
любое свойство объекта, в том числеoptions.color
в начальномunsafeOptions
недоступен в .
Существует также простой способ использования оператора распространения в ES6:
const unsafeOptions = {
fontSize: 18
};
const defaults = {
fontSize: 16,
color: 'black'
};
const options = {
...defaults,
...unsafeOptions
};
options.fontSize; // => 18
options.color; // => 'black'
Инициализаторы объектов изdefaults
а такжеunsafeOptions
Расширенные свойства исходного объекта. Порядок, в котором указываются исходные объекты, важен, так как более поздние свойства исходных объектов переопределяют более ранние исходные объекты.
Заполнение незавершенных объектов значениями свойств по умолчанию — эффективная стратегия, позволяющая сделать ваш код безопасным и долговечным. В любом случае объект всегда содержит полный набор свойств: и не может быть сгенерированundefined
характеристики.
2.3 Функциональные параметры
Параметры функции неявно по умолчанию равны
undefined
.
Как правило, функции, определенные с определенным количеством параметров, должны вызываться с таким же количеством параметров. В этом случае параметр получает желаемое значение.
function multiply(a, b) {
a; // => 5
b; // => 3
return a * b;
}
multiply(5, 3); // => 15
передачаmultiply(5,3)
сделать параметрa
а такжеb
получить соответствующий5
а также3
значение, возвращаемый результат:5 * 3 = 15
.
Что происходит, когда вы опускаете аргументы при вызове?
function multiply(a, b) {
a; // => 5
b; // => undefined
return a * b;
}
multiply(5); // => NaN
функцияmultiply(a, b){}
по двум параметрамa
а такжеb
определение. передачаmultiply(5)
выполнить с одним аргументом: результат один аргумент5
,ноb
параметрundefined
.
Совет 6. Используйте значения параметров по умолчанию
Иногда функции не требуется полный набор аргументов для вызова, и вы можете просто установить значения по умолчанию для аргументов, которые не имеют значений.
Возвращаясь к предыдущему примеру, давайте сделаем улучшение, еслиb
Если параметр не определен, ему присваивается значение по умолчанию.2
:
function multiply(a, b) {
if (b === undefined) {
b = 2;
}
a; // => 5
b; // => 2
return a * b;
}
multiply(5); // => 10
Хотя предоставленный метод присвоения значения по умолчанию работает, не рекомендуется напрямую взаимодействовать сundefined
значение для сравнения. Это многословно и похоже на взлом.
Здесь можно использовать значения по умолчанию ES6:
function multiply(a, b = 2) {
a; // => 5
b; // => 2
return a * b;
}
multiply(5); // => 10
multiply(5, undefined); // => 10
2.4 Возвращаемое значение функции
косвенно, нет
return
заявление, функция JS возвращаетundefined
.
В JS нетreturn
Функция оператора возвращает неявноundefined
:
function square(x) {
const res = x * x;
}
square(2); // => undefined
square()
Функция не возвращает результат вычисления, результат при вызове функцииundefined
.
когдаreturn
Возвращает по умолчанию, если после оператора нет выраженияundefined
.
function square(x) {
const res = x * x;
return;
}
square(2); // => undefined
return;
Оператор выполняется, но не возвращает никакого выражения, и результат вызова такжеundefined
.
function square(x) {
const res = x * x;
return res;
}
square(2); // => 4
Совет 7: не доверяйте автоматической вставке точки с запятой
Перед следующим списком операторов в JS должна стоять точка с запятой(;)
конец:
-
пустой оператор
-
let,const,var,import,export
утверждение -
выразительное заявление
-
debugger
утверждение -
continue
утверждение,break
утверждение -
throw
утверждение -
return
утверждение
Если вы используете одно из приведенных выше объявлений, постарайтесь указать в концеточка с запятой:
function getNum() {
let num = 1;
return num;
}
getNum(); // => 1
let
заявление иreturn
В конце заявления обязательно написатьточка с запятой.
Что происходит, когда вы не хотите писать эти точки с запятой? Например, мы хотим уменьшить размер исходного файла.
В этом случае ECMAScript предоставляетМеханизм автоматической вставки точки с запятой (ASI), вставки для васотсутствует точка с запятой.
С помощью ASI это можно сделать из предыдущего примераудалить точку с запятой:
function getNum() {
// Notice that semicolons are missing
let num = 1
return num
}
getNum() // => 1
Приведенный выше код является действительным кодом JS, отсутствующийточка с запятойASI автоматически вставит его для нас.
На первый взгляд выглядит красиво. Механизм ASI позволяет писать меньше ненужных точек с запятой, что может сделать код JS меньше и его легче читать.
ASI создает небольшую, но раздражающую ловушку. когда новая строка находится вreturn
а такжеreturn \n expression
ASI автоматически вставляет точку с запятой перед новой строкой (return; \n expression
).
внутри функцииreturn;
? то есть функция возвращаетundefined
. Если вы не понимаете механизм ASI в деталях, неожиданно возвращаетсяundefined
Могут возникнуть неожиданные проблемы.
ПриходитьgetPrimeNumbers()
Значение, возвращаемое вызовом:
function getPrimeNumbers() {
return
[ 2, 3, 5, 7, 11, 13, 17 ]
}
getPrimeNumbers() // => undefined
существуетreturn
Между оператором и массивом есть новая строка, JS вreturn
Автоматически после точки с запятой, интерпретируемый код следующим образом:
function getPrimeNumbers() {
return;
[ 2, 3, 5, 7, 11, 13, 17 ];
}
getPrimeNumbers(); // => undefined
return;
сделать функциюgetPrimeNumbers()
вернутьundefined
вместо ожидаемого массива.
Этот вопрос снимаетсяreturn
и новые строки между литералами массива для разрешения:
function getPrimeNumbers() {
return [
2, 3, 5, 7, 11, 13, 17
];
}
getPrimeNumbers(); // => [2, 3, 5, 7, 11, 13, 17]
Мой совет - изучитьТочный способ автоматической вставки точки с запятой, чтобы избежать этого.
Конечно, никогдаreturn
Между выражением и возвращаемым выражением помещается новая строка.
2.5 Пустой оператор
void <expression>
Вычисляемое выражение возвращается независимо от результата вычисленияundefined
.
void 1; // => undefined
void (false); // => undefined
void {name: 'John Smith'}; // => undefined
void Math.min(1, 3); // => undefined
void
Одним из вариантов использования операторов является ограничение вычисления выражений доundefined
, который зависит от некоторых побочных эффектов оценки.
3. Неопределенный массив
При доступе к элементу массива с индексом за пределами границ вы получаетеundefined
.
const colors = ['blue', 'white', 'red'];
colors[5]; // => undefined
colors[-1]; // => undefined
colors
Массив состоит из 3 элементов, поэтому допустимый индекс0,1
а также2
.
из-за индекса5
а также-1
Элементов массива нет, поэтому доступcolors[5]
а такжеcolors[-1]
значениеundefined
.
В JS вы можете столкнуться с так называемыми разреженными массивами. Эти массивы разрываются, то есть по определенным индексам ни один элемент не определен.
При доступе к промежутку (также известному как пустой слот) в разреженном массиве вы также получаетеundefined
.
Следующий пример создает разреженные массивы и пытается получить доступ к их пустым слотам.
const sparse1 = new Array(3);
sparse1; // => [<empty slot>, <empty slot>, <empty slot>]
sparse1[0]; // => undefined
sparse1[1]; // => undefined
const sparse2 = ['white', ,'blue']
sparse2; // => ['white', <empty slot>, 'blue']
sparse2[1]; // => undefined
При использовании массивов, во избежание полученияundefined
, обязательно используйте допустимые индексы массива и избегайте создания разреженных массивов.
4. Разница между undefined и null
Возникает закономерный вопрос:undefined
а такжеnull
В чем основная разница между двумя этими специальными значениями, представляющими пустое состояние.
Основное отличие в том, чтоundefined
представляет значение переменной, которая еще не была инициализирована,null
Указывает, что объект не существует намеренно.
Давайте рассмотрим различия между ними на некоторых примерах.
число определено, но ему не присвоено значение.
let number;
number; // => undefined
number
Переменная не определена, что явно указывает на неинициализированную переменную.
Та же концепция неинициализированного также возникает при доступе к несуществующему свойству объекта.
const obj = { firstName: 'Dmitri' };
obj.lastName; // => undefined
потому чтоobj
не существует вlastName
свойство, поэтому JS правильно будетobj.lastName
Рассчитано какundefined
.
В других случаях вы знаете, что переменная ожидает объект или функцию, которая возвращает объект. Но по какой-то причине вы не можете создать экземпляр этого объекта. при этих обстоятельствах,null
является значимым индикатором отсутствующих объектов.
Например,clone()
это функция, которая клонирует обычный объект JS, функция вернет объект
function clone(obj) {
if (typeof obj === 'object' && obj !== null) {
return Object.assign({}, obj);
}
return null;
}
clone({name: 'John'}); // => {name: 'John'}
clone(15); // => null
clone(null); // => null
Однако можно вызывать с аргументами, не являющимися объектами.clone()
: 15
илиnull
(или обычно примитивное значение,null
илиundefined
). В этом случае функция не может создать клон, поэтому возвращаетnull
- индикатор пропавшего предмета.
typeof
оператор различает два значения
typeof undefined; // => 'undefined'
typeof null; // => 'object'
оператор строгого равенства===
может правильно различатьundefined
а такжеnull
:
let nothing = undefined;
let missingObject = null;
nothing === missingObject; // => false
Суммировать
undefined
Существование JS является результатом разрешительного характера JS, который позволяет использовать:
- неинициализированная переменная
- Несуществующее свойство или метод объекта
- доступ к элементу массива по индексу за пределами границ
- результат вызова функции, которая не возвращает результата
В большинстве случаев непосредственно сundefined
Сравнение — плохая практика. Эффективная стратегия заключается в уменьшении количестваundefined
Возникновение ключевых слов:
-
Уменьшите использование неинициализированных переменных
-
Сделайте время жизни переменной коротким и близким к тому, где она используется.
-
Присваивайте начальные значения переменным, когда это возможно
-
Более формальный const и пусть
-
Используйте значение по умолчанию, чтобы указать несущественный параметр функции
-
Проверить существование свойства или заполнить небезопасный объект свойством по умолчанию
-
Избегайте разреженных массивов
Ошибки, которые могут существовать после развертывания кода, не могут быть известны в режиме реального времени.Чтобы решить эти ошибки впоследствии, много времени тратится на отладку журнала.Кстати, я рекомендую всем полезный инструмент мониторинга ошибок.Fundebug.
общаться с
Статья постоянно обновляется каждую неделю. Вы можете выполнить поиск «Big Move to the World» в WeChat, чтобы прочитать и обновить ее как можно скорее (на одну или две статьи раньше, чем в блоге). Эта статья находится на GitHub.GitHub.com/QQ449245884…Он был включен, и многие мои документы были разобраны. Добро пожаловать в Звезду и совершенство. Вы можете обратиться в тестовый центр для ознакомления во время собеседования. Кроме того, обратите внимание на паблик-аккаунт и ответьте в фоновом режиме.Благосостояние, вы можете увидеть преимущества, вы знаете.