call apply bind简单理解

js函数涉及到作用域时,函数定义时作用域以及很多东西无法确定,只有调用它时才能确定

call

作用是改变运行时上下文(作用域,即this),但是很多博客解释的非常复杂,这个解释比较清楚,直接上代码,上下两段代码等价。

function add(c,d) {
        return this.a + this.b + c + d;
    }
    const obj = {a: 1, b: 2};
    console.log(add.call(obj, 3, 4)); // 10
    // 等价于
    const o = {
        a: 1,
        b: 2,
        add: function(c,d) {
            return this.a + this.b + c + d;
        }
    };
    console.log(o.add(3,4)) // 10
    // 感觉相当于把add这个方法拉到obj这个作用域里来

apply

apply和call区别在于apply第二个参数是Array,而call是将一个个传入,将第一段代码改写可得

    function add(c,d) {
        return this.a + this.b + c + d;
    }
    const obj = {a: 1, b: 2};
    console.log(add.apply(obj, [3, 4])); // 10
    // 或者
    const e = [3, 4];
    console.log(add.apply(obj, e)); // 10

bind

bind 的作用和call很像,也会将它的第一个参数变成函数运行时的作用域对象,后边的参数作为函数的参数传入,但是它的独特型在于它会新建一个函数,上述的作用发生在这个新的函数被调用时,而且,当这个新函数作为构造函数时,它当时绑定的this对象(也就是刚刚的第一个参数)会失效,不过后边的参数依然有效。

    function foo(c,d) {
        this.b = 100;
        console.log(this.a);
        console.log(this.b);
        console.log(c)
        console.log(d)
    }
    var func = foo.bind({a: 1},'no.1')
    func('no.2')
        // 1
        // 100
        // no.1
        // no.2
    // 即使call也不能改变this
    func.call({a: 2},'no3')
        // 1
        // 100
        // no.1
        // no.3
    // 当 bind 返回的函数作为构造函数的时候,
    // bind 时指定的 this 值会失效,但传入的参数依然生效。
    // 所以使用func为构造函数时,this不会指向{a: 1}对象,this.a的值为undefined
    new func('no.4')

类数组对象转数组

类数组对象虽然可以访问到某个键值,但是却不能进行遍历

es5和es6都有各自的方法实现:

    const list = document.getElementsByTagName('li')
    console.log(Array.isArray(list)) // 不是数组
    console.log(list[2].innerHTML) // 可以输出其下某个元素的值
    console.log(list.forEach); // 无法进行遍历
    // ES5方法将类数组对象数组化
    var es5 = Array.prototype.slice.call(list)
    // 或者使用 var es5 = [].slice.call(list)
    console.log(es5)
    // ES6方法将类数组对象数组化
    var es6 = Array.from(list)
    console.log(es6)
发布了46 篇原创文章 · 获赞 12 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/yuanfangyoushan/article/details/103326589