美文网首页JavaScript
JavaScript之call、apply、bind

JavaScript之call、apply、bind

作者: h2coder | 来源:发表于2023-07-20 00:25 被阅读0次

前言

在JavaScript中,this指向总是动态的,但也提供了手动改变this指向的方法,那就是call()、applay()和bind(),那么它们之间又有什么区别呢?

Call

语法

fn.call(this, arg1, arg2, arg3...);

示例

// 改变 this 的指向
const obj = {
  name: '八戒',
  say(a, b) {
    console.log(a, b);
    console.log(this);
  }
};
const newObj = {
  name: '悟空'
};
obj.say();// 输出八戒对象本身

// 通过call,改变this指向为 newObj
obj.say.call(newObj, 11, 22);// 输出悟空对象本身

总结

使用call()能改变函数的this,并且马上调用该函数,函数的参数是一个接一个传入

Apply

语法

fn.apply(this, [arg1, arg2, arg3...]);

示例

// 改变 this 的指向
const obj = {
  name: '八戒',
  say(a, b) {
    console.log(a, b);
    console.log(this);
  }
};
const newObj = {
  name: '悟空'
};
// apply的效果和call的效果一致,区别只是传参的方式不同
// apply()的话,参数必须放到数组中,放在第二个参数
// call()的话,参数是放在剩余参数上
obj.say.apply(newObj, [11, 22]);// 输出悟空对象本身

总结

apply()和call()一样,都能改变this指向,也是马上调用该函数,但函数的参数必须放在数组中

Bind

语法

let newFn = fn.bind(this);
newFn(arg1, arg2, arg3...);

示例

// 改变 this 的指向
const obj = {
  name: '八戒',
  say(a, b) {
    console.log(a, b);
    console.log(this);
  }
};
const newObj = {
  name: '悟空'
};
// bind()不会直接调用函数,而是返回一个新函数,但它的this指向已经被修改过了
const fn = obj.say.bind(newObj);
fn(11, 22);

总结

bind()也可以改变函数的this指向,但不会马上调用函数,而是返回一个新函数,函数的参数是在调用返回的新函数时,一个接一个的传入

this的取值

this的取值 不取决于函数的定义,而是取决于怎么调用的(this指向调用者)

  • 全局内调用: fn() 指向window
  • 对象内的方法调用:obj.fn() 指向调用对象
  • 构造函数调用:new Person() 指向实例对象
  • 事件处理函数中调用:指向当前触发事件的DOM元素
  • 特殊调用 比如 call、apply、bind可以改变this指向,fun.call(obj) 指向 obj

应用场景

call的应用场景

  • 判断变量的类型
// Object.prototype.toString.call(目标变量) 最强大,判断得最准确
// 代码太长,还要严谨地判断字符串结果,建议进行封装来使用
Object.prototype.toString.call(1);//[object Number]
Object.prototype.toString.call('hello');//[object String]
Object.prototype.toString.call(true);//[object Boolean]
Object.prototype.toString.call(null);//[object Null]
Object.prototype.toString.call(undefined);//[object Undefined]
Object.prototype.toString.call([]);//[object Array]
Object.prototype.toString.call({});//[object Object]

apply的应用场景

  • 让Math.max()、Math.min()等函数,支持数组
// apply的应用场景,很像展开运算符,能把数组参数拆开成单个参数来调用
const max = Math.max.call(null, [1, 2, 3]);
// ES6展开运算符,更简洁
// const max = Map.max(...[1, 2, 3]);
console.log(`数组的最大值:${max}`);

bind的应用场景

// bind的应用场景,改变定时器或延时器的this指向
const button = document.querySelector('button');
button.addEventListener('click', function (e) {
  const fn = function () {
    console.log(this);
  };
  // 改变延时器回调函数的this
  setTimeout(fn.bind(this), 1000);
});

相关文章

网友评论

    本文标题:JavaScript之call、apply、bind

    本文链接:https://www.haomeiwen.com/subject/laqoudtx.html