【05】ES6: Расширение функции

1. Значения параметров функции по умолчанию

ES6 позволяет устанавливать значения по умолчанию для параметров функции сразу после определения параметра.

1. Основное использование

Условия действия значений по умолчанию

Не передавайте никаких параметров или явно передайте неопределенное значение в качестве параметра.Только в этих двух случаях вступит в силу значение по умолчанию.

注意:null 就是 null,不会使用默认值。

// ES6 之前的默认值实现方式
const log = (x, y) => {
    
    
	// typeof类型检测:返回表示当前数据类型的字符串
    if (typeof y === 'undefined') {
    
    
        y = 'world'
    }
    
    console.log(x, y)
}

log('Hello') // Hello World
log('Hello', 'China') // Hello China
log('Hello', '') // Hello
// ES6 默认值实现方式
function log(x, y = 'World') {
    
    
	console.log(x, y)
}

log('Hello') // Hello World
log('Hello', 'China') // Hello China
log('Hello', '') // Hello

Некоторые правила для значений по умолчанию

Переменные-параметры объявляются по умолчанию, поэтому их нельзя объявить повторно с помощью let или const.

function foo(x = 5) {
    
    
	let x = 1 // error
	const x = 2 // error
}

При использовании значений параметров по умолчанию функции не могут иметь параметры с одинаковыми именами.

// 不报错
function foo(x, x, y) {
    
    
	// ...
}

// 报错 SyntaxError: Duplicate parameter name not allowed in this context
function foo(x, x, y = 1) {
    
    
	// ...
}

Значения параметров по умолчанию оцениваются лениво. Значение параметра по умолчанию не передается по значению, но значение выражения значения по умолчанию пересчитывается каждый раз.

let x = 99
function foo(p = x + 1) {
    
    
	console.log(p)
}

foo() // 100

x = 100
foo() // 101

2. Используется вместе со значением деструктуризации назначения по умолчанию.

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

// 只使用对象的解构赋值默认值
function foo({
     
      x, y = 5 }) {
    
    
	console.log(x, y)
}

foo({
    
    }) // undefined 5
foo({
    
     x: 1 }) // 1 5
foo({
    
     x: 1, y: 2 }) // 1 2
// 函数 foo()调用时没提供参数,变量 x 和 y 就不会生成,从而报错
foo() // TypeError: Cannot read property 'x' of undefined


// -------------------------------------------


// 使用对象的解构赋值默认值 + 函数参数的默认值
function foo({
     
      x, y = 5 } = {
     
     }) {
    
    
	console.log(x, y)
}

foo() // undefined 5
// 只使用对象的解构赋值默认值
function fetch(url, {
    
     body = '', method = 'GET', headers = {
    
    } }) {
    
    
	console.log(method)
}

fetch('http://example.com', {
    
    }) // 'GET'
fetch('http://example.com') // 报错

// --------------------------------------------------

// 使用对象的解构赋值默认值 + 函数参数的默认值
function fetch(url, {
    
     body = '', method = 'GET', headers = {
    
    } } = {
    
    }) {
    
    
	console.log(method)
}

fetch('http://example.com') // 'GET'

注意,函数参数的默认值生效以后,参数解构赋值依然会进行。

// 参数默认值 { a: 'hello' } 生效;进行解构赋值,从而触发参数变量 b 的默认值生效。
function f({
    
     a, b = 'world' } = {
    
     a: 'hello' }) {
    
    
	console.log(b)
}

f() // world


// 解构赋值的默认值只在属性值为 undefined 时才会生效
function f({
    
     a, b = 'world' } = {
    
     b: 'hello' }) {
    
    
	console.log(b)
}

f() // hello

3. Положение значения параметра по умолчанию.

Обычно параметры с определенными значениями по умолчанию должны быть хвостовыми параметрами функции. Потому что легче увидеть, какие параметры опущены. Если для параметра, не являющегося хвостовым, установлено значение по умолчанию, этот параметр фактически нельзя опустить.

// 例一
function f(x = 1, y) {
    
    
	return [x, y]
}

f() // [1, undefined]
f(2) // [2, undefined]
f(, 1) // 报错
f(undefined, 1) // [1, 1]

// 例二
function f(x, y = 5, z) {
    
    
	return [x, y, z]
}

f() // [undefined, 5, undefined]
f(1) // [1, 5, undefined]
f(1, ,2) // 报错
f(1, undefined, 2) // [1, 5, 2]

В приведенном выше коде параметры со значениями по умолчанию не являются хвостовыми параметрами. В настоящее время вы не можете опустить только этот параметр, не опуская параметры после него, если только вы явно не введете неопределенное значение.

Если передано значение undefined, это приведет к тому, что параметр будет равен значению по умолчанию. Если значение равно нулю, это не будет иметь такого эффекта.

function foo(x = 5, y = 6) {
    
    
	console.log(x, y)
}

foo(undefined, null) // 5 null

4. Атрибут длины функции

Атрибут длины функции равен количеству параметров, которые, как ожидается, будут переданы в функцию.

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

(function (a) {
    
    }).length // 1
(function (a = 5) {
    
    }).length // 0
(function (a, b, c = 5) {
    
    }).length // 2

(function(...args) {
    
    }).length // 0

(function (a = 0, b, c) {
    
    }).length // 0
(function (a, b = 1, c) {
    
    }).length // 1

5. Приложение

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

function throwIfMissing() {
    
    
	throw new Error('Missing parameter')
}

function foo(mustBeProvided = throwIfMissing()) {
    
    
	return mustBeProvided
}

foo() // Error: Missing parameter

Если функция foo в приведенном выше коде вызывается без параметров, будет вызвана функция throwIfMissing со значением по умолчанию, что вызовет ошибку.

