5.call apply bind 小结
Geek-James opened this issue · 6 comments
apply()
apply() 方法调用一个函数, 其具有一个指定的this值,以及作为一个数组(或类似数组的对象)提供的参数
语法:
fun.apply(thisArg, [argsArray])
-
thisArg:在 fun 函数运行时指定的 this 值。需要注意的是,指定的 this 值并不一定是该函数执行时真正的 this 值,如果这个函数处于非严格模式下,则指定为 null 或 undefined 时会自动指向全局对象(浏览器中就是window对象),同时值为原始值(数字,字符串,布尔值)的 this 会指向该原始值的自动包装对象。
-
argsArray:一个数组或者类数组对象,其中的数组元素将作为单独的参数传给 fun 函数。如果该参数的值为null 或 undefined,则表示不需要传入任何参数。从ECMAScript 5 开始可以使用类数组对象。浏览器兼容性请参阅本文底部内容。
apply 和 call 的区别
其实 apply 和 call 基本类似,他们的区别只是传入的参数不同。
语法:
fun.call(thisArg[, arg1[, arg2[, ...]]])
所以 apply 和 call 的区别是 call 方法接受的是若干个参数列表,而 apply 接收的是一个包含多个参数的数组。
var a ={
name : "Cherry",
fn : function (a,b) {
console.log( a + b)
}
}
var b = a.fn;
// 接受的是一个数组
b.apply(a,[1,2]) // 3
var a ={
name : "Cherry",
fn : function (a,b) {
console.log( a + b)
}
}
var b = a.fn;
// 接受的是参数
b.call(a,1,2) // 3
bind 和 apply、call 区别
var a ={
name : "Cherry",
fn : function (a,b) {
console.log( a + b)
}
}
var b = a.fn;
b.bind(a,1,2)
以上code我们会发现并没有输出.
bind()方法创建一个新的函数, 当被调用时,将其this关键字设置为提供的值,在调用新函数时,在任何提供之前提供一个给定的参数序列。
所以我们可以看出,bind 是创建一个新的函数,我们必须要手动去调用:
var a ={
name : "Cherry",
fn : function (a,b) {
console.log( a + b)
}
}
var b = a.fn;
b.bind(a,1,2)() // 3
一个面试经典问题:new 的过程了
伪代码
var a = new myFunction("Li","Cherry");
new myFunction{
var obj = {};
obj.__proto__ = myFunction.prototype;
var result = myFunction.call(obj,"Li","Cherry");
return typeof result === 'obj'? result : obj;
}
- 1.创建一个空对象 obj;开辟一个新的内存空间
- 2.将新创建的空对象的隐式原型指向其构造函数的显示原型。
- 3.使用 call 改变 this 的指向,指向新开辟的内存空间
- 4.如果无返回值或者返回一个非对象值,则将 obj 返回作为新对象;如果返回值是一个新对象的话那么直接直接返回该对象。
所以我们可以看到,在 new 的过程中,我们是使用 call 改变了 this 的指向。
运用场景
// 实现继承
function Animal(name) {
this.name = name;
this.showName = function () {
console.log(this.name);
}
}
function Cat(name) {
Animal.call(this, name);
}
var cat = new Cat('black cat');
console.dir(Cat)
cat.showName();
// 数组追加
var array1 = [1, 2, 3, 4, 5];
var array2 = ['ss','dd','adf','iu'];
// 在谁的基础上进行增加
Array.prototype.push.apply(array2,array1);
console.log(array2);
//获取数组中的最大值和最小值
var num = [1,2,4,5,6,7,9];
var maxNum = Math.max.apply(Math,num);
var minNum = Math.min.apply(Math,num);
console.log(maxNum);
console.log(minNum);
// 将伪数组转为数组
var fakeArr = {0:'a',1:'b',2:'c',length:2};
var arr1 = Array.prototype.slice.call(fakeArr);
console.log(arr1[0]);
var arr2 = [].slice.call(fakeArr);
console.log(arr2[0]);
arr1.push('c');
console.log(arr1);
//保存this变量
var foo = {
bar:1,
eventBind:function () {
var _this = this;
$('.someClass').on('click',function (event) {
console.log(_this.bar);
});
}
}
var foo = {
bar:1,
eventBind:function () {
$('.someClass').on('click',function (event) {
console.log(this.bar);
}.bind(this))
}
}
总结 apply 、 call 、bind
-
三者都是用来改变函数的this对象的指向的;
-
apply 、 call 、bind 三者第一个参数都是this要指向的对象,也就是想指定的上下文;
-
apply 、 call 、bind 三者都可以利用后续参数传参;
-
bind 是返回对应函数,便于稍后调用;apply 、call 则是立即调用 。
参考网站
你好,再this的那边,你讲的是apply讲this指向新对象,这边说的是call呢
你好,再this的那边,你讲的是apply讲this指向新对象,这边说的是call呢
call和apply都可以改变this的指向,call改变this指向传入的是字符串对象,而apply传入的是数组对象
所以在new那边,改变this指向,两个方法都是可以的吗
所以在new那边,改变this指向,两个方法都是可以的吗
对是的,apply 和 call 的区别是 call 方法接受的是若干个参数列表,而 apply 接收的是一个包含多个参数的数组。本质上是改变this的指向,只不过区别在于传入的参数列表存在差别,如果传入的参数都不是数组,那么这两个方法是一样的效果。你可以尝试着用实例代码跑一遍。
噢噢,知道了,非常感谢
噢噢,知道了,非常感谢
不客气😄加油🚀