Eval函数大家都很熟悉,但是globalEval方法却很少使用,大多数参考手册也没有相关api,下面就对其用法和源码相应介绍:

jQuery.globalEval()函数用于全局性地执行一段JavaScript代码。

示例:

var name = "全局变量";

function test(){
var name = "局部变量"; alert(name); // 局部变量 eval( "alert(name);" ); // 局部变量 $.globalEval( "alert(name);" ); // 全局变量
} test();

可以看到该方法跟eval方法相比有一个作用域的范围差异即始终处于全局作用域下面,下面进行源码分析:

// Evaluates a script in a global context
// Workarounds based on findings by Jim Driscoll
// http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
globalEval: function( data ) {
if ( data && rnotwhite.test( data ) ) {
// We use execScript on Internet Explorer
// We use an anonymous function so that context is window
// rather than jQuery in Firefox
( window.execScript || function( data ) {
window[ "eval" ].call( window, data );
} )( data );
}
},

注释里的意思是提到了此方法的实现是在Jim Driscoll的基础之上的而且把相关的文章链接还附了上面,索性链接还可以打开瞅瞅,里面大致介绍了怎么让js代码在全局执行的方法,对于ie浏览器而言则提供了一个不太常用的方法(反正我是第一次听到)---window.execScript

window.execScript 方法会根据提供的脚本语言执行一段脚本代码。window.execScript 方法有两个参数,第一个参数指定被执行的脚本代码段,第二个参数指定脚本代码语言类别 (缺省值为 JScript),execScript 方法执行后的代码位于全局作用域下。举例:

 var str='全局';
(function(){
var str='局部';
window.execScript('alert(str)'); //ie 全局
}());

但是此方法现在只有ie支持,早期的chrome版本也支持现在已经放弃,具体的此方法介绍请参考http://ued.sina.com/?p=789;

打开注释中的网址是一个英文网站四级英语水品的我毫不犹豫的使用了谷歌网页翻译功能,可以谷歌不给力告诉我无法翻译,那没办法只能硬着头皮读下去,怕译错把原文附上请以原文为准

For more standards-respecting browsers, the way to do this should be to use the call function, which is a standard function attached to every Function object. So, eval.call(window, src) should work. But to understand why, it's important to know about context, in addition to scope. Every function call has it's own context: this is the object that's represented by the special value this. When we use the call function, the first parameter is the context object we'll use for this. This is handy for all kinds of purposes, but for us, it's just nice to use to set the context to the window object - which, you'll recall, is the global.

这段是提供解决方法的,对于标准浏览器而言可以采用eval函数解析js代码字符串,然后通过对象冒充的方式把作用域指向window,下面就是自己的测试:

var str='全局';
(function(){
var str='局部';
eval.call(window, "alert(str)");
}());

经过测试ie9及以上和非ie均弹出“全局“ ,ie9以下弹出局部,说明这个方法有见兼容性有问题啊,但是这个方法本来就是给非IE用的,你ie爱咋咋地吧

Sadly, eval.call(window,src) breaks on Chrome - it complains about contexts not matching. Odd - and I was unable to Google up why this might be so. But a couple lucky guesses later, and I discovered that window.eval.call(window,src) works on all non-IE browsers. Now, when I say "var j = 1", the window[j] is the variable that's set... So, that's good. Why do we have to add the extra window. on Chrome? Not sure - I could guess, but it's too likely to be wrong.

该文作者用了多次用了”odd“,我也觉得很”odd",作者说在谷歌中报错了,然后把代码修改为window.eval.call(window,src)就可以啦,正如作者所困惑的,全局方法是不需要加window直接调用的这个大家都清楚,但是我做检测的时候是没有出现问题的,应该是年代久远了谷歌已经解决了,最后作者还提到火狐在执行解析this存在问题

At this point, I thought we'd licked the problem. No such luck. Sure, global variables are getting set, but it turns out that if you say: alert(this) - then you would correctly receive the global object back on Chrome and Safari, but not Firefox - there, you'd get back the object that was the enclosing object before the call function got called. Very odd, and likely a bug in their implementation.

既然全局解析alert(this)肯定是window才对,而火狐弹出最近的作用链的对象,对于需要测试下,代码如下:

 var str='全局';
(function(){
var str='局部';
window.eval.call(window, "alert(this)");
}());

经检测火狐没有问题,估计火狐也是早把这个问题处理了,在文章的最后作者留了一个方法

var globalEval = function globalEval(src) {
if (window.execScript) {
window.execScript(src);
return;
}
var fn = function() {
window.eval.call(window,src);
};
fn();
};

可以说这个方法已经够用了,但是回过头来看看我们的jQuery源码会发现精简了很多

data && rnotwhite.test( data )

该条件保证有数据而且是不带空格的数据,当然你也可以不传字符串但是没什么意义rnotwhite的定义在构造函数中

// Check if a string has a non-whitespace character in it
rnotwhite = /\S/,

至于为什么要检测不能有空格还是这篇外文中有其他开发者指出了如果是空白的在ie8出现错误

by vesperaba - 2012-10-18 08:54
If src is a blank string you will get an error in IE8. To avoid that I added the following check at the beginning: if (src == undefined || src == '') {
return;
} //The whole function will be:
var globalEval = function globalEval(src) {
if (src == undefined || src == '') {
return;
}
if (window.execScript) {
window.execScript(src);
return;
}
var fn = function() {
window.eval.call(window,src);
};
fn();
};

通过逻辑或运算来选择何种方式解析,如果是采用eval则是处在一个自执行的匿名函数中,结构很精简

