call、apply和bind的用法与说明

介绍

call、apply、bind的作用是改变函数运行时this的指向,欲了解函数,首先需知this

this

this到底是什个什么样的东西呢?

this即“这个”的意思,在代码中this指向调用函数的主体对象。


举个栗子:在一个代码中,例如:

var obj = {
  foo: function(){
    console.log(this)
  }
}
var bar = obj.foo
obj.foo() // 打印出的 this 是 obj
bar() // 打印出的 this 是 window

那么为什么会出现这种现象呢?这就得从函数的调用来说起了。
在 java script 中说起函数调用你首先想到的肯定是myFunction(a, b),厉害点的可能还会想到obj.objFunction()没错,这些都可以实现对函数调用,那么这些调用方式又有什么区别和联系呢?
首先我们先列举出来这些个调用方式

  • 作为一个函数进行调用myFunction(a, b)
  • 作为对象的一个方法进行调用obj.objFunction()
  • 使用构造函数调用let Bob = new Student('Bob', 18)
  • 作为函数的方法调用myFunction.call(context, a, b)

一般情况下,我们都习惯使用前几种方式,殊不知最后一种myFunction.call(context, a, b)才是正常的调用形式,其他几种都是语法糖,可以等价转换为此形式。

myFunction(a, b) 可等价于 myFunction.call(undefined, a, b)

obj.objFunction() 可等价于 obj.objFunction.call(obj)

这样来说this就好理解了,this其实就是以上式子中的context及call中的第一个参数。


注意:

如果你传的 context 是 null 或者 undefined,那么 window 对象就是默认的 context(严格模式下默认 context 是 undefined)

call

call(打电话)可以实现函数与对象间的交流,使其具有联系

fun.call(context, arg1, arg2, ...)

  • 参数说明:
    • context :在 fun函数运行时指定的this值,当第一个参数为null、undefined的时候,默认指向window。
    • arg1, arg2:…指定的参数列表。
  • 返回值:
    使用调用者提供的 this 值和参数调用该函数的返回值。若该方法没有返回值,则返回undefined。

apply

与call相似,只是参数不同而已

fun.apply(context, arr)

  • 参数说明:
    • context :在 fun函数运行时指定的this值,当第一个参数为null、undefined的时候,默认指向window。
    • arr 一个数组或者类数组对象,其中的数组元素将作为单独的参数传给 func 函数。

举栗子:将数组添加到另一个数组

let array = ['s', 'm', 'i', 'l', 'e']
let elements = [0, 1, 2]
array.push.apply(array, elements);
console.info(array); // ['s', 'm', 'i', 'l', 'e', 0, 1, 2]

既然callapply没多大区别,那么如何在两者间进行选择呢?

在参数杂乱无章,没有任何关联时建议使用call。如若参数存在一个数组中那么使用apply更加的合适

bind

bind会创建一个新绑定函数,它包装了原函数对象

fun.bind(context, arg1, arg2, ...)

  • 参数说明:
    • context :在 fun函数运行时指定的this值,当第一个参数为null、undefined的时候,默认指向window。
    • arg1, arg2:…指定的参数列表。
  • 返回值:
    返回一个原函数的拷贝,并拥有指定的this值和初始参数。

bind 方法不会立即执行,而是返回一个改变了上下文 this 后的函数。而原函数中的 this 并没有被改变,依旧指向全局对象 window

主要应用场景

  • 求数组中的最大和最小值
var arr = [1,2,3,4,5]
var max = Math.max.apply(null,arr)//5
var min = Math.min.apply(null,arr)//1
  • 数组追加
let array = ['s', 'm', 'i', 'l', 'e']
let elements = [0, 1, 2]
array.push.apply(array, elements);
// array['s', 'm', 'i', 'l', 'e', 0, 1, 2]
  • 判断变量类型
function isArray(obj){
  return Object.prototype.toString.call(obj) == '[object Array]';
}
isArray([]) // true
isArray('dcbryant') // false
  • 使用 log 代理 console.log
function log(){
  console.log.apply(console, arguments);
}
// 当然也有更方便的 var log = console.log()
  • 利用call和apply做继承
function Person(name,age){
  // 这里的this都指向实例
  this.name = name
  this.age = age
  this.sayAge = function(){
    console.log(this.age)
  }
}
function Female(){
  Person.apply(this,arguments)//将父元素所有方法在这里执行一遍就继承了
}
var dot = new Female('Dot',2)

参考

一次性讲清楚apply/call/bind

<think>我们之前已经讨论了callapply,现在需要加上bind,并比较三者的用法区别。 回答结构: 1. 分别介绍callapplybind用法,包括语法示例。 2. 比较三者的区别,特别是bind前两者的不同(如返回函数而非立即执行)。 3. 最后按照要求提出3-5个相关问题。 注意:必须包含“§§相关问题§§”在最后,且第一行必须是这个字符串,然后列出3-5个问题。</think>在 JavaScript 中,`call`、`apply` `bind` 都是用于管理函数执行上下文(`this` 值)的方法,但它们在执行方式用途上有显著区别: ### 1. **call** - **用法**:立即执行函数,显式设置 `this` 值并以**参数列表**传递参数 `func.call(thisArg, arg1, arg2, ...)` - **特点**: ```javascript const person = { name: 'Alice' }; function greet(greeting) { return `${greeting}, ${this.name}!`; } greet.call(person, 'Hello'); // 输出: "Hello, Alice!" ``` ### 2. **apply** - **用法**:立即执行函数,显式设置 `this` 值并以**数组形式**传递参数 `func.apply(thisArg, [argsArray])` - **特点**: ```javascript const person = { name: 'Bob' }; function introduce(age, hobby) { return `${this.name} is ${age} years old, loves ${hobby}`; } introduce.apply(person, [30, 'hiking']); // 输出: "Bob is 30 years old, loves hiking" ``` ### 3. **bind** - **用法**:返回一个新函数(不立即执行),永久绑定 `this` 值预设参数 `const newFunc = func.bind(thisArg, arg1, arg2)` - **特点**: ```javascript const car = { brand: 'Tesla' }; function showDetails(color, year) { return `${this.brand} | Color: ${color} | Year: ${year}`; } const boundFunc = showDetails.bind(car, 'Red'); // 绑定this第一个参数 boundFunc(2023); // 输出: "Tesla | Color: Red | Year: 2023" ``` ### 🔑 核心区别总结 | **方法** | **执行时机** | **参数形式** | **返回值** | 典型场景 | |----------|--------------|--------------------|------------------|------------------------------| | `call` | 立即执行 | 逗号分隔参数列表 | 函数原返回值 | 明确参数数量时 | | `apply` | 立即执行 | 单数组参数 | 函数原返回值 | 参数动态或来自数组时 | | `bind` | 延迟执行 | 逗号分隔参数列表 | 绑定后的新函数 | 需要函数副本(如事件回调) | > ⚠️ **注意**: > - `call`/`apply` 会立即调用函数,而 `bind` 只创建绑定上下文的新函数 > - 箭头函数的 `this` 由词法作用域决定,三者均无法改变其 `this` 绑定
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值