前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >关于Function.prototype.apply.call的一些补充

关于Function.prototype.apply.call的一些补充

作者头像
空空云
发布2018-09-27 11:47:44
7880
发布2018-09-27 11:47:44
举报
文章被收录于专栏:大前端_Web大前端_Web

宿主对象,在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)

代码语言:javascript
复制
//摘自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不是说尽量不要用么,还是算了吧!!)

代码语言:javascript
复制
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什么时候用,就是在这种应用场景。

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

代码语言:javascript
复制
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
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017年02月24日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档