( window.execScript || function( data ) {
window[ "eval" ].call( window, data );
} )( data );

另需注意的事该方法没有返回值,或者可以理解为返回undefined

jQuery静态方法globalEval使用和源码分析的更多相关文章

  1. jQuery静态方法parseXML使用和源码分析

    jQuery.parseXML( data ) 接受一个格式良好的 XML 字符串,返回解析后的 XML 文档. 方法 jQuery.parseXML() 使用浏览器原生的 XML 解析函数实现. 在 ...

  2. jQuery静态方法type使用和源码分析

    jQuery.type方法是检测数据类型的工具方法,在分析其用法之前先总结下js给我们提供了那些监测数据类型的方法: 一.typeof 操作符 下面是测试代码 var data=[],a='123', ...

  3. jQuery静态方法isPlainObject,isEmptyObject方法使用和源码分析

    isPlainObject方法 测试对象是否是纯粹的对象(通过 "{}" 或者 "new Object" 创建的) 示例: //测试是否为纯粹的对象 jQuer ...

  4. Quartz学习--二 Hello Quartz! 和源码分析

    Quartz学习--二  Hello Quartz! 和源码分析 三.  Hello Quartz! 我会跟着 第一章 6.2 的图来 进行同步代码编写 简单入门示例: 创建一个新的java普通工程 ...

  5. 分享7款非常实用的jQuery/CSS3插件演示和源码

    上次我们分享了15款效果很酷的最新jQuery/CSS3特效,非常不错,今天要分享7个非常实用的jQuery/CSS3插件演示和源码,一起来看看. 1.jQuery ajax点击地图显示商家网点分布 ...

  6. jQuery 2.0.3 源码分析Sizzle引擎解析原理

    jQuery 2.0.3 源码分析Sizzle引擎 - 解析原理 声明:本文为原创文章,如需转载,请注明来源并保留原文链接Aaron,谢谢! 先来回答博友的提问: 如何解析 div > p + ...

  7. Android Debuggerd 简要介绍和源码分析(转载)

    转载: http://dylangao.com/2014/05/16/android-debuggerd-%E7%AE%80%E8%A6%81%E4%BB%8B%E7%BB%8D%E5%92%8C%E ...

  8. Java并发编程(七)ConcurrentLinkedQueue的实现原理和源码分析

    相关文章 Java并发编程(一)线程定义.状态和属性 Java并发编程(二)同步 Java并发编程(三)volatile域 Java并发编程(四)Java内存模型 Java并发编程(五)Concurr ...

  9. Kubernetes Job Controller 原理和源码分析(一)

    概述什么是 JobJob 入门示例Job 的 specPod Template并发问题其他属性 概述 Job 是主要的 Kubernetes 原生 Workload 资源之一,是在 Kubernete ...

随机推荐

  1. Latch2:Latch和性能

    1,数据的IO操作 SQL Server访问的任何一个Page必须存在于内存中,如果不存在于内存中,那么SQL Server发出 Disk IO请求,将数据页从Disk读取到内存中,然后SQL Ser ...

  2. 【WP开发】记录屏幕操作

    在某些应用中,比如游戏,有时候需要将用户的操作记录下来.ScreenCapture类提供了这个功能.但必须注意的是:此屏幕记录功能只对当前应用程序的屏幕有效,即只有当前应用程序在前台运行时才有效. 与 ...

  3. Jser 设计模式系列之面向对象 - 接口封装与继承

    GOF在<设计模式>中说到:面向接口编程,而非面向实现编程 鉴于此,这个概念可见一斑! JS却不像其他面向对象的高级语言(C#,Java,C++等)拥有内建的接口机制,以确定一组对象和另一 ...

  4. 前端工程师技能之photoshop巧用系列第三篇——切图篇

    × 目录 [1]切图信息 [2]切图步骤 [3]实战 前面的话 前端工程师除了使用photoshop进行测量之外,更重要的是要使用该软件进行切图.本文是photoshop巧用系列的第三篇——切图篇 切 ...

  5. DOM-Element类型

    Element类型 Element类型用于表现XML或HTML元素,提供了对元素标签名.子节点及特性的访问.Element节点具有以下特征: nodeType的值为1 nodeName的值为元素的标签 ...

  6. angularjs 请求后端接口请求了两次

    用angularjs的过程中发现,每次打开页面,请求后端的接口都请求了两次 如下图可以看到, http://192.168.1.109:8080/zdh/api/v1/goods/54 这个页面loa ...

  7. iOS开发之窥探UICollectionViewController(四) --一款功能强大的自定义瀑布流

    在上一篇博客中<iOS开发之窥探UICollectionViewController(三) --使用UICollectionView自定义瀑布流>,自定义瀑布流的列数,Cell的外边距,C ...

  8. Android动画学习(一)——Android动画系统框架简介

    2015-11-09补充:Drawable Animation极有可能是Frame Animation 这几天在找工作,面试的时候被问到了Android动画,之前完全没接触过这部分,直接给懵了,当然其 ...

  9. Ubuntu杂记——双系统重装Win7后找不到Ubuntu的解决办法

    之前装过Ubuntu和Win7的双系统,后来重装了Win7,发现Ubuntu不见了,那会没怎么用,也没去解决问题.现在再看Android内核剖析,大部分都是在Ubuntu环境下进行的,所以百度了一些方 ...

  10. 分享一段数据库中表数据更新SQL

    应用场景 我们在应用程序开发的时候,经常会遇到这样的一种情况:附属表更新了,主表的数据没有更新,这个关联表不只是外键的关联(通过附属表 ID 关联),主表中还会存在一些附属表的字段,这样一般做的目的是 ...