JS中 call、apply 和 bind 的区别及应用

概述

    JS中的 call,apply 和 bind 是 Function.prototype 下的方法,都是用于改变函数执行时的上下文。最终的返回值是你调用的方法的返回值,若该方法没有返回值,则返回 undefined。它们的作用都是改变当前函数 this 的指向。

Call

    call 方法接收的是参数列表,简单说就是需要把实参按照形参的个数传进去
    call 方法的第一个参数用于改变 this 指向,但是如果传入 null / undefined 值,this 会指向 window

'use strict'    //  严格模式
var obj = {
    value: '我是obj对象'
}

function fn(a, b) {
    console.log(this)
    console.log(a + b)
}

fn(10,20)                    // 普通模式下 this 是 window,在严格模式下 this 是 undefined   30
fn.call('',10,20)            // 普通模式下 this 是 {''},  在严格模式下 this 是 ''          30
fn.call(obj,10,20)           // 普通模式下 this 是 obj,   在严格模式下 this 是 obj         30
fn.call(null,10,20)          // 普通模式下 this 是 window,在严格模式下 this 是 null        30
fn.call(undefined,10,20)     // 普通模式下 this 是 window,在严格模式下 this 是 undefined   30

call 应用场景

  1. 验证是否是数组
function isArray(obj){
	return Object.prototype.toString.call(obj) === '[object Array]'
}

var obj = {
	name: 'lisi'
}
var arr = [1, 2, 3, 4, 5, 6]

console.log(isArray(obj))  // false
console.log(isArray(arr))  // true
  1. 将伪数组转为标准数组
<body>
<div>one</div>
<div>two</div>
<div>three</div>
<script>
    function change(arr){
        return Array.prototype.slice.call(arr)
    }

    var divs = document.getElementsByTagName("div")
    console.log(divs)          // HTMLCollection(3) [div, div, div]
    console.log(change(divs))  // [div, div, div]
</script>
</body>

apply

    apply 方法的第二个参数需要传入一个实参列表,也就是数组或类数组
    apply 方法的第一个参数用于改变 this 指向,但是如果传入 null / undefined 值,this 会指向 window

apply 应用场景

  1. 获取数组中的最大值和最小值
const arr = [1,2,3,4,5,6]
const max = Math.max.apply(null, arr)
const min = Math.min.apply(null, arr)

console.log(max)    // 6
console.log(min)    // 1
  1. 数组之间追加(拼接数组)
const arr1 = [1, 2, 3, 'name']
const arr2 = ['age', 4, 5, 6]
Array.prototype.push.apply(arr1, arr2)

console.log(arr1)   // [1, 2, 3, "name", "age", 4, 5, 6]
  1. 封装一个简单的 log 方法
function log() {
	console.log.apply(console, arguments)
}

log(123)            // 123
log('name', 456)    // name 456

bind

    bind 方法直接改变这个函数的 this 指向并且返回一个新的函数,之后再次调用这个函数的时候 this 都是指向 bind 绑定的第一个参数。IE6、7、8不支持
    bind 方法的第一个参数也是用于改变 this 指向,如果传入null / undefined,this 会指向window
    bind 方法可以使函数拥有预设的初始参数。这些参数(如果有的话)作为 bind () 的第二个参数跟在this(或其他对象)后面,之后它们会被插入到目标函数的参数列表的开始位置,传递给绑定函数的参数会跟在它们的后面

    bind 的第二个参数传入是 参数列表

var obj = {
	name: 'lisi',
	age: 20
}

function Person(name, age) {
    console.log(this.name, this.age)
    console.log(name, age)
    console.log(arguments)
}

var fn = Person.bind(obj,'zhangsan', 21)
fn(1,2,3)

// lisi 20
// zhangsan 21
// Arguments(5)["zhangsan", 21, 1, 2, 3]

    bind 的第二个参数传入是 实参列表(数组)

var obj = {
	name: 'lisi',
	age: 20
}

function Person() {
    console.log(this.name, this.age)
    console.log(arguments)
}

var fn = Person.bind(obj, ['zhangsan',20])
fn(1,2,3)

// lisi 20
// Arguments(4)[Array(2), 1, 2, 3]

call 和 apply 的区别

  1. call 是 apply 的语法糖
  2. call 和 apply 都是改变 this 指向后并执行函数
  3. call 和 apply 的第一个参数的作用相同,都是让另外一个对象替换当前对象,改变 this 的指向
  4. call 的第二个参数传入的是参数列表,apply 的第二个参数传入的是实参列表,也就是数组或类数组

call 和 bind 的区别

  1. call 是改变 this 指向后并执行函数,bind 是返回改变 this 指向后的函数
  2. call 的第二个参数传入的是参数列表,bind 的第二个参数(可选)可以是参数列表,也可以是实参列表(数组)

猜你喜欢

转载自blog.csdn.net/fu983531588/article/details/89505587