(0,eval)('this')在插件中的作用

阅读前需要了解:   

    ES5严格模式:‘use strict’

    eval的间接引用和直接引用

    逗号运算符的作用

    现在网上已经有很多的插件,他们不仅外观漂亮而且性能也好,插件再多也架不住产品的想法多,但是在开发过程中很多时候我们需要针对自己的项目,对一些常用的功能进行封装,这样大大提高了代码复用率。

    封装过程中会有这么一步,是把自己的函数暴露给当前作用于或者全局。

    一般推荐暴露给当前作用域,也就是this的指向。

;(function(){

    var fn = function(){......};//我自己的插件方法


    //暴露给全局作用域

    window.fn = fn;

    //或者是暴露给当前函数的外层作用域(推荐)

    this.fn = fn;

}());

逼格高一点的会在这个自执行函数IIF里面放一个,暂且不考虑window还是当前作用域。

!('myFn' in window) && (window.myFn = myFn);

这里的(‘myFn’ in Obj)方法是判断window下面有没有键为‘myFn’的方法,如果有则返回true。

为了提高插件中语法的严谨性好多人都在自执行函数内部或者局部使用严格模式"use strict";

;(function(){

    "use strict"

}());

严格模式的特点不在这里做过多的赘述,但是在这里有一点要清楚,

在严格模式下会抑制 this

举个例子:

;(function()

    "use strict";

    console.log(this)

})

//输出的结果为undefined

    说了这么多,我们今天的重点来了:如何解决这一问题,就需要我们的eval来获取当前上下文对象

    js 中 eval() 函数的作用就是讲函数内的参数当做代码来执行。

    比如eval('1+1')得到的值为2,然而如果直接打印‘1+1’他就是一个字符串,eval(‘this’)得到的就是this。

    很多插件中都有这句话(0,eval)('this')。这时候就涉及到了eval的直接引用和间接引用以及逗号表达式。逗号表达式是执行顺序等级最低的,如果(1,eval)会先执行逗号前面的式子(逗号前面也会当做一个表达式),最终会执行eval()。

    但是(0,eval)('this')和eval('this')同样是执行eval,但他们有什么区别呢,下面是间接引用和直接引用的方法。

间接引用

(1, eval)('...')

(eval, eval)('...')

(1 ? eval : 0)('...')

(__ = eval)('...')vare = eval; e('...')

(function(e) { e('...') })(eval)

(function(e) {returne })(eval)('...')

(function() { arguments[0]('...') })(eval)this.eval('...')this['eval']('...')

[eval][0]('...')

eval.call(this, '...')

eval('eval')('...')

直接引用

eval('...')

(eval)('...')

(((eval)))('...')

(function() { return eval('...') })()

eval('eval("...")')

(function(eval) { return eval('...'); })(eval)

with({ eval: eval })eval('...')

with(window) eval('...')

    通过上面大致看一眼,我们可以理解,间接引用大部分都是表达式,表达式计算出来的是一个值,而直接引用就是一个引用,个人理解由于在严格模式下对this的引用是有限制的,所以如果转换成了值就可以直接获取到正确的this指向了。(如果异议请留下您的宝贵意见)

    所以我们需要间接引用eval来获取准确的this指向,才可以将他暴露给当前函数的作用域。

    (0,eval)('this')不管逗号前面是什么数字,都可以。

    所以,逼格再高一点的会在这个自执行函数IIF里面放

;(function(){

    'use strict'                                                                                          //设置为严格模式

    var myFn = function(){......};                                                              //我的插件方法

    _global = (function(){ return this || (0, eval)('this'); }());                    //查找当前作用域,也就是this的指向,也就是找到顶层对象;这里不了解的可以查看阮一峰老师的《 ECMAScript 6 入门 》第一章,“global对象 ”

    !('myFn' in _global) && (_global.myFn = myFn);                            //暴露

}())




    逗号表达式问题扩展:

   如何不通过第三个变量来改变ab两个变量的值?

var a = 'a' , b = 'b';

a = [b,b=a][0]

console.log(a,b)//打印出b,a

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • "use strict";function _classCallCheck(e,t){if(!(e instanc...
    久些阅读 6,253评论 0 2
  • @转自GitHub 介绍js的基本数据类型。Undefined、Null、Boolean、Number、Strin...
    YT_Zou阅读 5,002评论 0 0
  • 前端开发面试题 <a name='preface'>前言</a> 只看问题点这里 看全部问题和答案点这里 本文由我...
    自you是敏感词阅读 4,292评论 0 3
  • 在你最悲观最失望的时候,那正是你必须鼓起坚强的信心的时候。 你们现在要离开母校了,我没有什么礼物送给你们,只好送你...
    孚光阅读 3,649评论 0 0
  • 开车去景区要经过一长段山区公路。山路弯弯,双向只有两车道。路面狭窄,时不时的交汇车必须聚精会神。 在返程时,突然从...
    Nunu0077阅读 2,707评论 0 0

友情链接更多精彩内容