Всем привет, увидимся снова.
Праздники быстротечны, в первый рабочий день после нового года очень не хочется вставать утром, поэтому одеваюсь с закрытыми глазами, чтобы не опоздать.
Ладно, ладно, давайте к делу, взбодритесь!
предисловие
Функции являются важной частью всех языков программирования.До появления Es6 синтаксис функций в JavaScript не сильно изменился, оставив много проблем и неясных практик, что привело к необходимости написания большого количества кода для реализации некоторых функций.
значение параметра функции по умолчанию
Особенность функций JavaScript заключается в том, что независимо от того, сколько параметров определяются в параметрах функции, любое количество параметров может быть передано, но в некоторых случаях наши параметры могут быть заполнены только, поэтому мы все еще находимся в телу функции. Написание кучу логики приводит к резервию кода. К счастью, версия ES6 имеет функциональные значения по умолчанию.
Сравним коды Es5 и Es6
Es5 обрабатывает параметры по умолчанию
function person(name, age) {
name = typeof(name) != "undefined" ? name : `蛙人${+ new Date()}`
age = typeof(age) != "undefined" ? age : 24
}
person()
В приведенном выше примере Es5 обрабатывает значения параметров по умолчанию таким образом.Если у нас будет слишком много параметров, будет очень избыточно писать код таким образом, поэтому Es6 имеет значения параметров функции по умолчанию.
Es6 обрабатывает параметры по умолчанию
function person(name = "蛙人", age = 24) {
console.log(name, age)
}
person() // 蛙人 24
person("张三", 30) // 张三 30
person(null, null) // null null
В приведенном выше примере параметр по умолчанию обрабатывается в Es6. Вы можете видеть, что код очень упрощен. В приведенном выше коде вы можете видеть, что параметр передается в значении null, что также является допустимым значением для параметра по умолчанию. В этом случае он будет использоваться только в том случае, если параметр функции не определен.
выражение параметра функции
Что касается значений параметров по умолчанию, наиболее интересной особенностью может быть то, что в параметры передаются непримитивные значения, а параметры по умолчанию также могут быть определены как函数
or 变量
.
function defaultName() {
return "蛙人"
}
function person(name = defaultName()) {
console.log(name)
}
person("张三") // 张三
person() // 蛙人
Следует отметить, что выражение параметра по умолчанию выполняется не сразу после создания функции, а при создании функции.
person
Выполняется при вызове без передачи аргументов.
В приведенном выше примере, если никакие параметры не переданы, будет вызвано значение по умолчаниюdefaultName
функция.
Давайте посмотрим на параметры по умолчанию, передаваемые в переменных.
let defaultName = "蛙人"
function person(name = defaultName) {
console.log(name)
}
person("张三") // 张三
person() // 蛙人
function person(name, nickName = name) {
console.log(name, nickName)
}
person("张三") // 张三 张三
person("蛙人", "掘金蛙人") // 蛙人 掘金蛙人
В приведенном выше примере мы можем понять внутреннюю часть первого блока кода, но заменим предыдущую функцию переменной. Глядя на код во втором блоке кода, мы ставимnickName
Значение параметра по умолчанию установлено на первый параметрname
Параметр, это при ссылке на значение параметра по умолчанию, разрешено ссылаться только на значение предыдущего параметра, что эквивалентно параметру функции, является определенной переменной, наша последняя переменная может получить доступ к предыдущей переменной, но это эта функция ограничена только текущей областью действия Параметром является текущая область. Давайте посмотрим на другой пример.
function person(name = nickName, nickName) {
console.log(name, nickName)
}
person("张三") // 张三 undefined
В приведенном выше примере значением по умолчанию первого параметра является второй параметр. В это время операция выдаст ошибку, потому что доступ ко второй переменной до ее определения вызовет временную мертвую зону. Если вы не понимаете временную мертвая зона Вы можете перейти к моей прошлой статье.«Разница между var, let и const, которую вы можете понять с первого взгляда»
Влияние значений параметров функции по умолчанию на аргументы
Объект Arguments ведет себя по-разному при использовании аргументов функции по умолчанию
Использование аргументов в нестрогом режиме Es5
В нестрогом режиме Es5 изменение именованных параметров функции будет отражено вarguments
на объекте,arguments
Получает фактические параметры текущей функции,arguments
В нестрогом режиме это отношение отображения с формальными параметрами, то есть формальные параметры изменяютсяarguments
Следите за изменением.
function test(a, b) {
console.log(a == arguments[0]) // true
console.log(b == arguments[1]) // true
a = "a"
b = "b"
console.log(arguments) // ["a", "b"]
}
test(1, 2)
В приведенном выше примере в нестрогом режиме изменения именованных параметров будут обновляться синхронно сarguments
в объекте. когдаa
Изменения параметров будут отображены наarguments[0]
на объекте.
Использование аргументов в строгом режиме Es5
Давайте посмотрим на строгий режимarguments
function test(a, b) {
'use strict';
console.log(arguments) // [1, 2]
b = 10
console.log(arguments) // [1, 2]
}
test(1, 2)
Приведенный выше пример находится в строгом режиме, видно, что когда мы меняем параметрыb
, распечатать сноваarguments
объект, который также является значением инициализации. в строгом режимеJavaScript
отменен вarguments
Возражайте против этого запутанного поведения, независимо от того, как изменяется параметр,arguments
Объект больше не меняется вместе с ним.
Влияние использования значений параметров по умолчанию на аргументы в Es6
В Es6, если функция использует значения параметров по умолчанию, тоarguments
Поведение объекта будет таким же, какJavaScript
Согласован в строгом режиме.
function test(a, b = 2) {
a = 12
b = 10
console.log(arguments) // [1]
}
test(1)
В приведенном выше примереarguments
распечатать объект[1]
Потому чтоarguments
Объект получает фактический параметр, мы видим, что параметру фактического параметра передается значение, поэтомуarguments
Объект имеет только одно значение. Посмотрите на второй пункт,a
а такжеb
параметры изменили значения, ноarguments
Объект все еще не изменился, о чем я сказал выше,如果一个函数使用了默认参数值,那么arguments对象的行为都将与JavaScript中的严格模式下保持一致
.
Обработка безымянных параметров
Количество параметров функции в js произвольное, когда передается меньшее количество, функция параметров по умолчанию может эффективно упростить код объявления функции. Es6 также обеспечивает лучшее решение, когда передается больше объемов.
Получить безымянные параметры в Es5
function test(a, b, c) {
console.log(arguments) // [1, 2, 3]
}
test(1, 2, 3)
В приведенном выше примереarguments
Объекты тоже могут достигать всех параметров, но если мы хотим получить все параметры после второго параметра, то придется зацикливаться.
Получить безымянные параметры в Es6
function test(...parmas) {
console.log(params) // [1, 2, 3, 4]
}
test(1, 2, 3, 4)
function test(a, b, ...params) {
console.log(params)
}
test(1, 2, 3, 4)
В приведенном выше примере первый блок кода реализует получение всех параметров в Es6, но это не соответствует нашим потребностям. Затем смотрим код во втором блоке кода, и мы получаем все параметры после второго параметра.
Es6 получает недостатки неназванных параметров
Прежде всего, каждая функция может объявить только один переменный параметр, и его можно поместить только в конец функции, иначе будет сообщено об ошибке.
function test(...params, a, b) {
}
test()
В приведенном выше примере будет выброшена ошибка После объявления неопределенного количества параметров вы не сможете продолжить объявление параметров позже.
Еще один момент, неопределенные параметры не могут быть определены в литерале объектаsetter
в, потому чтоsetter
Функция получает только одну функцию, и это будет массив после того, как он будет записан как неопределенный параметр, что вызовет исключения программы.
let obj = {
set name(...params) {
}
}
атрибут имени функции
существуетJavaScript
Все функции вname
свойство, которое содержит строку имени функции. Функция без имени по-прежнему имеетname
свойства,name
Значение свойства — пустая строка.
function person() {}
let test = function() {}
console.log(person.name) // person
console.log(test.name) // test
В приведенном выше примереperson
функцияname
Значением атрибута является «человек», что соответствует имени функции на момент объявления. выражение анонимной функцииtest
функциональныйname
Имя, соответствующее переменной, присвоенной анонимной функции.
Особый случай атрибута name
Я изначально думал, что каждая функцияname
Все имена соответствуют текущему имени функции, но позже было обнаружено, что это не так. Рассмотрим частный случай функции
var person = {
get getName() {
return "蛙人"
}
}
console.log(Object.getOwnPropertyDescriptor(person, 'getName').get.name) // get getName
function test() {}
console.log(test.bind().name) // bound test
В приведенном выше примереperson.getName
является функцией стоимостиgetter
, поэтому имя его функцииget getName
,еслиsetter
функция, то имя будет иметь префиксset
. пройти черезbind
Созданы функции, имена которых имеют префикс «bound».
стрелочная функция
Функция стрелки в Es6 — одна из самых интересных функций, функция стрелки — это своего рода стрелка использования.=>
Новый синтаксис для определения функций, но он отличается от традиционногоJavaScript
Функции немного отличаются, подробности см. в следующих пунктах.
- нет
this
,super
,arguments
- не могу пройти
new
вызов ключевого слова - нет прототипа
prototype
- не может быть изменен
this
направление - Повторяющиеся именованные параметры не поддерживаются
Стрелочные функции, как и традиционные функции, имеют неизменный атрибут имени.
Синтаксис стрелочной функции
let person = () => "蛙人"
// 相当于下代码
function person() {
return "蛙人"
}
В приведенном выше примере, когда вычисляется выражение справа от стрелочной функции, оно возвращается немедленно.
Параметры стрелочной функции
let getName = val => val
// 相当于下代码
function getName(val) {
return val
}
Когда стрелочная функция имеет только один параметр, вы можете опустить круглые скобки и написать имя параметра напрямую. Если вы хотите передать два или более параметра, вам нужно поставить круглые скобки. см. пример ниже
let sum = (a, b) => a + b
// 相当于下代码
function sun(a, b) {
return a + b
}
Если вы хотите вернуть литерал объекта, вы можете написать
let getObj = () => ({name: "蛙人", age: 24}) // {name: "蛙人", age: 24}
// 相当于下代码
function getObj() {
return {
name: "蛙人",
age: 24
}
}
Стрелочные функции не имеют этого
стрелочная функцияthis
значение, зависящее от значения нестрелочной функции вне функцииthis
Значение, если верхний слой все еще стрелочная функция, то продолжить поиск вверх, если не найдено, тоthis
то естьwindow
объект
let person = {
test: () => {
console.log(this)
},
fn() {
return () => {
console.log(this)
}
}
}
person.test() // window
person.fn()() // person对象
В приведенном выше примере хорошо видно, что стрелка неthis
, то егоthis
Он найдет только функции, которые не являются стрелочными функциями во внешнем слое.
Стрелочные функции неarguments
объект
Также не работает стрелкаarguments
объект, но если во внешнем слое есть слой нестрелочных функций, он найдет функцию внешнего слоя.arguments
объект следующим образом
let test1 = () => console.log(arguments) // 执行该函数会抛出错误
function test2(a, b, c) {
return () => {
console.log(arguments) // [1, 2, 3]
}
}
test2(1, 2, 3)()
В приведенном выше примере вы можете ясно видеть, что текущая стрелочная функция не работает.arguments
объект, но перейдите к его внешнему слою, чтобы найти функции, которые не являются стрелочными функциями.注意:箭头函数找arguments对象只会找外层非箭头函数的函数,如果外层是一个非箭头函数的函数如果它也没有arguments对象也会中断返回,就不会在往外层去找了
. см. пример ниже
function test(a) {
return function() {
return () => {
console.log(arguments) // []
}
}
}
test(1)()()
Как вы можете видеть в приведенном выше примере, стрелочная функция внутри ищет нестрелочную функциональную функцию во внешнем слое, а затем независимо от того, имеет ли внешний слой эту функцию или нетarguments
объекты возвращаются. Только это не стрелочная функция, и если внешний слой является стрелочной функцией, она продолжит искать внешний слой.
Функции стрелок не могут быть использованыnew
объявление ключевого слова
let test = () => {}
new test() // 抛出错误,找不到constructor对象
Стрелочные функции не имеют прототипаprototype
Помните, стрелочные функции не имеют прототипов, и интервьюер может спросить:JavaScript
Все функции в наличииprototype
атрибут?
let test = () => {}
test.prototype // undefined
Функции стрелок не могут быть измененыthis
направление
let person = {}
let test = () => console.log(this)
test.bind(person)()
test.call(person)
test.apply(person)
В приведенном выше примере изменитеthis
Ни один из указанных методов не вызовет ошибку, но ни один из них недействителен и не может быть изменен.this
направление.
Функция стрелки не может повторить параметры именования
let sum = (a, a) => {} // 抛出错误,参数不能重复
Если вы считаете, что это хорошо написано, то ставьте палец вверх!
Вы также можете добавить мой WeChat для общения