#浅析 JavaScript ES6 call(). apply(), bind()
call()
, apply()
, bind()
call()
和 apply()
语法
call()
和apply()
方法使用一个指定的 this
值和单独给出的一个或多个参数来调用一个函数。
注意: 这两个方法类似,只有一个区别,就是
call()
方法接受的是一个参数列表,而apply()
方法接受的是一个包含多个参数的数组。
#语法
function.call(thisArg, arg1, arg2, ...)
func.apply(thisArg, [argsArray])
实验
var name = "bob";
var obj = {
name: "harry",
func: function(age = "default",height = "default"){
console.log(this.name);
console.log(this.name,"'s age is :",age,"and height is :",height)
console.log(this);
console.log("---------------------------------")
}
}
var obj2 = {
name: "tom"
}
obj.func(21,171);
obj.func.call(null,23,172);
obj.func.call(obj,23,173);
obj.func.call(obj2,24,174);
console.log("==============================")
obj.func();
obj.func.apply(null,[22,172]);
obj.func.apply(obj,[23,173]);
obj.func.apply(obj2,[24,174]);
描述:
在这个示例中,有三个不同的对象,分别是:全局(window),obj ,obj2 。
当直接,进行函数,调用时候,不指定任何对象:
obj.func(21,171);
此时this
指向当前对象,即函数 func()
被定义的对象 obj中。
在使用call()
和 apply()
后, 当不指定任何参数:
obj.func.call(null,23,172);//不能为空,所以指向null
obj.func.apply(null,[23,173]);
此时this
将会指向全局对象,即 window 。
在指定特定的对象后,如 obj , obj2:
obj.func.call(obj2,24,174);
obj.func.apply(obj2,[24,174]);
此时,this
会指向特定的对象。
总结
call()
和 apply()
具体有什么意义呢? 总结的来看,当你在执行一个对象内的函数的时候,就务必需要考虑到 函数体中,this
的指向。否则很容易出现一些错误,好在,大多数情况下,是直接调用对象中的函数,此时的this
指向当前对象。
但是,如果,你希望借助A对象中的函数,去访问B对象中的属性,那就要切换this
的指向,这时候,call()
或者apply()
就能够派上用场了。 你可以轻松的将this
指向B对象,这样你就能够在A对象的函数中去访问B对象了。 从一定意义上来说,这实现了复用。
bind()
语法
bind()
的语法和call()
, apply()
类似,
function.bind(thisArg[, arg1[, arg2[, ...]]])
和call()
,apply()
所不同的是,bind()
方法,将会创建一个新的函数。 这个新函数的this
被指定为bind()
的第一个参数,而其余的参数将作为新函数的参数,一共函数调用。
实验⭐⭐
this.x = 9; // 在浏览器中,this 指向全局的 "window" 对象
var module = {
x: 81,
getX: function() { return this.x; }
};
module.getX(); // 81
var retrieveX = module.getX;
let a = retrieveX();
console.log(a);
// 返回 9 - 因为函数是在全局作用域中调用的⭐⭐⭐⭐⭐
// 创建一个新函数,把 'this' 绑定到 module 对象
var boundGetX = module.getX.bind(module);
let b = boundGetX(); // 81
console.log(b);
总结
bind()
最简单的用法,是创建一个函数,不论怎么调用,这个函数都有同样的this
值。
Js 新手常犯的一个错误,将一个方法从对象拿出来直接用,期望
this
的指向,原来的对象,如果不做特殊处理,一般会丢失原来的对象。 而基于bind()
这个函数,用原始的对象创建一个绑定函数,巧妙的解决了这个问题。
call()
, apply()
, bind()
的基础使用上,实现的目的,其实都一样,都是为了在调用对象内函数时,指定this
。 所不同的是, bind()
函数,将会返回一个绑定了指定this
的新函数。 而call()
,apply()
则是在调用的时候,临时指定this
。
这几个方法都有更加深层的应用和特性。 你应该在有一定掌握后去深入研究。
在这几个方法的使用学习和使用中,有几个问题特别需要留意,详见本文关联文章:
#FUNCTION#CALL对象中的函数内作用域问题.md