zoukankan      html  css  js  c++  java
  • 关于Function.prototype.apply.call的一些补充

    宿主对象,在javascript中有三类对象,本地对象,内置对象和宿主对象。其他两类暂且不提,宿主对象是指什么呢(DOM BOM),控制台对象是文档对象模型的扩展,也被认为是宿主对象。那么,它们有什么缺陷呢?在IE9之前,宿主对象不是继承自Object,它们的方法也不继承自Function,IE9之后就大有改进了。

      看下IE8与IE9的document.getElementById

    ie8:

    ie9:

    我们可以看到,ie9的document.getElementById是有Function.prototype上的方法的,所以说,IE9+的宿主对象它们继承了Object,方法继承了Function。

    IE8不支持call,所以问题就来了,我们经常会有这样的需求,比如,重新控制台。

    很多人想到了console.log.call,但是它不完美,现在你们知道了~~

    好,想想解决办法吧:

    1、使用Function.prototype.bind,但是...你得为不支持bind的浏览器做兼容

    Function.prototype.bind.call(console.log,console).apply(console,arguments)
    //摘自MDN
    if (!Function.prototype.bind) {
      Function.prototype.bind = function (oThis) {
        if (typeof this !== "function") {
          // closest thing possible to the ECMAScript 5 internal IsCallable function
          throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
        }
    
        var aArgs = Array.prototype.slice.call(arguments, 1), 
            fToBind = this, 
            fNOP = function () {},
            fBound = function () {
              return fToBind.apply(this instanceof fNOP && oThis
                                     ? this
                                     : oThis || window,
                                   aArgs.concat(Array.prototype.slice.call(arguments)));
            };
    
        fNOP.prototype = this.prototype;
        fBound.prototype = new fNOP();
    
        return fBound;
      };
    }

    2、new Function+replace (new Function不是说尽量不要用么,还是算了吧!!)

    function log(){
    
        var fn = 'console.log(args)',
    
        args=[].slice.call(arguments);
    
     
    
        fn = new Function('args',fn.replace(/args/,args.join(',')));
    
        fn(arguments);
    
    };

    3、终极方法

    Function.prototype.apply.call(console.log,console,arguments);

    这么一对比,第三种方案妥妥的胜出啊,不用考虑兼容,代码简短,虽然不是很好理解~~

    说了这么多废话,Function.prototype.apply.call什么时候用,就是在这种应用场景。

    如果还有其他的话,那就是那些奇葩面试题,比如:

    var f1=function(){console.log(1)};
    var f2=function(){console.log(2)};
    Function.prototype.call.call(Function.prototype.call,f2)//2
    Function.prototype.call.call(f1,f2);//1



  • 相关阅读:
    通过登入IP记录Linux所有用户登录所操作的日志
    PHP写的异步高并发服务器,基于libevent
    PHP event 事件机制
    PHP高级工程师的要求
    TBS 手册 --phpv 翻译
    两局域网互联解决方案
    比ngx_http_substitutions_filter_module 更强大的替换模块sregex的replace-filter-nginx-module
    直播平台虚拟币与人民币的关系
    查询出来的东西异步缓存
    如何解决GBK的编码的文件中的中文转换成为UTF-8编码的文件而且不乱码
  • 原文地址:https://www.cnblogs.com/qianlegeqian/p/4786766.html
Copyright © 2011-2022 走看看