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]

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