JS中的bind 、call 、apply




# 一 、bind 特點: ### 1.返回原函數的拷貝,我們稱這個拷貝的函數為綁定函數 ### 2.將函數中的this固定為調用bind方法時的第一個參數,所以稱之為綁定函數。注意是名詞而非動詞。 ### 3.以后無論由哪個對象調用綁定函數,綁定函數中的this依然由當時調用的bind方法的一個參數決定,不會改變。 ### 4.如果綁定函數作為構造函數來使用,那么已經固定了的this將不會生效,此時構造函數中的this依然為實例對象。 ### 5.調用bind方法時的第二個參數做為綁定函數的第一個參數,稱之為預設參數,調用綁定函數時的第一個參數則排在預設參數后面 ### 6.無論使用任何對象調用bind方法時如果不傳參數、第一個參數為undefined、第一個參數為null時,綁定函數中的this指向window對象
作用: ### 1.拷貝一個目標函數 ### 2.改變綁定函數運行時的this指針
1-1 證明是原函數的拷貝 (需要知道:函數也是對象,並且是引用類型,比較的是內存地址) ``` function fn(){}

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

fn === bindFn //false

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

function fn(){ return this }

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

<br>
<br>
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];
arr0 //由數組調用 , this依然指向{name:"綁定函數"}

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

<br>
<br>
4-1    如果綁定函數作為構造函數,已經捆綁的this會被忽略掉,this依然指向實例對象

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

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

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

<br>
<br>
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); //調用綁定函數時的第一參數則排在預設參數的后面

<br>
<br>
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

<br>
<br>
<br>
#  二、call           
特點:
### 1.返回值取決於目標函數的返回值
### 2.用call的第一個參數對象來代替調用目標函數的對象,以此來改變目標函數體內的this指向
### 3.調用call方法時的第二個參數做為目標函數的第一個參數,將第二個作為第三個以此類推
<br>
作用:
### 1.用於繼承,例如子構造函數繼承父構造函數
### 2.改變綁定函數運行時的this指針。
<br>
1-1    返回值取決於目標函數的返回值

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

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

<br>
<br>
2-1    改變目標函數體內的this指向 , 相當於使用第一個參數對象調用

function fn(){ return this }

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

<br>
<br>
3-1    參數位置

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

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

<br>
<br>
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)

<br>
<br>
<br>
#  三、apply
特點:
### 1.與call方法一樣唯一不同的地方就是apply的第二個參數是一個數組,數組的第一個元素對應目標函數的第一個參數,以此類推
<br>
作用:
### 1.與call方法一樣
<br>
1-1    參數

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

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

<br>
<br>
<br>
## 總結
### 相同點
####1. 3個方法都是改變綁定函數運行時的上下文
### 不同點
####1.bind方法的返回值是原函數的拷貝,供以后調用 。參數既可以在拷貝時預設又可在調用時添加
####2.call與apply一樣,返回值取決於目標函數的返回值 , 則是立即調用
####3.call與apply唯一的區別是call從第二個參數開始是若干個參數,而apply第二個參數是一個數組


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM