call,apply,bind的区别及使用

636 阅读2分钟

call,apply,bind的意义

改变函数执行时的上下文,也就是改变this指向

call,apply,bind的用法及区别

apply、call、bind 都是可以改变 this 的指向的,但是这三个函数稍有不同。 在 MDN中定义 call 如下;

call() 方法使用一个指定的 this 值和单独给出的一个或多个参数来调用一个函数。

语法:

function.call(thisArg, arg1, arg2, ...)

该方法的语法和作用与 apply() 方法类似,只有一个区别,就是 call() 方法接受的是一个参数列表,而 apply() 方法接受的是一个包含多个参数的数组

bind和call的作用和参数一样,只不过bind不是立即执行,需要再次调用

    var name = "1";
    var obj = {
        name: 2,
        prop: {
            name: 3,
            getName: function (age, s) {
                return {
                    name: this.name,
                    age: age,
                    s: s
                }
            }
        }
    }
    console.info(obj.prop.getName(3, 4)); // 3, 4, 3
    console.info(obj.prop.getName.call(obj, 3, 4)); //2, 3, 4 
    console.info(obj.prop.getName.call(this, 3, 4)); //this是window 1, 3, 4
    console.info(obj.prop.getName.apply(this, [2, 3])); //this是window 1, 3, 4
    // let array = [1, 2, 3]

示例

使用call方法调用父构造函数

在一个子构造函数中,你可以通过调用父构造函数的 call 方法来实现继承,类似于 Java 中的写法。下例中,使用 Dog 构造函数创建的对象实例都会拥有在 Animal 构造函数中添加的 name 属性和 sex 属性,但 age 属性是在各自的构造函数中定义的。

    function Animal(name, sex) {
        this.name = name
        this.sex = sex
    }
    function Dog(name, sex, age) {
        Animal.call(this, name, sex)
        this.age = age
    }
    const dog = new Dog('狗狗', '男', 12)
    console.log(dog) 

将类数组,转化成数组

类数组

  1. 类数组看起来像数组,但是没有数组的一些方法
  2. 是个对象,但是有length属性 类数组的几个出处
  3. 获取dome节点:
  4. arguments: 获取函数传递参数的集合,是一个类数组
  5. 自定义类数组对象: 定义一个对象,但是有length属性

获取dome节点,将类数组转化为数组

<body>
   <div class="divDom"></div>
   <div class="divDom"></div>
   <div class="divDom"></div>
   <div class="divDom"></div>
</body>
<script>
   let divDom = document.getElementsByClassName('divDom')
   console.log('divDom', divDom instanceof Array) // false
   let arr = Array.prototype.slice.call(divDom)
   console.log('arr', arr instanceof Array) // true
<script/>
其他的转化方法

假设divDom 是一个Dom集合

将divDom用Array.from()转换为数组,并用list变量接收
let list= Array.from(divDom) 

判断数据类型

 let array = [1, 2, 4]
    let array2 = 2
    function isArray(arr) {
        return Object.prototype.toString.call(arr) === '[object Array]'
    }
    console.log('类型检测', isArray(array)) // true
    console.log('类型检测', isArray(array2)) // false

后续文章输出

  1. 说call,apply,bind,改变this的指向,那么this的指向到底是怎么回事呢?
  2. this的执行跟作用域,作用域链的关系
  3. 怎么判断是数组
  4. Object.prototype.toString.call() 为什么要toString,call 为什么要和[object, Array] 做比较
  5. 手写call,apply,bind