• javascript函数篇四、函数的属性和方法——apply()、call()和bind()方法区别


    > 本篇文章的内容:
    > 函数的属性:length、prototypy、caller;
    > 函数的方法: apply()、call()、bind()

    因为在javascript中函数也是对象,所以函数也有属性和方法。每个函数都包含三个属性。

    length

    function fn (n1, n2) {
        return n1 + n2
    }
    console.log(fn.length) // 2
    

    **length属性表示函数希望接收的函数个数。**

    prototypy
    每一个函数都有一个prototype属性,它是一个对象,prototype是一个极其重要的属性,这里只做一个简单罗列,以后会详细介绍。

    caller
    ECMAScript5还规范化了一个函数对象的属性,就是caller,它指向的是调用当前函数的函数的引用,如果是在全局作用域中调用当前函数,它的值为null。

    function a () {
        b()
    }
    function b () {
        console.log(b.caller) // 打印a函数的源代码
    }
    a()

    注意当函数在严格模式下执行的时候会导致错误!

    每个函数都包含两个方法:apply()和call(),另外在ECMAScript5中还定义了一个方法bind()。下面来介绍这三个方法。

    apply()、call()、bind()
    1、apply()和call()
    首先apply()和call()的作用都是改变函数执行的上下文,也就是this值。每个函数都有这两个方法,它们的第一个参数都是你要指定的上下文,第二参数就是传递的参数。

    var obj = {
        a: 1
    }
    function add (b, c) {
        return this.a + b + c
    }
    console.log(add.apply(obj, [1, 2])) // 4
    console.log(add.call(obj, 3, 4)) // 8

    apply()和call()两种方法的区别仅仅在于传参方式,apply要以数组的形式传参,call则需要一一传入。

    2、与call和apply不同,bind()不会立即执行
    ***bind()在使用的时候,调用bind()方法的函数不会立即执行,而是返回一个改变了上下文的函数副本(即重新创建了一个函数,然后将this指向bind函数的第一个参数,最后将这个新创建的函数返回)***

    bind()方法是如何实现的呢?为了更好的理解bind方法我们来模拟一下bind方法的实现:

    if (!function(){}.bind) { // 如果没有bind方法则向Function对象的原型中添加自定义的bind方法,因为有的浏览器(如ie6~ie8)并不支持bind,所以若想在多个浏览器中使用bind可以这样做兼容处理
        Function.prototype.bind = function(cnt) {
            var fn = this // 获取调用bind方法的函数
            var args = Array.prototype.slice.call(arguments) // 这里是将bind方法内的arguments对象转为数组,以便arguments能使用数组的方法
                return function () { //返回一个函数, 而这个函数的内部是执行调用bind()的函数,并将执行的结果返回
                    return fn.apply(cnt, args.slice(1))
                }
           }
    }    

    通过模拟bind()可以清晰的看到bind方法的实现原理,为了好理解假设有如下调用:fn.bind(obj, a, b):
    在bind函数的内部是这样操作的,首先通过this拿到调用bind方法的函数fn利用arguments对象处理传入bind方法的参数,拿到除第一个参数以外的参数(这里的a,b)。整个bind方法返回一个函数,函数内部执行调用bind方法的函数fn,并利用apply方法将fn的this指向传入bind函数的第一参数(obj),并将fn执行结果返回

    利用bind()方法不会立即执行的特点,我们可以在一些交互的时间处理函数中使用bind()。

    var btn = document.getElementById("btn")
    var lines = document.getElementById("lines")
    btn.onclick = function() {
        console.log(this.id) // lines
    }.bind(lines) // 此时处理函数不会立即执行,当点击事件触发时,bind()返回的函数副本执行,返回了fn.apply(cnt, args.slice(1)); apply立即执行

    调用了bind方法的点击事件处理函数不会立即执行,当点击事件触发时,bind()返回的函数副本执行,这时候返回了fn.apply(cnt, args.slice(1)); apply立即执行处理函数,同时改变了this指向,输出结果为lines。

  • 相关阅读:
    倒下
    我还能相信谁

    工作这点事
    人,这东西
    祝福
    路,公车和鞋子
    那片海
    document.querySelector bug All In One
    js logical or assignment bug All In One
  • 原文地址:https://www.cnblogs.com/youyang-2018/p/11706522.html
Copyright © 2020-2023  润新知