如何区分call、apply、bind在JavaScript中的用法及其适用环境?

2026-04-28 10:071阅读0评论SEO问题
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1836个文字,预计阅读时间需要8分钟。

如何区分call、apply、bind在JavaScript中的用法及其适用环境?

call、apply、bind方法的作用和区别:

这三个方法的作用都是改变函数的执行上下文,即改变函数内部的this指向。简单来说,它们都是用来改变函数体内this的指向。

- call方法:用于调用一个函数,并传入一个或多个参数。语法为`func.call(thisValue, [arg1[, arg2[, ...]]])`。其中,thisValue是call方法将要使用的this值,后续参数是传递给函数的参数。

- apply方法:与call类似,也是用于调用一个函数,但apply方法接受一个参数数组。语法为`func.apply(thisValue, [argsArray])`。其中,thisValue是apply方法将要使用的this值,argsArray是一个包含所有参数的数组。

- bind方法:返回一个新函数,当这个新函数被调用时,其this值会被bind方法指定的值。语法为`func.bind(thisValue, [arg1[, arg2[, ...]]])`。其中,thisValue是bind方法将要使用的this值,后续参数是传递给新函数的参数。

具体来说:

1. call作用:用于立即执行函数,并改变函数内部的this指向。

2.apply作用:用于立即执行函数,并改变函数内部的this指向,同时传入一个参数数组。

3.bind作用:返回一个新函数,当这个新函数被调用时,其this值会被bind方法指定的值,但不立即执行函数。

如何区分call、apply、bind在JavaScript中的用法及其适用环境?

总结:这三个方法都是用来改变函数的执行上下文,但使用方式和效果略有不同。call和apply用于立即执行函数,而bind返回一个新函数,需要在适当的时候调用。

call、apply、bind方法的作用和区别:

这三个方法的作用都是改变函数的执行上下文,换句话说就是改变函数体内部的this指向,以此来扩充函数依赖的作用域

1.call

作用:用于改变方法内部的this指向

格式:xxx.call(对象名,参数1,参数2,...) 即:将 xxx 方法中的 this 指向 对象名

例子:未使用call方法前,test()中的this指向window,使用后指向obj对象

function test(a,b){ console.log(this); console.log(a + b); } test(1,2); // window 3 var obj = {name:'lqs'}; window.test.call(obj,3,5); // {name:'lqs'} 8

2.apply

作用:和call方法一样是修改内部的 this 指向的,区别在于apply的第二个参数必须是一个数组(部署了Iterator接口的类数组对象也是可以的)

格式:xxx.apply(对象名,[...]) 即:将 xxx 方法中的this 指向 对象名,数组中的元素依次与方法的形参对应

例子:未使用apply方法前,test()中的this指向window,使用后指向obj对象

function test(a,b){ console.log(this); console.log(a + b); } test(1,2); // window 3 var obj = {name:'lqs'}; window.test.call(obj,[3,5]); // {name:'lqs'} 8

3.bind

作用:也是用于改变this的指向

格式:xxx.bind(对象名,参数1,参数2,...) 即:将 xxx 方法中的this 指向 对象名,传参与call一样

例子:未使用bind方法前,foo()中的this指向window,使用后指向obj对象

var obj = {key:"value"} var foo = function(){ console.log(this) } foo.bind(obj)() // obj

区别:

三者的第一个参数都是this需要指向的对象,但在后续的参数上只有apply是接收一个数组,call和bind用逗号分开

call和apply直接调用,返回的是一个值,而bind不直接调用,返回的是一个函数形式,执行:foo.bind(obj)()

应用场景:

通常情况下call用于对象的继承,真伪数组转换、apply用于找出数组中的最大值和最小值以及数组合并、bind用于vue和react中改变函数this指向

对象继承:

在构造函数中调用父构造函数,但是改变this指向,就可以继承父属性

