乐趣区

关于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()
退出移动版