「javascript高級プログラム設計」学習ノート10.9-10.11.関数内部
10110 ワード
注目前端の民謡より多くのオリジナル技術記事を読む
関連コード→
10.9関数内部ES 5には、関数内部に2つの特殊オブジェクト ES 6新規 10.9.1アーグメンントキーワード定義関数の場合のみ 対象は一つ 厳格モードでアクセス 標準関数では、 矢印関数 イベントコールやタイミングコールである関数を呼び出した場合 ES 5は、 厳格モードでアクセス ES 6が関数内部に追加 未使用 使用 関数には2つの属性が含まれています. 関数には3つの方法があります. に結び付けられている.関数宣言の重要な特徴は、関数宣言の向上であり、すなわち関数声明がコード実行前に定義されること 関数式は、先に値を付けてから使用し、匿名関数を作成する必要があります( 匿名関数の 関数宣言と関数表現の違いは、関数宣言の使用を条件ブロックで避け、関数式 関数を作成し、変数に値を割り当てることで、他の関数を1つの関数の値として返すことができる argmentsとは何ですか?argments.calleeはどこを指しますか?関数名と関数論理が結合されている階乗関数 thisの標準関数と矢印関数の指向はどう違いますか?イベントのコールバックやタイミングのコールバックでは、なぜ矢印関数がより適切なのですか? 関数のcaler属性はどこを指していますか?argments.callerの値は何ですか?厳格なモードではどのような制限がありますか? new.targetの役割と値はそれぞれ何ですか? 関数にはどのような属性がありますか?指差と使い方はそれぞれ何ですか? 関数のスコープをコードで証明してください.Funtions.prototype.apply.call()、bind()はどのように関数のスコープを拡張し、Function.prototype.apple.call()の意味を説明してください. 関数宣言と関数表現の最大の違いは何ですか?どのように声明のアップグレードを理解しますか? コードを書いて、対象配列のある対象属性に従って並べ替えて、パラメータによって並べ替え属性と昇順
関連コード→
10.9関数内部
arguments
和this
、1つの内部属性caller
new.target
属性arguments
関数を呼び出した時に入ってきたすべてのパラメータを含むクラスのオブジェクトfunciton
オブジェクト(矢印関数なし)arguments
属性であり、指し示すcallee
所在関数の指針(関数ではなくポインタである関数名)arguments
エラー// :
function factorial(num) {
if (num <= 1) return 1
else return num * factorial(num - 1)
}
// arguments.callee
function factorial(num) {
if (num <= 1) return 1
else return num * arguments.callee(num - 1) // callee arguments
}
let trueFactorial = factorial //
// factorial ,trueFactorial
factorial = function () {
return 0
}
console.log(trueFactorial(5)) // 120, arguments.callee ,
console.log(factorial(5)) // 0,
10.9.2 thisarguments.callee
関数を指すコンテキストオブジェクト、すなわち関数が実行する環境オブジェクト(グローバルスコープthis
)window.color = 'red' // vscode node , window, window global
let o = { color: 'blue' }
function sayColor() {
console.log(this.color)
}
sayColor() // 'red',this
o.sayColor = sayColor
o.sayColor() // 'blue',this o
window
定義関数のコンテキストオブジェクト、すなわちこの関数の外部の環境オブジェクトlet sayColor2 = () => {
console.log(this.color) // this sayColor2 ,
}
sayColor2() // 'red',this
o.sayColor2 = sayColor2
o.sayColor2() // 'red',this
this
意図していないオブジェクトを指し、コールバック関数を矢印関数として書いて問題を解決することができるfunction King() {
this.royaltyName = 'Henry'
setTimeout(() => {
console.log(this.royaltyName) // ,this , King()
}, 1000)
}
function Queen() {
this.royaltyName = 'Elizabeth'
setTimeout(function () {
console.log(this.royaltyName) // ,this , setTimeout()
}, 1000)
}
new King() // 'Henry',1
new Queen() // undefined,1
10.9.3 callerthis
属性を定義し、現在の関数を呼び出す関数(グローバルスコープではnull)function callerTest() {
console.log(callerTest.caller)
}
callerTest() // null,
function outer() {
inner()
}
function inner() {
console.log(inner.caller)
}
outer() // [Function: outer], outer()
//
function inner() {
console.log(arguments.callee.caller) // arguments.callee arguments , inner
}
outer() // [Function: outer], outer()
caller
の値はあくまでもarguments.caller
の区別undefined
関数のためのarguments.caller
caller
関数であるarguments.caller
属性割当値がエラーfunction inner2() {
console.log(arguments.caller) // undefined
console.log(arguments.callee) // [Function: inner2]
}
inner2()
10.9.4 new.targetcaller
属性を追加し、検出関数が使用されているかどうかnew.target
キーワードコールnew
呼び出し、new
の値はnew.target
undefined
呼び出し、new
の値は呼び出しのコンストラクターfunction King2() {
if (!new.target) {
console.log(new.target, 'King2 must be instantiated using "new"')
} else {
console.log(new.target, 'King2 instantiated using "new"')
}
}
new King2() // [Function: King2] 'King2 instantiated using "new"'
King2() // undefined 'King2 must be instantiated using "new"'
10.10関数の属性と方法new.target
length
prototype
保存関数が受信したいネーミングパラメータの個数function nameLength(name) {
return name
}
function sumLength(sum1, sum2) {
return sum1 + sum2
}
function helloLength() {
return 'Hello'
}
console.log(nameLength.length, sumLength.length, helloLength.length) // 1 2 0
length
ポインティング関数のプロトタイプオブジェクト、保存関数のすべての例の方法は列挙できない(使用prototype
発見できない)console.log(Array.prototype) // Array , sort()
console.log(Object.keys(Array)) // [],Array
console.log(Object.getOwnPropertyNames(Array)) // [ 'length', 'name', 'prototype', 'isArray', 'from', 'of' ],Array
for-in
apply()
function sumPrototype(num1, num2) {
return num1 + num2
}
call()
和bind()
いずれも指定apply()
値呼び出し関数であり、呼び出し関数を設定する際の関数体内call()
の指向this
2つのパラメータを受信する:①運転関数のスコープ(thisを指定)②パラメータ配列(例またはargmentsオブジェクトでも可)function applySum1(num1, num2) {
return sum.apply(this, arguments) // arguments
}
function applySum2(num1, num2) {
return sum.apply(this, [num1, num2]) //
}
console.log(applySum1(10, 10)) // 20
console.log(applySum2(10, 10)) // 20
this
幾つかのパラメータを受信する:①運転関数の作用域(thisを指定する);残りのパラメータは1つずつ入ってくるfunction callSum(num1, num2) {
return sum.call(this, num1, num2) //
}
console.log(callSum(10, 10)) // 20
apply()
和call()
本当に強大なところは、関数運転の役割領域を拡張できること、すなわち制御関数体内apply()
値window.color = 'red' // vscode node , window, window global
let o2 = { color: 'blue' }
function sayColor3() {
console.log(this.color)
}
sayColor3() // 'red',this
sayColor3.call(this) // 'red',this
sayColor3.call(window) // 'red',this , window global
sayColor3.call(o2) // 'blue',this o2
call()
関数のプロトタイプthis
方法利用Function.prototype.apply.call()
バインディング(経由apply
簡略コード)let f1 = function () {
console.log(arguments[0] + this.mark)
}
let o3 = {
mark: 95,
}
f1([15]) // '15undefined',this f1 ,this.mark undefined
f1.apply(o3, [15]) // 110, f1 this o3
Function.prototype.apply.call(f1, o3, [15]) // 110, f1 apply , call
Reflect.apply(f1, o3, [15]) // 110, , ( 、 this 、 )
call()
新しい関数例を作成し、そのReflect.apply()
転送bind()
の対象let o4 = { color: 'blue' }
function sayColor4() {
console.log(this.color)
}
let bindSayColor = sayColor4.bind(o4) // bindSayColor, this o4
sayColor4() // 'red',this
bindSayColor() // 'blue',this o4
10.11関数式sayHi() // 'Hi',
function sayHi() {
console.log('Hi')
}
this
識別子がない).bind()
属性は空の文字列sayHi2() // ReferenceError: Cannot access 'sayHi2' before initialization,
let sayHi2 = function sayHi() {
console.log('Hi')
}
let condition = false
if (condition) {
function sayHi3() {
console.log('true')
}
} else {
function sayHi3() {
console.log('false')
}
}
sayHi3() // ,
let sayHi4
if (condition) {
sayHi4 = function () {
console.log('true')
}
} else {
sayHi4 = function () {
console.log('false')
}
}
sayHi4() // false,
/**
* object key,
* @param {String} key key
* @param {String} sort / :asc/desc, asc
*/
function arraySort(key, sort) {
return function (a, b) {
if (sort === 'asc' || sort === undefined || sort === '') {
// :a[key] > b[key]
if (a[key] > b[key]) return 1
else if (a[key] < b[key]) return -1
else return 0
} else if (sort === 'desc') {
// :a[key] < b[key]
if (a[key] < b[key]) return 1
else if (a[key] > b[key]) return -1
else return 0
}
}
}
var userList = [
{ name: 'Tony', id: 3 },
{ name: 'Tom', id: 2 },
{ name: 'Jack', id: 5 },
]
console.log(userList.sort(arraySort('id'))) // [{ name: 'Tom', id: 2 },{ name: 'Tony', id: 3 },{ name: 'Jack', id: 5 }], id
console.log(userList.sort(arraySort('id', 'desc'))) // [{ name: 'Jack', id: 5 },{ name: 'Tony', id: 3 },{ name: 'Tom', id: 2 }], id
console.log(userList.sort(arraySort('name'))) // [{ name: 'Jack', id: 5 },{ name: 'Tom', id: 2 },{ name: 'Tony', id: 3 }], name
まとめ&質問