call,apply,bind

函數的三種角色

  1. length 形參的個數
  2. name:函數名
  3. prototype:類的原型,在原型上定義方法都是當前類實例的公有方法
  4. _proto:把函數當成普通對象,指向Function類的原型
function Fn(){
    var num = 500;
    this.x = 100;
}
Fn.prototype.getX = function(){
    console.log(this.x);
}
Fn.aaa = 1000;
var f = new Fn();
f.num;
f.aaa;
var res = Fn();
  • 普通函數,Fn就是一個,執行時候會形成私有作用域,然後進行形參賦值,預解析,代碼執行,執行完成之後內存銷燬;
  • 類,有自己的實例,f就是一個Fn的作爲類產生的實例,有prototype屬性作爲自己的原型,
  • 普通對象,Fn和var obj = {}中的obj一樣,都是一個普通對象,它作爲對象都有一些自己的私有屬性,可以通過_proto_找到Function.prototype

call

var ary = [12,23,34];
ary.slice();

ary實例通過原型鏈查找機制找到Array.prototype上的slice方法。

var obj = {name:'ice'};
function fn(){
    console.log(this); //this->window
    console.log(this.name);
}
obj.fn() //TypeError;
fn.call(obj);

call方法作用:通過原型鏈Function原型找到call,在執行call,讓fn中this作爲第一個參數obj,然後再執行。
模擬call方法

function sum(){
    console.log(this);
}
function fn(){
    console.log(this);
}
var obj = {name:'iceman'};
Function.prototype.myCall = function (context) {
    // myCall方法中的this就是當前我要操作和改變其this關鍵字的那個函數名

    // 1、讓fn中的this關鍵字變爲context的值->obj
    // 讓this這個函數中的"this關鍵字"變爲context
    // eval(this.toString().replace("this","obj"));

    // 2、讓fn方法在執行
    // this();
};
fn.myCall(obj);// myCall方法中原來的this是fn
sum.myCall(obj);// myCall方法中原來的this是sum
function fn1() {
    console.log(1);
}
function fn2() {
    console.log(2);
}
fn1.call(fn2); // 1
fn1.call.call(fn2);; // 2

fn1.call(fn2):fn1通過原型鏈查找機制找到原型上的call方法,此時call方法中的this就是操作fn1,在call執行過程中,讓fn1中的this變爲fn2,在執行f1;

fn1.call(fn2):fn1通過原型鏈查找機制找到原型上的call方法,然後第二次找到call再執行方法,this爲fn.call,this變爲fn2,然後再讓fn1.call執行.

call,apply,bind 區別

作用都是改變上下文
call的第一個參數將會是function改變上下文後指向的對象,如果不傳,將會默認是全局對象window,第二個參數開始可以接收任意個參數,這些參數將會作爲function的參數傳入function,調用call的方法會立即執行
不同點:

function func (a,b,c) {}
func.call(obj, 1,2,3) // function接收到的參數實際上是 1,2,3 
func.call(obj, [1,2,3]) // function接收到的參數實際上是[1,2,3],undefined,undefined
function fn() {
    console.log(this);
}
fn.call(); // 普通模式下this是window,在嚴格模式下this是undefined
fn.call(null); // 普通模式下this是window,在嚴格模式下this是null
fn.call(undefined); // 普通模式下this是window,在嚴格模式下this是undefined

call和apply主要區別就在於apply是傳遞數組,而call一個一個傳遞。
bind有所不同,bind是事先把fn的this改成我們想要的結果。bind對應參數值不會馬上執行,用到的時候執行(在ie6-8不執行);
this值綁定到bind函數上,爲改變函數內部this指向,創建一個新函數爲綁定函數
在react中經常使用,改變方法的this

Function.prototype.bind(thisArg [, arg1 [, arg2, …]])
onPress={this.timePlus.bind(this)}
在react中還可以用箭頭函數指向
onClick={ ()=>{ this.handleClick() } }

參考[:https://www.jianshu.com/p/00dc4ad9b83f]

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章