function superClass () { this.a = 1; this.print = function () { console.log(this.a); } } function subClass () { superClass.call(this); // 执行superClass,并将superClass方法中的this指向subClass this.print(); } subClass();

类数组与真数组的转换:

类数组:具有length属性的对象,且键为数字或string类型的数字;例如:元素检索 api 返回的都是类数组

document.getElementsByTagNamedocument.querySelectorAll等等。除了dom api中,常见的function中的arguments也是类数组

数组 ==> 数组:

var arr = [1,3,5]; var obj = {}; [].push.apply(obj,arr); // { 0:1, 1:3 , 2:5 , length:3 }

类数组 ==> 真数组:

ES5:call、apply、Array API

// 系统自带类数组对象 var divs = document.querySelectorAll('div'); // 自定义类数组对象 var obj = {0:'lqs' , 1:18 , length:2}; var arr = []; // 真数组 // 在高级的浏览器中使用如下的方法是可以实现类数组对象转换为真数组,但是在 IE8 及其以下是不行的 // [].push.apply(arr,divs); // [].push.apply(arr,obj); // 为了兼容 IE8 及其以下的浏览器,需要使用数组的 slice 方法 // 数组的 slice 方法不传递参数的时候是将数组中的元素依次遍历然后放到一个 新的数组 中原样返回 var arr2 = [].slice.call(obj);

// 一切以数组为输入,并以数组为输出的API都可用来做数组转换 Array (借用 arguments) Array.prototype.concat (借用 arguments) Array.prototype.slice (借用 this) Array.prototype.map (借用 this) Array.prototype.filter (借用 this)

const arrayLike = {0: 3,1: 4,2: 5,length: 3} Array.prototype.slice.call(arrayLike) Array.apply(null, arrayLike) Array.prototype.concat.apply([], arrayLike) Array.prototype.slice.call(arrayLike) Array.prototype.map.call(arrayLike, x => x) Array.prototype.filter.call(arrayLike, x => 1)

ES6:Array.from()、... 扩展运算符

// Array.from();方法用于将类数组对象和可遍历(Iterator)对象转换为真数组 var obj = {0:'lqs' , 1:18 , length:2}; var arr = Array.from(obj) // ['lqs',18]

// ... 扩展运算符 // 适用于 iterable 对象 [...doucmnet.querySelector('div')] // 但在{length:3}这种情况下会抛出异常 // Uncaught TypeError: object is not iterable (cannot read property Symperty Symbol(Symbol.iterator))[...{length:3}]

jQuery:.get() .toArray()和$makeArray(obj)

稀疏数组:

使用Array(n) 将会创建一个稀疏数组,为了节省空间,稀疏数组内含非真实元素,在控制台上将以empty显示

如下:[,,,]与Array(3) 都将返回稀疏数组

> [,,,][empty × 3] > Array(3)[empty × 3]

当类数组为{ length: 3 }时,一切将类数组做为this的方法将都返回稀疏数组,而将类数组做为arguments的方法将都返回密集数组

数组中最大最小值及数组合并:

获取数组中最大、最小的一项

let max = Math.max.apply(null, array);

let min = Math.min.apply(null, array);

实现两个数组合并

let arr1 = [1, 2, 3];

let arr2 = [4, 5, 6];

Array.prototype.push.apply(arr1, arr2);

console.log(arr1); // [1, 2, 3, 4, 5, 6]

总结:

以上方法中靠谱的数组转换方法

Array.from(arrayLike)

Array.apply(null, arrayLike)

Array.prototype.concat.apply([], arrayLike)

需要考虑稀疏数组转化

Array.prototype.filter.call(divs, x => 1)

Array.prototype.map.call(arrayLike, x => x)

Array.prototype.filter.call(arrayLike, x => 1)

以下方法要注意是否是iterable object

[...arrayLike]

参考:

www.cnblogs.com/deng-jie/p/15038342.html

wenku.baidu.com/view/533ab9c6514de518964bcf84b9d528ea80c72f54.html

wenku.baidu.com/view/bfd955c1514de518964bcf84b9d528ea81c72f77.html

blog.csdn.net/weixin_39828457/article/details/111701235

本文共计1836个文字,预计阅读时间需要8分钟。

如何区分call、apply、bind在JavaScript中的用法及其适用环境?

call、apply、bind方法的作用和区别:

这三个方法的作用都是改变函数的执行上下文,即改变函数内部的this指向。简单来说,它们都是用来改变函数体内this的指向。

- call方法:用于调用一个函数,并传入一个或多个参数。语法为`func.call(thisValue, [arg1[, arg2[, ...]]])`。其中,thisValue是call方法将要使用的this值,后续参数是传递给函数的参数。

- apply方法:与call类似,也是用于调用一个函数,但apply方法接受一个参数数组。语法为`func.apply(thisValue, [argsArray])`。其中,thisValue是apply方法将要使用的this值,argsArray是一个包含所有参数的数组。

- bind方法:返回一个新函数,当这个新函数被调用时,其this值会被bind方法指定的值。语法为`func.bind(thisValue, [arg1[, arg2[, ...]]])`。其中,thisValue是bind方法将要使用的this值,后续参数是传递给新函数的参数。

具体来说:

1. call作用:用于立即执行函数,并改变函数内部的this指向。

2.apply作用:用于立即执行函数,并改变函数内部的this指向,同时传入一个参数数组。

3.bind作用:返回一个新函数,当这个新函数被调用时,其this值会被bind方法指定的值,但不立即执行函数。

如何区分call、apply、bind在JavaScript中的用法及其适用环境?

总结:这三个方法都是用来改变函数的执行上下文,但使用方式和效果略有不同。call和apply用于立即执行函数,而bind返回一个新函数,需要在适当的时候调用。

call、apply、bind方法的作用和区别:

这三个方法的作用都是改变函数的执行上下文,换句话说就是改变函数体内部的this指向,以此来扩充函数依赖的作用域

1.call

作用:用于改变方法内部的this指向

格式:xxx.call(对象名,参数1,参数2,...) 即:将 xxx 方法中的 this 指向 对象名

例子:未使用call方法前,test()中的this指向window,使用后指向obj对象

function test(a,b){ console.log(this); console.log(a + b); } test(1,2); // window 3 var obj = {name:'lqs'}; window.test.call(obj,3,5); // {name:'lqs'} 8

2.apply

作用:和call方法一样是修改内部的 this 指向的,区别在于apply的第二个参数必须是一个数组(部署了Iterator接口的类数组对象也是可以的)

格式:xxx.apply(对象名,[...]) 即:将 xxx 方法中的this 指向 对象名,数组中的元素依次与方法的形参对应

例子:未使用apply方法前,test()中的this指向window,使用后指向obj对象

function test(a,b){ console.log(this); console.log(a + b); } test(1,2); // window 3 var obj = {name:'lqs'}; window.test.call(obj,[3,5]); // {name:'lqs'} 8

3.bind

作用:也是用于改变this的指向

格式:xxx.bind(对象名,参数1,参数2,...) 即:将 xxx 方法中的this 指向 对象名,传参与call一样

例子:未使用bind方法前,foo()中的this指向window,使用后指向obj对象

var obj = {key:"value"} var foo = function(){ console.log(this) } foo.bind(obj)() // obj

区别:

三者的第一个参数都是this需要指向的对象,但在后续的参数上只有apply是接收一个数组,call和bind用逗号分开

call和apply直接调用,返回的是一个值,而bind不直接调用,返回的是一个函数形式,执行:foo.bind(obj)()

应用场景:

通常情况下call用于对象的继承,真伪数组转换、apply用于找出数组中的最大值和最小值以及数组合并、bind用于vue和react中改变函数this指向

对象继承:

在构造函数中调用父构造函数,但是改变this指向,就可以继承父属性

function superClass () { this.a = 1; this.print = function () { console.log(this.a); } } function subClass () { superClass.call(this); // 执行superClass,并将superClass方法中的this指向subClass this.print(); } subClass();

类数组与真数组的转换:

类数组:具有length属性的对象,且键为数字或string类型的数字;例如:元素检索 api 返回的都是类数组

document.getElementsByTagNamedocument.querySelectorAll等等。除了dom api中,常见的function中的arguments也是类数组

数组 ==> 数组:

var arr = [1,3,5]; var obj = {}; [].push.apply(obj,arr); // { 0:1, 1:3 , 2:5 , length:3 }

类数组 ==> 真数组:

ES5:call、apply、Array API

// 系统自带类数组对象 var divs = document.querySelectorAll('div'); // 自定义类数组对象 var obj = {0:'lqs' , 1:18 , length:2}; var arr = []; // 真数组 // 在高级的浏览器中使用如下的方法是可以实现类数组对象转换为真数组,但是在 IE8 及其以下是不行的 // [].push.apply(arr,divs); // [].push.apply(arr,obj); // 为了兼容 IE8 及其以下的浏览器,需要使用数组的 slice 方法 // 数组的 slice 方法不传递参数的时候是将数组中的元素依次遍历然后放到一个 新的数组 中原样返回 var arr2 = [].slice.call(obj);

// 一切以数组为输入,并以数组为输出的API都可用来做数组转换 Array (借用 arguments) Array.prototype.concat (借用 arguments) Array.prototype.slice (借用 this) Array.prototype.map (借用 this) Array.prototype.filter (借用 this)

const arrayLike = {0: 3,1: 4,2: 5,length: 3} Array.prototype.slice.call(arrayLike) Array.apply(null, arrayLike) Array.prototype.concat.apply([], arrayLike) Array.prototype.slice.call(arrayLike) Array.prototype.map.call(arrayLike, x => x) Array.prototype.filter.call(arrayLike, x => 1)

ES6:Array.from()、... 扩展运算符

// Array.from();方法用于将类数组对象和可遍历(Iterator)对象转换为真数组 var obj = {0:'lqs' , 1:18 , length:2}; var arr = Array.from(obj) // ['lqs',18]

// ... 扩展运算符 // 适用于 iterable 对象 [...doucmnet.querySelector('div')] // 但在{length:3}这种情况下会抛出异常 // Uncaught TypeError: object is not iterable (cannot read property Symperty Symbol(Symbol.iterator))[...{length:3}]

jQuery:.get() .toArray()和$makeArray(obj)

稀疏数组:

使用Array(n) 将会创建一个稀疏数组,为了节省空间,稀疏数组内含非真实元素,在控制台上将以empty显示

如下:[,,,]与Array(3) 都将返回稀疏数组

> [,,,][empty × 3] > Array(3)[empty × 3]

当类数组为{ length: 3 }时,一切将类数组做为this的方法将都返回稀疏数组,而将类数组做为arguments的方法将都返回密集数组

数组中最大最小值及数组合并:

获取数组中最大、最小的一项

let max = Math.max.apply(null, array);

let min = Math.min.apply(null, array);

实现两个数组合并

let arr1 = [1, 2, 3];

let arr2 = [4, 5, 6];

Array.prototype.push.apply(arr1, arr2);

console.log(arr1); // [1, 2, 3, 4, 5, 6]

总结:

以上方法中靠谱的数组转换方法

Array.from(arrayLike)

Array.apply(null, arrayLike)

Array.prototype.concat.apply([], arrayLike)

需要考虑稀疏数组转化

Array.prototype.filter.call(divs, x => 1)

Array.prototype.map.call(arrayLike, x => x)

Array.prototype.filter.call(arrayLike, x => 1)

以下方法要注意是否是iterable object

[...arrayLike]

参考:

www.cnblogs.com/deng-jie/p/15038342.html

wenku.baidu.com/view/533ab9c6514de518964bcf84b9d528ea80c72f54.html

wenku.baidu.com/view/bfd955c1514de518964bcf84b9d528ea81c72f77.html

blog.csdn.net/weixin_39828457/article/details/111701235