call()和apply()的区别以及简单使用

call() 方法使用一个指定的 this 值和单独给出的一个或多个参数来调用一个函数。
apply() 方法调用一个具有给定this值的函数,以及作为一个数组(或类似数组对象)提供的参数。
bind()方法创建一个新的函数,在bind()被调用时,这个新函数的this被bind的第一个参数指定,其余的参数将作为新函数的参数供调用时使用。

三者的相似之处:
1、都是用来改变函数的this对象的指向的。
2、第一个参数都是this要指向的对象。
3、都可以利用后续参数传参。

注意:call()方法的作用和 apply() 方法类似,区别就是call()方法接受的是参数列表,而apply()方法接受的是一个参数数组

语法:
call:fun.call(thisOject, arg1, arg2, ...)
apply:func.apply(thisOject, [argsArray])
bind:function.bind(thisOject[,arg1[,arg2[, ...]]])

一个小示例来解释三者的不同

function fn1(height){console.log(`姓名:${this.name},年龄:${this.age},身高:${height}`)}
var obj = {name:'李四',age:35}

fn1(180); // 姓名:undefined,年龄:undefined,身高:180

// call
fn1.call(obj,180); // 姓名:李四,年龄:35,身高:180

// apply
fn1.apply(obj,[180]); // 姓名:李四,年龄:35,身高:180

// bind
fn1.bind(obj,180)(); // 姓名:李四,年龄:35,身高:180

1.Function.prototype.call()

语法:fun.call(thisOject, arg1, arg2, ...)
参数:
thisOject:在 fun 函数运行时指定的 this 值。

if(thisOject== undefined|null) {this = window}
if(thisOject== number|boolean|string){ this == new Number()|new Boolean()| new String()}

arg1, arg2, ...指定的参数列表。

call() 允许为不同的对象分配和调用属于一个对象的函数/方法。
call() 提供新的 this 值给当前调用的函数/方法。可以使用 call 来实现继承:写一个方法,然后让另外一个新的对象来继承它(而不是在新对象中再写一次这个方法)。

示例:

实现继承:

/* 不使用继承,fn2使用fn1里面的属性 */
function fn1(name){this.name =name;this.sex ='女';}
function fn2(){this.age = 20;}

var f2 = new fn2();
console.log(f2.name);'// undefined
console.log(f2.sex);'// undefined

/* 使用call继承fn1 */
function fn1(name){this.name =name;this.sex ='女';}
function fn2(){fn1.call(this,'张三');this.age = 20;}

var f2 = new fn2();
console.log(f2.name); //"张三"
console.log(f2.sex); //"女"

实现调用函数并且指定上下文的 'this'

function fn1(height){console.log(`姓名:${this.name},年龄:${this.age},身高:${height}`)}
var obj = {name:'李四',age:35}

fn1(180); // 姓名:undefined,年龄:undefined,身高:180
fn1.call(obj,180); // 姓名:李四,年龄:35,身高:180

2.Function.prototype.apply()

apply 与 call() 非常相似,不同之处在于提供参数的方式。apply 使用参数数组而不是一组参数列表。apply 可以使用数组字面量(array literal),如 fun.apply(this, ['eat', 'bananas']),或数组对象, 如  fun.apply(this, new Array('eat', 'bananas'))。

例如上面的案例使用apply的话:

function fn1(height){console.log(`姓名:${this.name},年龄:${this.age},身高:${height}`)}
var obj = {name:'李四',age:35}

fn1(180); // 姓名:undefined,年龄:undefined,身高:180
fn1.call(obj,180); // 姓名:李四,年龄:35,身高:180

// apply
fn1.apply(obj,[180]); // 姓名:李四,年龄:35,身高:180

语法:func.apply(thisOject, [argsArray])
参数:
thisOject:可选的。在 func 函数运行时使用的 this 值。请注意,this可能不是该方法看到的实际值:如果这个函数处于非严格模式下,则指定为 null 或 undefined 时会自动替换为指向全局对象,原始值会被包装。
argsArray:可选的。一个数组或者类数组对象,其中的数组元素将作为单独的参数传给 func 函数。如果该参数的值为 null 或  undefined,则表示不需要传入任何参数。从ECMAScript 5 开始可以使用类数组对象。 浏览器兼容性 请参阅本文底部内容。

拓展
用 apply 将数组添加到另一个数组

var arr1 = ['张三', '李四'];
var arr2 = [0, 1, 2];
arr1.push.apply(arr1, arr2);
console.log(arr1 ); // ["张三", "李四", 0, 1, 2]

使用apply和内置函数

var arr = [4, 5, 1, 2, 6];

Math.max(...arr); // 6
Math.max.apply(null, arr);  // 6

但是当心:如果用上面的方式调用apply,会有超出JavaScript引擎的参数长度限制的风险。当你对一个方法传入非常多的参数(比如一万个)时,就非常有可能会导致越界问题, 这个临界值是根据不同的 JavaScript 引擎而定的

 

发布了112 篇原创文章 · 获赞 149 · 访问量 55万+

猜你喜欢

转载自blog.csdn.net/l284969634/article/details/100986801