【JavaScript】-call()、apply()、bind()の違いと使い方

メソッド借用パターン

コンテキストモードとも呼ばれ、適用と呼び出し、バインドに分けられます

3つの類似点:

1は、関数のこのオブジェクトのポイントを変更するために使用されます。

2.最初のパラメーターは、これが指すオブジェクトです。

3.後続のパラメーターを使用して、パラメーターを渡すことができます。

1.call:

callメソッドは関数を呼び出すことができ、この関数へのthisポインターを指定できます

メソッドの呼び出し後、パラメータリストが渡され、パラメータは任意のタイプにすることができます。パラメータが渡されない場合、または最初のパラメータがまたはであるnull場合nudefinedthisそれらはすべてwindow

これらのメソッドは、プロトタイプのプロトタイプにあります。

const RichWumon = {
    name: "富婆",
    say: function () {
        console.log(this.name, " 我要重金求子");
    }
}

const obj = {
    name: "屌丝"
}

RichWumon.say();			// 富婆
RichWumon.say.call(obj);	// 屌丝

// fn.call(你想谁作为this变量,参数列表)
// call可以改变方法中this的指向,会以你调用call方法时传递的变量做为方法中的this

通話の詳細:

非厳密モード

パラメータが渡されない場合、または最初のパラメータがnullまたは未定義の場合、これはすべてウィンドウを指します

   let fn = function(a,b){
        console.log(this,a,b);
    }
    let obj = {name:"obj"};
    fn.call(obj,1,2);    // this:obj    a:1         b:2
    fn.call(1,2);        // this:1      a:2         b:undefined
    fn.call();           // this:window a:undefined b:undefined
    fn.call(null);       // this=window a=undefined b=undefined
    fn.call(undefined);  // this=window a=undefined b=undefined

ストリクトモード


nullや未定義を含め、これが指す最初のパラメータは誰ですか。これが渡されない場合、パラメータは未定義です。

    "use strict"
    let fn = function(a,b){
        console.log(this,a,b);
    }
    let obj = {name:"obj"};
    fn.call(obj,1,2);   // this:obj        a:1          b:2
    fn.call(1,2);       // this:1          a:2          b=undefined
    fn.call();          // this:undefined  a:undefined  b:undefined
    fn.call(null);      // this:null       a:undefined  b:undefined
    fn.call(undefined); // this:undefined  a:undefined  b:undefined

アプリケーションを呼び出す:

// 将伪数组转成数组
let divs = document.querySelectorAll('div'); // 伪数组
// let divs = document.body.children;
console.log(divs);

function change(nodelist) {
    console.log(Object.prototype.toString.call(nodelist));
    return Array.prototype.slice.call(nodelist);

}

// 定义一个伪数组:看起来像数组,但是并没有数组的api,本质上是一个对象
    let arr = {
      0: 1,
      1: 10,
      2: 200,
      length: 3
    }
// 第一个参数是this,后面的是参数列表
    let data = [50, 60, 70, 80, 90];
    [].push.call(arr, ...data)
    console.log(arr)	
/* 输出的是 
Object
0: 1
1: 10
2: 200
3: 50
4: 60
5: 70
6: 80
7: 90
length: 8		// arr[arr.length++] = 50
*/

2.適用:

つまり、このメソッドは複数のパラメーターを持つ配列をapply()受け入れますこのメソッドは、いくつかのパラメーターのリストを受け入れますcall()

applyを使用して、今すぐ通話のコードを変更できます

apply()には2つのパラメーターしかありません。最初のパラメーターはオブジェクトで、2番目のパラメーターは配列です。

const RichWumon = {
    name: "富婆",
    say: function () {
        console.log(this.name, " 我要重金求子");
    }
}

const obj = {
    name: "屌丝"
}

RichWumon.say();			// 富婆
RichWumon.say.apply(obj);	// 屌丝

適用:基本的に呼び出しと同じですが、唯一の違いはパラメータの受け渡し方法です

applyは、fnに渡す必要のあるパラメーターを配列(またはクラス配列)に入れて渡します。配列を書き込みますが、fnを1つずつ渡すのと同じです。

applyApply:

// 简化log方法
function log() {
    // 不需要改变this
    console.log.apply(console, arguments);
}
​
​
var obj = {};
function foo(a, b, c) {
      console.log(a);
}
foo.apply(obj, [1, 2, 3])   //打印结果: 2;
//第一个参数是函数的对象,第二个参数是由函数的参数组成的数组
​
// 求数组中的最大值
var arr = [1, 66, 3, 99, 50];
var max = Math.max.apply(arr, arr);//第一个arr表示让arr借用max这个方法,第二个arr表示传给max的数据
console.log(max);       // 99
//apply()所执行的操作:1.执行Math.max(1,2,3,5,4) 2.把内部的this改成arr

3.bindメソッド:

bind()thisメソッドは、新しい関数のポインターにバインドできる新しい関数を作成します

bind()メソッドと最初の2つのメソッドの違いは、bind( メソッドは、実行コンテキストが変更された関数をすぐには実行せずに返すのに対し、最初の2つは関数を直接実行することです。そのパラメータはcall()と同じです

var name = '张三';
function Fn(){
    this.age = 1;
    
    console.log(this.name + this.age);
}

Fn();			// 张三 1

// 返回值:新的函数
// 参数:新函数的this指向,当绑定了新函数的this指向后,无论使用何种调用模式,this都不会改变。
let obj = {
    name:'小强',
}
const newFn = Fn.bind(obj);
newFn();		// 小强 1

 応用:

function f() {
  console.log("看我怎么被调用");
  console.log(this) //指向this
}
var obj = {name:'jack'};
f.call(obj) //直接调用函数
// f.bind(obj);    bind()不能调用函数
var g = f.bind(obj); 	// bind()改过this后,不执行函数,会返回一个绑定新this的函数
g();  //此时才调用函数

おすすめ

転載: blog.csdn.net/m0_55960697/article/details/124026341