this-call|apply|bind

this

普通函数this

  1. 在函数中直接使用 类似于 fun.call(window, 参数)
  2. 函数作为对象的方法被调用(谁调用,指向谁) obj.run.call(obj,参数)

箭头函数this

  1. 箭头函数中的this是在函数定义时绑定的,而不是函数执行时绑定的
  2. 箭头函数中this指向的固定化,并不是因为箭头函数内部有绑定this的机制,而是因为箭头函数没有自己的this,导致内部的this是外层代码块的this,也因此,箭头函数不能用作构造函数

call|apply|bind

改变函数运行时this的指向

function person(age, gender,type) {
    console.log(this);
    return `my name is ${this.fullName},my age is ${age} and my gender is ${gender} ps:${type}`;
}
let obj = {
    fullName: 'obj full name'
}
window.fullName = 'window full name';

//call方法调用
person.call(obj, 20, 'female','call改变指向obj');//指向obj
person.call(null, 57, 'female','call改变指向window');//指向window
//apply方法调用
person.apply(obj, 20, ['female','apply改变指向obj']);//指向obj
person.apply(null, 57, ['female','apply改变指向window']);//指向window
//bind方法
let f1 = person.bind(obj);//指定指向
let f2 = person.bind(obj, 30);//指定指向,传递部分参数
let f3 = person.bind(obj, 30, 'female','bind改变指向obj');指定指向并传参
//bind方法调用
f1(30, 'female','bind改变指向obj');
f2('female','bind改变指向obj');
f3();

call

call(参数1,参数2)

  • 参数1:绑定给this的值,若为null|undefined,则默认指向window
  • 参数2:参数列表
手写call
//通过rest参数,获取函数的实参,代替arguments。将剩余参数作为一个数组进行传递
Function.prototype.myCall = function(context, ...args){
    //未传值或传空对象,指向window对象
    context = context || window;
    //定义临时方法
    context.temp = this;
    //调用临时方法,通过扩展运算符对传入参数数组进行展开
    let res = context.temp(...args);
    //删除临时方法
    delete context.temp;
    //返回结果
    return res;
}
//手写call方法调用
person.myCall(obj, 20, 'female','手写call改变指向obj');//指向obj
person.myCall(null, 57, 'female','手写call改变指向window');//指向window

apply

apply(参数1,参数2)

  • 参数1:绑定给this的值,若为null|undefined,则默认指向window
  • 参数2:参数数组
手写apply
Function.prototype.myApply = function(context, args){
     //未传值或传空对象,指向window对象
    context = context || window;
    //定义临时方法
    context.temp = this;
    //调用临时方法,传入的args为数组,需要使用扩展运算符进行展开
    let res = context.temp(...args);
    //删除临时方法
    delete context.temp;
    //返回结果
    return res;
}
person.myApply(obj, 20, ['female','手写apply改变指向obj']);//指向obj
person.myApply(null, 57, ['female','手写apply改变指向window']);//指向window

bind

bind(参数1,参数2)

  • 参数1:绑定给this的值,若为null|undefined,则默认指向window
  • 参数2:参数列表
  • 返回值:函数
手写bind
Function.prototype.bind = function(context, ...args){
    var self = this;
    return function(...args2){
        self.call(context, ...args, ...args2);
    }
}
let f1 = person.myBind(obj); //指定指向
let f2 = person.myBind(obj, 30); //指定指向,传递部分参数
let f3 = person.myBind(obj, 30, 'female', '手写bind改变指向obj'); //指定指向并传参
//调用
f1(30, 'female', '手写bind改变指向obj');
f2('female', '手写bind改变指向obj');
f3();

应用场景

  • 求数组的最大值最小值

    var arr = [1,2,3,4,5,6];
    var max = Math.max.apply(null, arr);
    var min = Math.min.apply(null, arr);
    
  • 将类数组转化为数组

    var arr = Array.prototype.slice.call(arrayLike);
    
  • 数组追加

    var arr1 = [1,2,3];
    var arr2 = [4,5,6];
    var add = [].push.apply(arr1, arr2);//返回追加后的数组长度,此处为6
    //arr1:[1,2,3,4,5,6]
    //arr2:[4,5,6]
    
    
  • 判断变量类型

    function isArray(obj){
        return Object.prototype.toString.call(obj) == '[object Array]';
    }
    isArray([]);//true
    isArray('dot');//false
    
  • 利用call和apply做继承

    function Person(name, age){
        this.name = name;
        this.age = age;
        this.sayName = function(){
            console.log(this.name);
        }
    }
    function Son(){
        Person.apply(this, arguments);
    }
    var inherit = new Son("Son's name", 24);
    
  • 使用log代理console.log

    function log(){
        console.log.call(console, arguments);
    }
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值