js——call、bindとapply、真配列と擬似配列は互いに転換して関数のカリー化となります.
29754 ワード
applyとcall方法の役割:
この2つの方法の用途は特定のスコープ内で関数を呼び出すことであり、実際には関数内のthisオブジェクトの値を設定することに等しい.
書式:例 例2 例3
bind関数は新しいバインディング関数(bound function、BF)を作成します.バインディング関数は、元の関数オブジェクトを包装したexotic function oject(怪しい関数オブジェクト、ECMAScript 2015の用語)です.バインディング関数の呼び出しは、通常、パッケージ関数の実行につながる.
bindメソッドは、新しい関数を作成し、呼び出し時に、thisキーワードを提供する値に設定します.そして、新しい関数を呼び出したとき、与えられたパラメータリストを元の関数のパラメータシーケンスの最初の項目とします.
シンタックス thisArgがバインディング関数を呼び出したとき、ターゲット関数にthisパラメータとして伝達される値.new演算子を使用してバインディング関数を作成すると、値を無視します.ビットを使用してsetTimeoutで関数を作成すると(コールバックとして提供される)、thisArg伝達の元の任意の値はobjectに変換される.Bind関数のパラメータリストが空の場合、スコープを実行するthisは、新しい関数のthisArgと見なされます. arg 1,arg 2,…ターゲット関数が呼び出されると、あらかじめバインディング関数のパラメータリストに追加されます.
applyとcallの違いは、伝え方が違っています. appyは、2つのパラメータだけを受信し、対象となるオブジェクトと配列は、この関数の参照 である. callは、複数のパラメータを受信し、最初は目標オブジェクトであり、後の値はすべて関数の参照 である.
ビッドと前の二つの違い: bind方法は、すぐに実行されずにコンテキストが変更された関数を実行することに戻り、前の2つは直接に関数を実行することになる.彼のパラメータの形式はコールと同じです.
真配列:
この2つの方法の用途は特定のスコープ内で関数を呼び出すことであり、実際には関数内のthisオブジェクトの値を設定することに等しい.
書式:
call( , 1, 2,...)
apply( ,[ ]) : arguments
function sum(num1, num2){
return num1 + num2;
}
function callSum1(num1, num2){
// arguments
return sum.apply(this, arguments);
}
function callSum2(num1, num2){
//
return sum.apply(this, [num1, num2]);
}
//20
alert(callSum1(10,10));
//40
alert(callSum2(20,20));
function fun1(...args) {
console.log(1)
console.log(...args)
}
function fun2() {
console.log(2)
fun1.call(this, 2, 3)
fun1.apply(this, [4, 5])
}
fun2()
/*
2
1
2 3
1
4 5
*/
// ,
window.color = 'red'
let obj = { color: "blue" }
function sayColor() {
console.log(this.color)
}
sayColor() // red
sayColor.call(this) // red
sayColor.call(window) // red
sayColor.call(obj) // blue
ビッドbind関数は新しいバインディング関数(bound function、BF)を作成します.バインディング関数は、元の関数オブジェクトを包装したexotic function oject(怪しい関数オブジェクト、ECMAScript 2015の用語)です.バインディング関数の呼び出しは、通常、パッケージ関数の実行につながる.
bindメソッドは、新しい関数を作成し、呼び出し時に、thisキーワードを提供する値に設定します.そして、新しい関数を呼び出したとき、与えられたパラメータリストを元の関数のパラメータシーケンスの最初の項目とします.
シンタックス
let writen = document.write
writen('hello')// error
writen.bind(document)('hello')// right
バインディング関数を作成var module = {
x: 42,
getX: function() {
return this.x;
}
}
var unboundGetX = module.getX;
console.log(unboundGetX()); // The function gets invoked at the global scope
// expected output: undefined
var boundGetX = unboundGetX.bind(module);
console.log(boundGetX());
// expected output: 42
包装Aray.prototype.slice方法function fun() {
console.log(Array.prototype.slice.call(arguments)) // (3) [1, 2, 3]
let slice = arg => Array.prototype.slice.apply(arg)
console.log(slice(arguments)) // (3) [1, 2, 3]
// bind , Array.prototype.slice
let unboundSlice = Array.prototype.slice;
let slice1 = Function.prototype.apply.bind(unboundSlice);
console.log(slice1(arguments)) // (3) [1, 2, 3]
}
fun(1, 2, 3)
もっと多くの例を参照してください.// bind
Function.prototype.myBind = function (oThis, ...args) {
if (typeof oThis !== 'object') return
let [_self, func] = [this, function () {}]
let fBind = function () {
return _self.apply(this instanceof _self ? this : oThis, [...args, ...arguments])
}
if(_self.prototype){ //
func.prototype = _self.prototype
fBind.prototype = new func()
}
return fBind
}
function add (...args) {
console.log(this.join(' '), args.reduce((a, b) => a + b))
}
let obj = ['hello', 'world']
let fun = add.myBind(obj, 1, 2, 3, 4)
fun(5) // hello 15
bind、appyとcallの3つの違いapplyとcallの違いは、伝え方が違っています.
ビッドと前の二つの違い:
function fun (...args) {
console.log(args)
}
let obj = {}
fun.call(obj, 1, 2, 3)// (3) [1, 2, 3]
fun.apply(obj, [4, 5, 6])// (3) [4, 5, 6]
let save = fun.bind(obj, 7, 8, 9)// fun
save()// (3) [7, 8, 9]
真の配列と疑似配列は互いに変換されます.真配列:
function.bind(thisArg[, arg1[, arg2[, ...]]])
疑似配列:var arr=[1,2,3,4];
(注:最後のレングスは欠かせない)/* */
var ar=[1,3,4,5,6];
var ob={};
/*
1、 [].push push
2、 apply(ob) push this
3、 , ob
*/
[].push.apply(ob,ar);//
console.log(ob);/*{0: 1, 1: 3, 2: 4, 3: 5, 4: 6, length: 5}*/
/* */
//
var res=document.querySelectorAll('div');
//
var obj={0:'lng',1:'af',length:2};
//
var arr=[].slice.call(obj);//
var arr1=[].slice.call(res);
/*
var arr=[];
[].push.apply(arr,res);// IE8
*/
console.log(arr1);//(3) [div, div, div]
console.log(arr);//(2) ["lng", "af"]
var arr3=[1,2,3,4];
console.log(arr3);//(4) [1, 2, 3, 4]
関数コリック化function curry(fn) {
let args = Array.prototype.slice.call(arguments, 1)
return function () {
let innerArgs = Array.prototype.slice.call(arguments)
let finalArgs = args.concat(innerArgs)
return fn.apply(null, finalArgs)
}
}
function add(num1, num2) {
return num1 + num2
}
console.log(curry(add, 5)(4)); // 9