【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]

上記のコードでは、デフォルト値を持つパラメータは末尾パラメータではありません。このとき、明示的にunknownと入力しない限り、以降のパラメータを省略せずにこのパラメータだけを省略することはできません。

未定義が渡されると、パラメータがデフォルト値と等しくなるようにトリガーされます。null の場合は、この効果はありません。

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 であることを示しています。パラメータは定義時ではなく実行時に実行されます。パラメータに値が割り当てられている場合、デフォルト値の関数は実行されません。

さらに、パラメータのデフォルト値を undefine に設定して、このパラメータを省略できることを示すことができます。

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) {
    
    
	// ...
}

残りのパラメーターを除く、関数の長さのプロパティ。

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

3. アロー関数

ES6 では、関数の定義に "arrow" => を使用できることが規定されており、構文はより簡潔になっています。独自の 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) と同等です。

es6 のアロー関数の this は次を指しています。

アロー関数のthisは定義時にバインドされており、上位スコープのthisを取得しますが、アロー関数自体はthisの値を決定しません。

コール、適用、バインド

fn.call(this, ...params) と fn.apply(this, [params]) はどちらも関数の this ポインタを変更するために使用されます
違いは次のとおりです。パラメータが異なる方法で渡されること、call() はリストを受け入れること、apply() は配列を受け入れること

fn.bind(this, params) メソッドは、関数の this ポイントを変更するためにも使用されますが、すぐには実行されず、新しい関数が返されます。

3. アロー機能が適用できないシナリオ

コンストラクターとして

アロー関数にはこれがなく、コンストラクタのコアはこれであるためです。

これが呼び出し元のオブジェクトを指す必要がある場合

アロー関数にはこれがないので、アロー関数にこれが出てきたら、これが外層だ!

メソッドをイベントにバインドするとき (たとえば、addEventListener を通じてメソッドをイベントにバインドするとき)、アロー関数が使用されている場合、これは親のこのウィンドウを指します。

オブジェクトにメソッドを定義する場合、アロー関数は使用できません

vue のメソッドではアロー関数を使用できません。これにより、現在の vm インスタンス以外のものを指すことになり、エラーが発生します。

引数を使用する必要がある場合

アロー関数には引数がありません。 (この問題には別の解決策があります: 不定パラメータ)

プロトタイプなし

アロー関数はコンストラクターとして使用できないため、独自のプロトタイプを持ちません。したがって、プロトタイプ プロパティを使用して新しいメソッドを追加することはできません。

yield コマンドは使用できないため、アロー関数をジェネレーター関数として使用することはできません

4. 関数パラメータの末尾のカンマ

ES2017 では、関数の最後のパラメーターに末尾のカンマを使用できます。

以前は、関数を定義または呼び出すときに、最後のパラメーターの後にカンマを使用することはできませんでした。

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

clownsEverywhere(
	'foo',
	'bar'
)

上記のコードで、param2 または bar の後にカンマを追加すると、エラーが報告されます。

上記のようにパラメータを複数行に分けて記述した場合(つまり、各パラメータが 1 行を占める)、将来コードを修正するときに、関数 clownsEverywhere に 3 番目のパラメータを追加したり、パラメータの順序を調整したりする必要がある場合に、の場合は、最後のパラメータの後に追加する必要があります。バージョン管理システムの場合、カンマが追加された行も変更されたことがわかります。これは少し冗長に見えるため、新しい構文では、末尾にコンマを付けて定義と呼び出しを行うことができます。

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

clownsEverywhere(
	'foo',
	'bar',
)

この規定により、関数パラメータが配列およびオブジェクトの末尾のカンマ規則と一致するようになります。

5. catchコマンドのパラメータは省略されています

JavaScript 言語の try...catch 構造では、以前は、catch コマンドの後にパラメータを指定し、try コード ブロックによってスローされたエラー オブジェクトを受け入れる必要があることが明示的に要求されていました。

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

上記のコードでは、catch コマンドの後にパラメータ err が続きます。

多くの場合、このパラメータはキャッチ コード ブロックでは使用されない場合があります。ただし、文法が正しいことを確認するには、やはり書く必要があります。 ES2019 では、catch ステートメントでパラメーターを省略できるように変更されました。

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

おすすめ

転載: blog.csdn.net/weixin_45559449/article/details/134597708