zoukankan      html  css  js  c++  java
  • JS中的bind 、call 、apply



    # 一 、bind 特点: ### 1.返回原函数的拷贝,我们称这个拷贝的函数为绑定函数 ### 2.将函数中的this固定为调用bind方法时的第一个参数,所以称之为绑定函数。注意是名词而非动词。 ### 3.以后无论由哪个对象调用绑定函数,绑定函数中的this依然由当时调用的bind方法的一个参数决定,不会改变。 ### 4.如果绑定函数作为构造函数来使用,那么已经固定了的this将不会生效,此时构造函数中的this依然为实例对象。 ### 5.调用bind方法时的第二个参数做为绑定函数的第一个参数,称之为预设参数,调用绑定函数时的第一个参数则排在预设参数后面 ### 6.无论使用任何对象调用bind方法时如果不传参数、第一个参数为undefined、第一个参数为null时,绑定函数中的this指向window对象
    作用: ### 1.拷贝一个目标函数 ### 2.改变绑定函数运行时的this指针
    1-1 证明是原函数的拷贝 (需要知道:函数也是对象,并且是引用类型,比较的是内存地址) ``` function fn(){}

    var bindFn = fn.bind(); //ƒ fn(){ return this } 供以后调用

    fn === bindFn //false

    <br>
    <br>
    2-1    将函数中的this固定为调用bind方法时的第一个参数
    

    function fn(){ return this }

    var bindFn = fn.bind({name:"绑定函数"}) //ƒ fn(){ return this }

    <br>
    <br>
    3-1    以后无论由哪个对象调用绑定函数,绑定函数中的this依然是{name:"绑定函数"}
    

    function fn(){ console.log(this) }

    var bindFn = fn.bind({name:"绑定函数"})

    bindFn() //等同于window对象调用 , this依然指向{name:"绑定函数"}

    var obj = {name:"obj"};
    obj.fn = bindFn;
    obj.fn() //由普通对象调用 ,this依然指向{name:"绑定函数"}

    var arr = [bindFn];
    arr0 //由数组调用 , this依然指向{name:"绑定函数"}

    setTimeout(bindFn , 200); //作为回调函数 , this依然指向{name:"绑定函数"}
    clearTimeout(1);

    <br>
    <br>
    4-1    如果绑定函数作为构造函数,已经捆绑的this会被忽略掉,this依然指向实例对象
    

    function Person(name){
    this.name = name;
    }

    var bindPerson = Person.bind({name:"绑定函数"})

    new bindPerson("张三") // Person {name: "张三"}

    <br>
    <br>
    5-1    预设参数
    

    function fn(a,b,c,d){
    console.log(a,b,c,d) // 1 ,2 ,3 ,4
    }

    var bindFn = fn.bind({name:"绑定函数"} , 1 ,2); // 拷贝原函数时的第2个参数开始往后称为预设参数

    bindFn(3,4); //调用绑定函数时的第一参数则排在预设参数的后面

    <br>
    <br>
    6-1    当没有参数、第一个参数为undefined、第一个参数为null时
    

    var obj = {
    fnOne:function(){ return this }.bind(),
    fnTwo:function(){ return this }.bind( undefined ),
    fnThree:function(){ return this }.bind( null )
    }
    //注意:这三种情况是使this指向window对象,而不是不去改变this指向,所以这里的this还是不会指向obj
    obj.fnOne() // window
    obj.fnTwo() //window
    obj.fnThree() //window

    <br>
    <br>
    <br>
    #  二、call           
    特点:
    ### 1.返回值取决于目标函数的返回值
    ### 2.用call的第一个参数对象来代替调用目标函数的对象,以此来改变目标函数体内的this指向
    ### 3.调用call方法时的第二个参数做为目标函数的第一个参数,将第二个作为第三个以此类推
    <br>
    作用:
    ### 1.用于继承,例如子构造函数继承父构造函数
    ### 2.改变绑定函数运行时的this指针。
    <br>
    1-1    返回值取决于目标函数的返回值
    

    function fn(){ return {name:"call"} }

    fn.call() // {name: "call"}

    <br>
    <br>
    2-1    改变目标函数体内的this指向 , 相当于使用第一个参数对象调用
    

    function fn(){ return this }

    fn.call( { name : "call" } ) // {name: "call"}

    <br>
    <br>
    3-1    参数位置
    

    function fn(a, b, c){ return arguments }

    fn.call( { name : "call" } , 1 , 2 , 3 ) //Arguments [1, 2, 3]

    <br>
    <br>
    1-2    用于继承
    

    function parent(name, age) {
    this.name = name;
    this.age= age;
    }

    function child(name, age) {
    parent.call(this, name, age);
    this.class = '三年级二班';
    }

    var xiaoming = new child("小明" , 18)

    <br>
    <br>
    <br>
    #  三、apply
    特点:
    ### 1.与call方法一样唯一不同的地方就是apply的第二个参数是一个数组,数组的第一个元素对应目标函数的第一个参数,以此类推
    <br>
    作用:
    ### 1.与call方法一样
    <br>
    1-1    参数
    

    function fn(a, b, c){ return a+b+c }

    fn.apply({name:"apply"} ,[1,2,3]) //6

    <br>
    <br>
    <br>
    ## 总结
    ### 相同点
    ####1. 3个方法都是改变绑定函数运行时的上下文
    ### 不同点
    ####1.bind方法的返回值是原函数的拷贝,供以后调用 。参数既可以在拷贝时预设又可在调用时添加
    ####2.call与apply一样,返回值取决于目标函数的返回值 , 则是立即调用
    ####3.call与apply唯一的区别是call从第二个参数开始是若干个参数,而apply第二个参数是一个数组
  • 相关阅读:
    Redis源码阅读笔记(2)——字典(Map)实现原理
    Partition List ——LeetCode
    docker format (golang template)
    markdown 换行
    pecan快速教程
    nvdimm
    k8s device plugin
    linux 文件同步
    复制MIFARE Classic卡
    install docker swarm on centos
  • 原文地址:https://www.cnblogs.com/liu-di/p/10690335.html
Copyright © 2011-2022 走看看