zoukankan      html  css  js  c++  java
  • JavaScript this

    this用的很多,react 的class component用了这么多自己也比较熟悉的了,下面就来讲讲如何判断一个this的绑定以及call、apply、bind的实现。

    判断this绑定

    主要就是以下的几点:

    1. 由new调用:绑定到新创建的对象上面。在类里面的contructor中,指向将要通过构造器创建的对象。
    2. 由call、apply、bind来调用,绑定到指定的对象上面。
    3. 由上下文对象调用,就绑定到上下文的对象上面。
    4. 默认:全局对象,node为global,浏览器为window

    如何实现call

    Function.prototype.call = function(context) {
      var context = Object(context) || window;
      // call是由一个函数调用的,此时this就指向该函数
      context.fn = this;
      var args = [];
      for(let i = 1; i < arguments.length; i++) {
        args.push('arguments[' + i + ']');
      }
      var res = eval('context.fn(' + args + ')');	
      delete context.fn;
      return res;
    }
    
    var obj = {
      a: 1
    }
    
    function print() {
      console.log(this.a)
    }
    print.call(obj);
    

    如何实现apply

    apply与call的最大区别就是,apply仅有第二个参数apply(obj, arguments),且arguments为一个数组,数组里面存放了要传递给调用call方法的函数的参数

    而call则一个一个的接收参数call(obj, argument1, argument2, argument3, ... argumentn)

    Function.prototype.apply = function(context, arr) {
      var context = Object(context) || window;
      context.fn = this;
      var res;
      if(!arr) {
        res = context.fn();
      } else {
        var args = [];
        for(let i = 0; i < arr.length; i++) {
          args.push('arr[' + i + ']');
        }
        res = eval('context.fn(' + args + ')');
      }
      delete context.fn;
      return res;
    }
    
    var obj = {
      a: 1
    }
    function bar(b, c) {
      return {
        a: this.a,
        b: b,
        c: c
      }
    }
    bar.apply(obj, [2,3])
    

    如何实现bind

    Function.prototype.bind = function(context) {
      if(typeof this !== "function") {
        throw new Error("Function.prototype.bind - what is trying to be bound is not callable");
      }
      var self = this;
      var args = Array.prototype.call(arguments, 1);
      var fNOP = function() {};
      var fBound = function() {
        self.apply(this instanceof self ? this :context, args.concat(Array.prototype.slice.call(arguments)));
      }
      fNOP.prototype = this.prototype;
      fbound.prototype = new fNOP();
      return bound;
    }
    
  • 相关阅读:
    Centos7 下 PHP 添加缺少的组件 sockets 和 openssl
    vue使用 video.js动态切换视频源视频源不刷新问题
    vue+js清除定时器
    获取ip地址,并根据ip获取当前省份
    html页面引用video.js播放m3u8格式视频
    uniapp每隔几秒执行一下网络请求(h5端亲测可以,其他端未测试)
    关于uniapp获取当前距离屏幕顶部的距离
    按值传递与按值引用详解(java版)
    JavaScript的深入理解(1)
    vue-cli3配置webpack-bundle-analyzer插件
  • 原文地址:https://www.cnblogs.com/ssaylo/p/13928993.html
Copyright © 2011-2022 走看看