JS中的bind 、call 、apply




一 、bind

特色:數組

1.返回原函數的拷貝,咱們稱這個拷貝的函數爲綁定函數

2.將函數中的this固定爲調用bind方法時的第一個參數,因此稱之爲綁定函數。注意是名詞而非動詞。

3.之後不管由哪一個對象調用綁定函數,綁定函數中的this依然由當時調用的bind方法的一個參數決定,不會改變。

4.若是綁定函數做爲構造函數來使用,那麼已經固定了的this將不會生效,此時構造函數中的this依然爲實例對象。

5.調用bind方法時的第二個參數作爲綁定函數的第一個參數,稱之爲預設參數,調用綁定函數時的第一個參數則排在預設參數後面

6.不管使用任何對象調用bind方法時若是不傳參數、第一個參數爲undefined、第一個參數爲null時,綁定函數中的this指向window對象



做用:app

1.拷貝一個目標函數

2.改變綁定函數運行時的this指針



1-1 證實是原函數的拷貝 (須要知道:函數也是對象,而且是引用類型,比較的是內存地址)函數

function fn(){}

var bindFn = fn.bind();           //ƒ fn(){ return this }  供之後調用

fn === bindFn                       //false





2-1 將函數中的this固定爲調用bind方法時的第一個參數this

function fn(){ return this }

var bindFn = fn.bind({name:"綁定函數"})   //ƒ fn(){ return this }





3-1 之後不管由哪一個對象調用綁定函數,綁定函數中的this依然是{name:"綁定函數"}指針

function fn(){  console.log(this)  }

var bindFn = fn.bind({name:"綁定函數"})

bindFn()                    //等同於window對象調用 , this依然指向{name:"綁定函數"}

var obj = {name:"obj"};
obj.fn = bindFn;    
obj.fn()                    //由普通對象調用 ,this依然指向{name:"綁定函數"}

var arr = [bindFn];
arr[0]()                    //由數組調用 , this依然指向{name:"綁定函數"}

setTimeout(bindFn , 200);   //做爲回調函數  , this依然指向{name:"綁定函數"}
clearTimeout(1);





4-1 若是綁定函數做爲構造函數,已經捆綁的this會被忽略掉,this依然指向實例對象code

function Person(name){ 
    this.name = name;
 }

var bindPerson = Person.bind({name:"綁定函數"})

new bindPerson("張三")          // Person {name: "張三"}





5-1 預設參數對象

function fn(a,b,c,d){
    console.log(a,b,c,d)          // 1 ,2 ,3 ,4
}

var bindFn = fn.bind({name:"綁定函數"} , 1 ,2);        // 拷貝原函數時的第2個參數開始日後稱爲預設參數

bindFn(3,4);                            //調用綁定函數時的第一參數則排在預設參數的後面





6-1 當沒有參數、第一個參數爲undefined、第一個參數爲null時繼承

var obj = {
    fnOne:function(){ return this }.bind(),
    fnTwo:function(){ return this }.bind( undefined ),
    fnThree:function(){ return this }.bind( null )
}
//注意:這三種狀況是使this指向window對象,而不是不去改變this指向,因此這裏的this仍是不會指向obj
obj.fnOne()   // window
obj.fnTwo()    //window
obj.fnThree()  //window






2、call

特色:內存

1.返回值取決於目標函數的返回值

2.用call的第一個參數對象來代替調用目標函數的對象,以此來改變目標函數體內的this指向

3.調用call方法時的第二個參數作爲目標函數的第一個參數,將第二個做爲第三個以此類推



做用:回調函數

1.用於繼承,例如子構造函數繼承父構造函數

2.改變綁定函數運行時的this指針。



1-1 返回值取決於目標函數的返回值

function fn(){ return {name:"call"} }

fn.call()      // {name: "call"}





2-1 改變目標函數體內的this指向 , 至關於使用第一個參數對象調用

function fn(){ return this }

fn.call( { name : "call" } )         // {name: "call"}





3-1 參數位置

function fn(a, b, c){ return arguments }

fn.call( { name : "call" } , 1 , 2 , 3 )          //Arguments [1, 2, 3]





1-2 用於繼承

function parent(name, age) {
  this.name = name;
  this.age= age;
}

function child(name, age) {
  parent.call(this, name, age);
  this.class = '三年級二班';
}

var xiaoming = new child("小明" , 18)






3、apply

特色:

1.與call方法同樣惟一不一樣的地方就是apply的第二個參數是一個數組,數組的第一個元素對應目標函數的第一個參數,以此類推



做用:

1.與call方法同樣



1-1 參數

function fn(a, b, c){ return a+b+c }

fn.apply({name:"apply"} ,[1,2,3])          //6






總結

相同點

1. 3個方法都是改變綁定函數運行時的上下文

不一樣點

1.bind方法的返回值是原函數的拷貝,供之後調用 。參數既能夠在拷貝時預設又可在調用時添加

2.call與apply同樣,返回值取決於目標函數的返回值 , 則是當即調用

3.call與apply惟一的區別是call從第二個參數開始是若干個參數,而apply第二個參數是一個數組

相關文章
相關標籤/搜索