bind()とcall/apply()方法の違いを深く理解する
7284 ワード
call
とapply
の機能は同じで、異なるのは、参照の仕方が異なることである.fn.call(obj, arg1, arg2, ...),
は、指定されたthis値と、それぞれ提供されるパラメータ(パラメータのリスト)とを有する関数を呼び出します.fn.apply(obj, [argsArray])
は、1つの指定されたthis値と、1つの配列(またはクラスの配列オブジェクト)として提供されるパラメータとを有する関数を呼び出します.call
コア:null
でなければ、デフォルトはwindow / global
Function.prototype.call = function (context) {
/** null undefined, this window/global */
/** null undefined, */
if (!context) {
//context null undefined
context = typeof window === 'undefined' ? global : window;
}
context.fn = this; //this (Function )
let rest = [...arguments].slice(1);// this , slice
let result = context.fn(...rest); // , this context.
delete context.fn;
return result;
}
//
var foo = {
name: 'Selina'
}
var name = 'Chirs';
function bar(job, age) {
console.log(this.name);
console.log(job, age);
}
bar.call(foo, 'programmer', 20);
// Selina programmer 20
bar.call(null, 'teacher', 25);
// : Chirs teacher 25; node : undefined teacher 25
apply:
apply
の実装およびcall
は類似しているが、apply
の第2のパラメータは配列またはクラス配列であることに注意が必要である.Function.prototype.apply = function (context, rest) {
if (!context) {
//context null undefined ,
context = typeof window === 'undefined' ? global : window;
}
context.fn = this;
let result = context.fn(...rest);
delete context.fn;
return result;
}
var foo = {
name: 'Selina'
}
var name = 'Chirs';
function bar(job, age) {
console.log(this.name);
console.log(job, age);
}
bar.apply(foo, ['programmer', 20]);
// Selina programmer 20
bar.apply(null, ['teacher', 25]);
// : Chirs programmer 20; node : undefined teacher 25
bind:
bind
とcall/apply
は重要な違いがあります.一つの関数がcall/apply
によって呼び出されると、直接に呼び出されますが、bind
は新しい関数を作成します.この新しい関数が呼び出されると、bind()
の最初のパラメータはその動作時のthis
として使用され、その後のシーケンスパラメータは、そのパラメータとして転送された実際の参照の前に渡される.Function.prototype.bind = function(context) {
if(typeof this !== "function"){
throw new TypeError("not a function");
}
let self = this;
let args = [...arguments].slice(1);
function Fn() {};
Fn.prototype = this.prototype;
let bound = function() {
let res = [...args, ...arguments]; //bind
context = this instanceof Fn ? this : context || this;
return self.apply(context, res);
}
//
bound.prototype = new Fn();
return bound;
}
var name = 'Jack';
function person(age, job, gender){
console.log(this.name , age, job, gender);
}
var Yve = {name : 'Yvette'};
let result = person.bind(Yve, 22, 'enginner')('female');
bind()とcall/apply()方法の違いを深く理解する