• call、apply、bind的实现


    一、如何使用

    this的四种指向:this 永远指向最后调用它的那个对象!!!

    1、普通函数调用,指向window --- 如果是严格模式,指向undefined
    function thisPoint() {
        console.log(this);
    }
    thisPoint(); //window
    
    function thisPointStrict() {
        'use strict'
        console.log(this);
    }
    thisPointStrict(); //undefined
    2、当this被obj.fn()调用时,指向obj.
    var obj = {
        name: '测试this指向的类名字',
        fn() {
            console.log(this);
        }
    }
    obj.fn(); // obj 对象
    3、call 改变this 的指向
    function a(a, b, c) {
        name: 'a的名字';
        console.log(this.name);
        console.log(a, b, c);
    }
    var b = {
        name: 'b的名字'
    }
    a.call(b, 1, 2, 3); //b的名字  1 2 3
    4、apply改变this的指向
    a.apply(b, [1, 2, 3]) //b的名字  1 2 3

    总结 call和apply

    相同点:
      1、都是改变this指向的
    使用区别:
      1、call 第一个参数是this指向的对象,后边是参数列表
      2、apply 第一个参数是this指向的对象,后边是参数数

    5、bind改变this指向
      bind会生成并且返回一个函数,这个函数的this指向第一个参数。
    var c = a.bind(b, 1, 2, 3);
    c(); //b的名字  1 2 3

     二、实现

    1、call实现code

    Function.prototype.mycall = function(context, ...arg) {
        const fn = Symbol('临时属性');
        context[fn] = this;
        context[fn](...arg);
        delete context[fn];
        }
        //思路:
        // 1、通过对象属性的方式调用函数,这个函数里面的this指向这个对象。
        // 每次调用新增一个symbol属性,调用完毕删除。
        // 这个symbol属性就是调用mycall方法的函数
        //函数形参中使用 ...arg 是将多个形参塞到一个数组里面,在函数内部使用arg这个变量时,就是包含所以形参。
        // 在调用context[fn](...arg) 时候,...arg是为了展开数组,依次传入参数调用函数。
    var obj = {
        name: '测试的obj的名字'
    }
    
    function test(a, b, c) {
        console.log(this.name);
        console.log(a, b, c);
    }
    test.mycall(obj, 1, 2, 3)

    2、apply实现code

    Function.prototype.myApply = function(context, arg) {
        const fn = Symbol('属性');
        context[fn] = this;
        context[fn](...arg);
        delete context[fn]
    }
    
    const obj2 = {
        name: '测试Obj2的名字'
    }
    
    function test(a, b, c) {
        console.log(this.name);
        console.log(a, b, c);
    }
    
    test.myApply(obj2, [2, 3, 4])
    
    //总结 :
    // call 是传参的列表,所以一开始需要...arg; apply 是传参数组,不需要...arg

    3、bind实现code

    var obj = {
        name: '我是obj的名字'
    }
    
    function test(a, b, c) {
        name: '我是test的名字';
        console.log(this.name);
        console.log(a, b, c);
    }
    // bind跟call和apply的区别: bind返回一个新的函数,并且不会调用。  call和apply会改变原函数的this指向,并且调用
    Function.prototype.myBind = function(objThis, ...params) {
        const _this = this;
        let fToBind = function(...secoundarg) {
            const isNew = this instanceof fToBind;
            const context = isNew ? this : Object(objThis);
            return _this.call(context, ...params, ...secoundarg);
        }
        fToBind.prototype = Object.create(_this.prototype);
        return fToBind;
    }
    var fnbind = test.myBind(obj, 2, 3, 4)
    fnbind()
  • 相关阅读:
    TDateTime 的相关用法
    Delphi 2005 之后的版本如何装组件
    (收藏)《博客园精华集》分类索引
    用 IIS 7、ARR 與 Velocity 建设高性能的大型网站
    异常处理准则
    Linq之动态排序(字符传入)
    用存储过程构造一个虚拟日期表发现的趣事
    Linq to SQL 加注Data Annotation在 Asp.Net MVC2中的应用
    .net framework加密方法
    SQL Server到Oracle连接服务器
  • 原文地址:https://www.cnblogs.com/qianqiang0703/p/14885548.html
Copyright © 2020-2023  润新知