Из приведенного выше кода также видно, что значение параметра mustBeProvided по умолчанию равно результату выполнения функции throwIfMissing (обратите внимание, что после имени функции throwIfMissing стоит пара круглых скобок), что указывает на то, что значение по умолчанию для функции throwIfMissing параметр выполняется не во время определения, а во время выполнения. Если параметру присвоено значение, функция со значением по умолчанию не будет запущена.

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

function foo(optional = undefined) {
    
     ··· }

2. параметр сброса (…неопределенный параметр)

ES6 вводит параметр rest (в форме... имени переменной) для получения дополнительных параметров функции, поэтому нет необходимости использовать объект аргументов. Переменная, сопоставленная с остальным параметром, представляет собой массив, который помещает в массив дополнительные параметры.

function add(...values) {
    
    
	let sum = 0
	
	for (var val of values) {
    
    
		sum += val
	}
	
	return sum
}

add(2, 5, 3) // 10
// arguments 变量的写法
function sortNumbers() {
    
    
	// arguments 为类数组对象,需先使用 Array.from 转换为数组
	return Array.from(arguments).sort()
}

// rest 参数的写法 (reset 参数为真正的数组)
const sortNumbers = (...numbers) => numbers.sort()

Обратите внимание, что после оставшегося параметра не может быть никаких других параметров (то есть это может быть только последний параметр), иначе будет сообщено об ошибке.

// 报错
function f(a, ...b, c) {
    
    
	// ...
}

Свойство длины функции, исключая параметр rest.

(function(a) {
    
    }).length  // 1
(function(...a) {
    
    }).length  // 0
(function(a, ...b) {
    
    }).length  // 1

3. Функция стрелки

ES6 предусматривает, что вы можете использовать «стрелку» => для определения функции, а синтаксис более краток. У него нет своих this, аргументов, super или new.target.Выражения стрелочных функций больше подходят для тех мест, где можно было бы ожидать анонимную функцию, но ее нельзя использовать в качестве конструктора.

1. Основное использование

Обычная функция

function 函数名() {
    
    }

const 变量名 = function () {
    
    }

функция стрелки

(参数) => {
    
    函数体}

const 变量名 = () => {
    
    }
// 基本语法
const add = (x, y) => {
    
    
	return x + y
}

// 有且只有一个参数,()可以省略
const add = x => {
    
    
	return x + 1
}

// 有且只有一条语句,且为 returen 语句,{} 和 return 可以省略
const add = (x, y) => x + y

// return 为对象时,对象外需要加 ()
const add = (x, y) => {
    
    
    return {
    
    
        value: x + y
    }
}
const add = (x, y) => ({
    
     value: x + y })

2. Функция, на которую это указывает

это в es5 указывает на

Значение функции this определяется во время выполнения функции, а не при ее определении.

(1) Вызывается как обычная функция и указывает на окно

(2) При вызове как метод объекта указывает на текущий объект.

(3) В конструкторе (метод класса es5, es6) это указывает на объект экземпляра, созданный с помощью конструктора.

(5) this функции таймера указывает на окно, а функция таймера эквивалентна вызову обычной функции (setTimeout | setInterval)

This функции стрелки в es6 указывает на

This в стрелочной функции привязан, когда он определен. Это принимает this из верхней области. Сама стрелочная функция не определяет значение this.

позвонить、 подать заявку、 связать

fn.call(this, ...params) и fn.apply(this, [params]) используются для изменения указателя this функции
Разница в том, что что параметры передаются по-разному, call() принимает список, apply() принимает массив

Метод fn.bind(this, params) также используется для изменения точки this функции, но он не будет выполнен сразу, а вернет новую функцию.

3. Сценарии, в которых стрелочные функции неприменимы

как конструктор

Потому что у стрелочной функции этого нет, а ядро ​​конструктора именно такое.

Когда вам нужно, чтобы это указывало на вызывающий объект

Поскольку у стрелочной функции этого нет, если это появляется в стрелочной функции, то это внешний слой!

При привязке метода к событию, например привязке метода к событию через addEventListener, если используется стрелочная функция, это будет указывать на родительское это окно.

Стрелочные функции нельзя использовать при определении методов объекта.

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

Когда необходимо использовать аргументы

Стрелочные функции не имеют аргументов. (У этой проблемы есть альтернативное решение: неопределенные параметры)

нет прототипа

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

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

4. Запятая для параметров функции.

ES2017 допускает использование запятой в последнем параметре функции.

Раньше запятая не допускалась после последнего параметра при определении или вызове функции.

function clownsEverywhere(
	param1,
	param2
) {
    
     /* ... */ }

clownsEverywhere(
	'foo',
	'bar'
)

Если в приведенном выше коде вы добавите запятую после param2 или bar, будет сообщено об ошибке.

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

function clownsEverywhere(
	param1,
	param2,
) {
    
     /* ... */ }

clownsEverywhere(
	'foo',
	'bar',
)

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

5. Параметры команды catch опущены.

Структура try...catch языка JavaScript ранее явно требовала, чтобы за командой catch следовали параметры и принимался объект ошибки, созданный блоком кода try.

try {
    
    
	// ...
} catch (err) {
    
    
	// 处理错误
}

В приведенном выше коде за командой catch следует параметр err.

Во многих случаях этот параметр нельзя использовать в блоке кода catch. Однако, чтобы обеспечить правильную грамматику, вам все равно придется писать. В ES2019 внесены изменения, которые позволяют операторам catch опускать параметры.

try {
    
    
	// ...
} catch {
    
    
	// ...
}

рекомендация

отblog.csdn.net/weixin_45559449/article/details/134597708