call、apply、bind的区别?如何实现一个bind?

什么情况需要改变this指向

下例,正常情況 say方法输出martin 但是我们把 say 放在setTimeout 方法中,在定时器中是作为回调函数来执行的,因此回到主栈执 行时是在全局执行上下文的环境中执行的,这时候this指向 window,所以输出Lucy 我们实际需要的是,this指向 obj对象,这时候就需要该改变 this指向了

javascript 复制代码
var name = "lucy";
var obj = {
    name: "martin",
    say: function () {
        console.log(this.name);
    }
};

obj.say(); // martin this指向obj

setTimeout(obj.say,0); // lucy this指向window

// 改变this指向
setTimeout(obj.say.bind(obj),0); //martin this指向obj

共同点

  • 都是显式改变this的方法
  • 第一个参数都是this的指向
  • 第一个参数是null或者undefined时,默认指向window(浏览器)

区别

  • call 方法接收两个参数,第一个参数是this的值,第二个参数是传递给函数的参数,以逗号分隔,参数一次性传入。改变this指向后原函数会立即执行,此方法只临时改变this指向一次
  • apply 方法也接收两个参数,第一个参数是this的值(为null或者undefined时,默认指向window(浏览器)),第二个参数一个数组或类数组对象,改变this指向后原函数会立即执行,此方法只临时改变this指向一次
  • bind 方法创建一个新的函数,当这个新函数被调用时,bind的第一个参数将作为它运行时的this,参数可分多次传入。改变this指向不会立即执行,而是返回一个永久改变this指向的函数
scss 复制代码
function fn(...args){ 
    console.log(this,args); 
} 

let obj = { myname:"xxx" } 

// apply 
fn.apply(obj,[1,2]); 

// call 
fn.call(obj, 1,2); 

// bind
const bindFn = fn.bind(obj); 
// bind不会理解执行需要执行一次 
bindFn(1,2) // this指向obj 

fn() // this指向window

实现一个bind

  1. 修改this指向
  2. 动态传递参数
  3. 兼容new关键字
javascript 复制代码
Function.prototype.myBind = function (context) {
    // 判断调用对象是否为函数
    if (typeof this !== "function") {
        throw new TypeError("Error");
    }

    // 获取参数
    const args = [...arguments].slice(1),
    fn = this;

    return function Fn() {
        // 根据调用方式,传入不同绑定值
        return fn.apply(this instanceof Fn ? new fn(...arguments) : context, args.concat(...arguments));
    }
}
相关推荐
bug总结10 小时前
uniapp vue3全局方法注册使用
前端·javascript·uni-app
华无丽言11 小时前
如何在宜搭中实现获取子表中的字段值赋值到父表中?
前端·javascript·低代码
2601_9623824312 小时前
剑指大前端全栈工程师(全2册)主要情节
javascript·实战案例·全栈工程师·剑指大前端·html5+css3
泯泷12 小时前
手搓JSVM第 12 篇:完整最小 JSVM 实现与源码设计复盘
前端·javascript·前端框架
默_笙13 小时前
🍔 给 AI 发一张结构化表格(下):从"自由发挥"到"按格填空"的输出驯服指南
前端·javascript
泯泷13 小时前
手搓JSVM第 11 篇:打包、模块与 CLI:把 VM 产物变成可运行文件
前端·javascript·前端框架
泯泷13 小时前
手搓JSVM第 10 篇:对象、数组与属性访问
前端·javascript·前端框架
泯泷13 小时前
手搓JSVM第 9 篇:闭包:函数如何记住外部变量
前端·javascript·前端框架
晴天1613 小时前
前端 SSR、BFF 原理介绍
前端·javascript·网络·html
梦想平凡14 小时前
百游棋牌源代码开发搭建教程(一):全端工程结构、开发环境配置与首次启动验证
前端·javascript·源代码管理