关于javascript:callapply和bind的用法和区别

call办法

call()办法应用一个指定的 this 值(this指向执行环境上下文)和独自给出的一个或多个参数来调用一个函数

语法

fun.call(thisArg[, arg1[, arg2[, …]]])

  • fun:调用的函数。
  • thisArg:必选的。函数运行时指定的this值(this指向执行环境上下文)。
  • arg1, arg2, …:可选的。指定的参数列表。

留神: 指定的this值并不一定是该函数执行时真正的this值,如果这个函数处于非严格模式下,则指定为null和undefined的this值会主动指向全局对象(浏览器中就是window对象),值为根本类型值(数字,字符串,布尔值)的this会指向该原始值的主动包装对象。

用处

应用call办法调用函数并且指定this,借用本人没有的函数

function speakName() {
    console.log('My name is ' + this.name);
}

var person1 = {
    name: 'chong',
}

speakName(); // speakName为全局函数,this指向全局对象window,因为全局作用域中不存在变量name,所以输入:My name is
speakName.call(person1); // 输入:My name is chong

应用call办法调用父构造函数,实现继承

function Product(name, price) {
    this.name = name;
    this.price = price;

    if (price < 0) {
        throw RangeError(
            'Cannot create product ' + this.name + ' with a negative price'
        );
    }
}

function Food(name, price) {
    Product.call(this, name, price);
    this.category = 'food';
}

// 下面Food构造函数等同于以下代码
function Food(name, price) {
    this.name = name;
    this.price = price;

    if (price < 0) {
        throw RangeError(
            'Cannot create product ' + this.name + ' with a negative price'
        );
    }


    this.category = 'food';
}

apply办法

apply() 办法用一个指定的 this 值,以及以一个数组(或类数组对象)的模式提供的参数调用一个函数

语法

func.apply(thisArg, [argsArray])

  • fun:调用的函数。
  • thisArg:必选的。函数运行时指定的this值。
  • argsArray 可选的。一个数组或者类数组对象,其中的数组元素将作为独自的参数传给 func 函数。

apply办法用处和call办法雷同,不再赘述

bind办法

bind() 办法用来创立一个新的函数。bind() 的第一个参数为这个新函数的 this ,其余参数将作为新函数的参数。

语法

func.bind(thisArg[, arg1[, arg2[, …]]])

  • fun:调用的函数。
  • thisArg:必选的。调用新函数时作为新函数的 this 值。如果应用new运算符结构绑定函数,则疏忽该值。当应用 bind 在 setTimeout 中创立一个函数(作为回调提供)时,作为 thisArg 传递的任何原始值都将转换为 object。如果 bind 函数的参数列表为空,或者thisArg是null或undefined,执行作用域的 this 将被视为新函数的 thisArg。
  • arg1, arg2, …: 可选的。给新函数预设的初始参数列表。
    返回值:返回一个原函数的拷贝,并领有指定的 this 值和初始参数。

用处

  1. 创立绑定函数
  2. 偏函数:使一个函数领有预设的初始参数

例如:

var x = 9;
var module = {
    x: 81,
    getX: function() {
        return this.x;
    },
    addX: function(n) {
        return this.x + n;
    }
};

module.getX(); // 81
module.addX(9); // 90

var _getX = module.getX;
var _addX = module.addX;
_getX(); // 返回 9, 因为函数是在全局作用域中调用的
_addX(9); // 返回 18

// 创立一个新函数boundGetX,并把this绑定为module对象;
var boundGetX = _getX.bind(module);
boundGetX(); // 81

// 1. 创立绑定函数 boundAddX,把this绑定为module对象,并预设参数为 10;
var boundAddX = _addX.bind(module, 10);
// 调用新函数时不必再传参数(传了也没用)
boundAddX(); // 91

// 2. 创立一个新函数boundAddX,把this绑定为module对象,不预设参数;
var boundAddX = _addX.bind(module);
// 调用新函数时须要传参数
boundAddX(9); // 90
  1. 配合 setTimeout

在默认状况下,应用 window.setTimeout() 时,this 关键字会指向 window (或 global)对象。当类的办法中须要 this 指向类的实例时,你可能须要显式地把 this 绑定到回调函数,就不会失落该实例的援用。

function LateBloomer() {
    // 花瓣数
    this.petalCount = Math.ceil(Math.random() * 12) + 1;
}

// 在调用bloom 1 秒钟后,调用declare
LateBloomer.prototype.bloom = function() {
    window.setTimeout(this.declare, 1000);
};

LateBloomer.prototype.declare = function() {
  console.log('I am a beautiful flower with ' +
    this.petalCount + ' petals!');
};

var flower = new LateBloomer();
flower.bloom();  // 一秒钟后, 调用 'declare' 办法

总结

call和apply比拟

  • 相同点:它们都能够用一个指定的this值调用一个函数,并且能够给函数传递一个或者多个参数。简略来说,它们的用处就是一个对象调/借用本身没有的函数。如果这个函数是构造函数,就能够实现继承
  • 不同点: 只在于传递参数的模式不同。call办法传递参数是通过参数列表,apply办法传递参数是通过数组/类数组。

call、apply和bind比拟

  • 相同点:它们都能够扭转一个函数执行时的this,并且能够给函数传递一个或者多个参数。
  • 不同点: bind办法返回一个新的函数,须要调用才会执行。而call和apply是立刻执行。

参考

  • Function.prototype.call()
  • Function.prototype.apply()
  • Function.prototype.bind()

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理