`
yiminghe
  • 浏览: 1460283 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

with eval and this

阅读更多

witheval 已经够麻烦了,被归到 bad parts 后总算减轻点负担,但如果确实使用了 eval,则要考虑下 this 是否受到影响. 


this:


google 代码规范 中提及到 this 的指向有5种情况:


1.大多数情况指向全局对象,在浏览器环境下就是 window

2.在 eval  中指向 the scope of the caller

3.在 dom1 事件绑定中指向绑定的元素,dom2 标准浏览器也是。

4.在apply,call调用下指向参数

5. 构造器中指向新生成对象


eval :


特别是 2 ,其实这里需要仔细说下,应该不是直接指向调用者所用域,而是和调用者作用域中存在的 this 相同才是。


当在函数中直接 eval 时:

 

function x(){
   eval("console.log(this)");
}

x();

x.apply({y:1});

 

根据规范解释:eval 中的 this 和 caller 调用者的 this 相同,上面即相当于,直接:

 

function x(){
  console.log(this);
}

 

但是有点需要注意的是,当间接使用 eval 时,情况就不一样了 :

 

var y=eval;
function x(){
   y("console.log(this)");
}

x();

x.apply({y:1});


在 webkit 下 this 都指向全局对象 window,而 firefox 则和直接使用 eval 一样,但同时两者在别名情况下执行代码串都丢失了作用域链的信息(这也正是这种写法的主要应用场景,脱离作用域链 )。

 

不过 IE 却又和 webkit,firefox 有区别,当使用别名 eval 时,这时和直接使用 eval 完全没有区别,作用域链仍然在,this 依然和调用者保持一致,怪异。

 

这种情况的解释目前尚未找到正式描述。

 

 

建议是不要使用直接别名引用,可以 work around by this :

 

function foo(v){
    eval(v)
}
 

但是这里又有点需要注意的地方,v 参数里面不要再引用到 v,否则引用到自身代码打印出来

 

function foo(v){
    eval(v)
}

var v=1;

//woo! surprise
foo("alert(v);");

 

 

所以最好还是使用 new Function 来执行吧:

 

var v=1;
new Function("alert(this.v);").call({v:2});
 

若不使用 call 以及 apply ,this 始终指向 window ,作用域链丢失。

 

 

 

终极混合测试:


终极就要达到茴字有几种写法的效果:

 var v='outer_v',foo=eval,
    foo2=function(v2){
        eval(v2);
    },
    x='outer_x';

    
(function (context,fn) {
    with (context) {
       foo2("("+fn+").call(this);"); 
       foo("("+fn+").call(this);");
       eval("("+fn+").call(this);");
       new Function("("+fn+").call(this);")();
    } 
}).call({x:'this_x'},{ v: 'inner_v' }, function () { alert(v);alert(this.x); });
   

 

 

 

 

分享到:
评论

相关推荐

    JSON2.JS JSON.JS JSON_PARSE.JS

    cycle.js: This file contains two functions, JSON.decycle and JSON.retrocycle, which make it possible to encode cyclical structures and dags in JSON, and to then recover them. JSONPath is used to ...

    Keil.STM32F3xx_DFP.2.1.0.pack

    This DFP works either with STM32CubeMX (STM32CubeMX V4.23.0 and STM32Cube_FW_F3 V1.9.0 or higher) or Standalone (no support for STM32CubeMX). STM32CubeMX is mandatory for use of CMSIS-Driver and MDK-...

    Core Java Volume I Fundamentals, 11th Edition

    You’ll learn how to use JShell’s new Read-Eval-Print Loop (REPL) for more rapid and exploratory development, and apply key improvements to the Process API, contended locking, logging, and ...

    Keil.STM32F3xx_DFP.2.1.0.pack(官方STM32F3xx系列最新固件库for Keil MDK 5)

    This DFP works either with STM32CubeMX (STM32CubeMX V4.23.0 and STM32Cube_FW_F3 V1.9.0 or higher) or Standalone (no support for STM32CubeMX). STM32CubeMX is mandatory for use of CMSIS-Driver and MDK-...

    Professional.Clojure.1119267277

    The discussion details the read—eval—print workflow that enables fast feedback loops, then dives into enterprise-level Clojure development with expert guidance on web services, testing, datomics, ...

    Chinese Entity Linking Comprehensive

    This package contains all evaluation and training data developed in support of TAC KBP Chinese Entity Linking during the four years since the task's inception in 2011. This includes queries, KB ...

    Python4DelphiPart-1-7139726.pdf

    - **Creating Python Extension Modules with Delphi Classes and Functions**: Developers can create Python extension modules using Delphi classes and functions, enabling the creation of custom Python ...

    TeeChart2018ActiveX_0_2_9Eval3264

    This had caused an import problem with the earlier releases of Visual Studio .NET. As a precaution we have chosen to rename the parameter to 'MoreValues' for the TeeChart Pro ActiveX Control. ...

    csapp-shell-labcsapp-shell-labcsapp-shell-lab

    1. **eval**: This is the main routine that parses and interprets the command line. [Approx. 70 lines] 2. **builtincmd**: This function recognizes and interprets built-in commands such as `quit`, `fg`,...

    Java - The Well-Grounded Java Developer

    - **Lisp Features**: Discussion on Clojure's Lisp heritage, including macros and the REPL (read-eval-print loop), which enable rapid prototyping and experimentation. #### PART 4: CRAFTING THE ...

    mvel 2.0.15

    MVEL supports that too, and there is both and easy way and a more advanced way (dealing with resolvers – which we won't get to here). The easy way simply involves passing in a Map of variables ...

    Java in easy steps: Covers Java 9, 6th Edition - epub格式

    By the end of this book you will have gained a sound understanding of the Java language and be able to write your own Java programs and compile them into executable files that can be run on any Java-...

    ehlib_vcl_src_9_3.26

    with a scrollable list and can display and edit a field in a dataset or can works as non data-aware combo edit control. TDBNumberEditEh component represents a single-line number edit control that ...

    EhLib 9.1.024

    with a scrollable list and can display and edit a field in a dataset or can works as non data-aware combo edit control. TDBNumberEditEh component represents a single-line number edit control that ...

    Loving Lisp

    - **Interactive Development**: Lisp’s REPL (Read-Eval-Print Loop) enables interactive development, allowing for immediate feedback and rapid prototyping. - **Code-as-Data**: In Lisp, code is treated ...

    js的日历时间控件

    with(this.options){if(isNaN(firstWeekDay*1)){firstWeekDay=0}else{firstWeekDay=firstWeekDay%7}}this.keysCaptured=false;this.calendarCont=null;this.currentDate=this.options.date?this.options.date:new ...

    EhLib5.0.13 最新的ehlib源码

    with a scrollable list and can display and edit a field in a dataset or can works as non data-aware combo edit control. TDBNumberEditEh component represents a single-line number edit control that ...

    EhLib 6.3 Build 6.3.176 Russian version. Full source included.

    with a scrollable list and can display and edit a field in a dataset or can works as non data-aware combo edit control. TDBNumberEditEh component represents a single-line number edit control that ...

Global site tag (gtag.js) - Google Analytics