Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

5.call apply bind 小结 #5

Open
Geek-James opened this issue Jul 18, 2019 · 6 comments
Open

5.call apply bind 小结 #5

Geek-James opened this issue Jul 18, 2019 · 6 comments
Labels
JavaScript About JavaScript

Comments

@Geek-James
Copy link
Owner

Geek-James commented Jul 18, 2019

apply()

apply() 方法调用一个函数, 其具有一个指定的this值,以及作为一个数组(或类似数组的对象)提供的参数

语法:

fun.apply(thisArg, [argsArray])
  • thisArg:在 fun 函数运行时指定的 this 值。需要注意的是,指定的 this 值并不一定是该函数执行时真正的 this 值,如果这个函数处于非严格模式下,则指定为 null 或 undefined 时会自动指向全局对象(浏览器中就是window对象),同时值为原始值(数字,字符串,布尔值)的 this 会指向该原始值的自动包装对象。

  • argsArray:一个数组或者类数组对象,其中的数组元素将作为单独的参数传给 fun 函数。如果该参数的值为null 或 undefined,则表示不需要传入任何参数。从ECMAScript 5 开始可以使用类数组对象。浏览器兼容性请参阅本文底部内容。

apply 和 call 的区别

其实 apply 和 call 基本类似,他们的区别只是传入的参数不同。

语法:

fun.call(thisArg[, arg1[, arg2[, ...]]])

所以 apply 和 call 的区别是 call 方法接受的是若干个参数列表,而 apply 接收的是一个包含多个参数的数组。

    var a ={
        name : "Cherry",
        fn : function (a,b) {
            console.log( a + b)
        }
    }

    var b = a.fn;
    // 接受的是一个数组
    b.apply(a,[1,2])     // 3
    var a ={
        name : "Cherry",
        fn : function (a,b) {
            console.log( a + b)
        }
    }

    var b = a.fn;
    // 接受的是参数
    b.call(a,1,2)       // 3

bind 和 apply、call 区别

    var a ={
        name : "Cherry",
        fn : function (a,b) {
            console.log( a + b)
        }
    }

    var b = a.fn;
    b.bind(a,1,2)

以上code我们会发现并没有输出.

bind()方法创建一个新的函数, 当被调用时,将其this关键字设置为提供的值,在调用新函数时,在任何提供之前提供一个给定的参数序列。

所以我们可以看出,bind 是创建一个新的函数,我们必须要手动去调用:

    var a ={
        name : "Cherry",
        fn : function (a,b) {
            console.log( a + b)
        }
    }

    var b = a.fn;
    b.bind(a,1,2)()           // 3

一个面试经典问题:new 的过程了

伪代码

var a = new myFunction("Li","Cherry");

new myFunction{
    var obj = {};
    obj.__proto__ = myFunction.prototype;
    var result = myFunction.call(obj,"Li","Cherry");
    return typeof result === 'obj'? result : obj;
}
  • 1.创建一个空对象 obj;开辟一个新的内存空间
  • 2.将新创建的空对象的隐式原型指向其构造函数的显示原型。
  • 3.使用 call 改变 this 的指向,指向新开辟的内存空间
  • 4.如果无返回值或者返回一个非对象值,则将 obj 返回作为新对象;如果返回值是一个新对象的话那么直接直接返回该对象。
所以我们可以看到,在 new 的过程中,我们是使用 call 改变了 this 的指向。

运用场景

    // 实现继承
    function Animal(name) {
        this.name = name;
        this.showName = function () {
            console.log(this.name);
        }
    }
    function Cat(name) {
        Animal.call(this, name);
    }
    var cat = new Cat('black cat');

    console.dir(Cat)

    cat.showName();

    // 数组追加
    var array1 = [1, 2, 3, 4, 5];
    var array2 = ['ss','dd','adf','iu'];
    // 在谁的基础上进行增加
    Array.prototype.push.apply(array2,array1);
    console.log(array2);
    
    //获取数组中的最大值和最小值
    var num = [1,2,4,5,6,7,9];
    var maxNum = Math.max.apply(Math,num);
    var minNum = Math.min.apply(Math,num);
    
    console.log(maxNum);
    console.log(minNum);
    
    // 将伪数组转为数组
    var fakeArr = {0:'a',1:'b',2:'c',length:2};
    var arr1 = Array.prototype.slice.call(fakeArr);
    console.log(arr1[0]);
    var arr2 = [].slice.call(fakeArr);
    console.log(arr2[0]);
    arr1.push('c');
    console.log(arr1);

    //保存this变量
    var foo = {
        bar:1,
        eventBind:function () {
            var _this = this;
            $('.someClass').on('click',function (event) {
                console.log(_this.bar);
            });
        }
    }

    var foo = {
        bar:1,
        eventBind:function () {
            $('.someClass').on('click',function (event) {
                console.log(this.bar);
            }.bind(this))
        }
    }

总结 apply 、 call 、bind

  • 三者都是用来改变函数的this对象的指向的;

  • apply 、 call 、bind 三者第一个参数都是this要指向的对象,也就是想指定的上下文;

  • apply 、 call 、bind 三者都可以利用后续参数传参;

  • bind 是返回对应函数,便于稍后调用;apply 、call 则是立即调用 。
    参考网站

  • this、apply、call、bind

  • 深入浅出 妙用Javascript中apply、call、bind

@webzlj
Copy link

webzlj commented Jul 24, 2019

你好,再this的那边,你讲的是apply讲this指向新对象,这边说的是call呢

@Geek-James
Copy link
Owner Author

你好,再this的那边,你讲的是apply讲this指向新对象,这边说的是call呢

call和apply都可以改变this的指向,call改变this指向传入的是字符串对象,而apply传入的是数组对象☺️

@webzlj
Copy link

webzlj commented Jul 24, 2019

所以在new那边,改变this指向,两个方法都是可以的吗

@Geek-James
Copy link
Owner Author

所以在new那边,改变this指向,两个方法都是可以的吗

对是的,apply 和 call 的区别是 call 方法接受的是若干个参数列表,而 apply 接收的是一个包含多个参数的数组。本质上是改变this的指向,只不过区别在于传入的参数列表存在差别,如果传入的参数都不是数组,那么这两个方法是一样的效果。你可以尝试着用实例代码跑一遍。

@webzlj
Copy link

webzlj commented Jul 24, 2019

噢噢,知道了,非常感谢

@Geek-James
Copy link
Owner Author

噢噢,知道了,非常感谢

不客气😄加油🚀

@Geek-James Geek-James changed the title 5.call apply band 小结 5.call apply bind 小结 Jul 25, 2019
@Geek-James Geek-James added the JavaScript About JavaScript label Aug 27, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
JavaScript About JavaScript
Projects
None yet
Development

No branches or pull requests

2 participants