guoshuai93 / blog

19 stars 2 forks source link

javaScript 中 call、apply、bind的用法详解 #21

Open guoshuai93 opened 6 years ago

guoshuai93 commented 6 years ago

ECMAScript 规范给所有函数都定义了 callapply 两个方法,他们可应用的地方也很多,callapply作用很相似,唯一的不同点就在于 传参的形式 不一样。

什么时候用它们俩其中哪一个合适? 如果你的参数本来就存在一个数组中,那自然就用 apply,如果参数比较散乱相互之间没什么关联,就用 call。

不同点

先说语法:
applyfunc.apply(thisArg[, argsArray])
callfunc.apply(thisArg, arg1, arg2, ...)

apply接受可包含多个参数的 数组 (或 array-like 对象),而call接受的是可包含若干个参数的 参数列表

共同点

apply ( 同call )调用一个函数,第一个参数指定 this 值。

thisArg:

apply 和 call 的用法

1.改变 this 指向

var obj = {
  name: 'Curry'
}

function func() {
  console.log(this.name);
}

func.call(obj);       // Curry

或去调用别的对象的方法

var Person1  = function () {
  this.name = 'Curry';
}
var Person2 = function () {
  this.getname = function () {
    console.log(this.name);
  }
  Person1.call(this);
}
var person = new Person2();
person.getname();       // Curry

2. 直接执行

function func() {
  console.log('Curry');
}
func.call();  // Curry

callapply 因为都会立即执行,所以也可以不传递参数,直接调用,只是一般很少人这样用,直接 func() 多方便。

callbind 的区别

bind 是 ES5 新增加的一个方法,bind() 方法用于创建一个新的函数(叫做绑定函数),并在调用时,指定 this 值,bind() 也接受预设的参数提供给原函数。所以它不会向 call 一样直接执行。

bind 用法

  1. 创建绑定函数
this.x = 9; 
var module = {
  x: 81,
  getX: function() { return this.x; }
};

module.getX(); // 返回 81

var retrieveX = module.getX;
retrieveX(); // 返回 9, 在这种情况下,"this"指向全局作用域

// 创建一个新函数,将"this"绑定到module对象
// 新手可能会被全局的x变量和module里的属性x所迷惑
var boundGetX = retrieveX.bind(module);
boundGetX(); // 返回 81
  1. 偏函数(或参数的影响 )

bind() 方法可以使一个函数一开始就拥有一些预设参数,它们的位置从参数的第二项开始,之后这些预设参数会插入到目标函数参数列表的前面,目标函数原有的参数会放在后面:

function func(a, b, c) {
    console.log(a, b, c);
}
var func1 = func.bind(null,'linxin');

func('A', 'B', 'C');            // A B C
func1('A', 'B', 'C');           // linxin A B
func1('B', 'C');                // linxin B C
func.call(null, 'linxin');      // linxin undefined undefined

call 把从第二项开始的参数当做实参传递给目标函数,bind 方法把预设参数传递给目标函数,并且预设参数在目标新参数列表的开始位置。

参考