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



  • 相关阅读:
    你的服务器和网站为什么会被反复入侵
    MAC 查看当前安装的JDK位置
    Jmeter高并发测试
    解密AndroidManifest.xml、AXMLPrinter2.jar源码下载
    Win10家庭版如何启用本地组策略
    SQLFlow使用中的注意事项--设置篇
    Sqlflow 之隐私政策(Privacy plolicy)介绍
    血缘关系分析工具SQLFLOW--实践指南
    Oracle SQL 性能优化利器
    SQLFlow数据流分析工具的job功能介绍
  • 原文地址:https://www.cnblogs.com/qianlegeqian/p/4786766.html
Copyright © 2011-2022 走看看