今天第一次在segmentfault里写文章。去年暑假的时候开通了博客园,然后开始找工作,至今为止只写了一篇文章。惭愧啊!今天兴致来了,投身博客园,尼玛,密码忘记了。看了那么无聊的找回密码,果断转投于此,但愿我以后能够坚持写点东西。毕竟,好好记性不如烂笔头。
公司不让去实习,在学校待的无聊,前两天再写东西的时候,突然意识到,已经大半年没有写过jQuery了。但看到那么多熟悉API,不想再去做重复的工作,果断找到源码,投入分析。
看源码的进程缓慢,但收获确实挺大,尤其有利于扎实js底层知识。今天看到了源码里面globalEval方法的实现。虽然用的不多,但是实现方法着实让人眼前一惊(大神不算)。所以就从这里开始我的文章生涯吧!!
eval和window.eval
对于eval基本的用法,对于任何一位前端来说,都不会陌生。jQuery源码里面也有其基本使用,但是用法。可视我第一次见啊啊啊啊。
我们知道,当我们在全局声明一个函数的时候,就相当于在window对象上面添加了一个方法。即有所谓的:函数名===window.函数名。以前在使用eval()函数的时候,也想当然的认为eval===window.eval。其实,两者的用法差距挺大的。
function create()
{
eval('var a = 2'); //和在函数里面直接var a = 2;的效果是一样的
window.eval('var b = 3'); //这种其实是在全局作用域里面声明了变量 b
}
//调用函数
create();
consoole.log(a); //报错:a is not defined
console.log(b); // 3
从上面的函数里面,我们就可以看出eval就是把其参数在当前的作用域里面运行。而window.eval无论其处于什么作用域里,都会把其参数在全局作用域里面运行。
除了直接使用window.eval外,我们也可以使用一个变量对其进行引用
function create(){\
{
var ev = eval; //js就是这么神奇,这里的eval指的是window.eval,而非对eval的直接引用
ev('var c = 4');
}
create();
console.log(c); //4
js果然是一门神奇的语言,那么小的一个玩意竟然会有那么多想不到的用法。
其实啊,eval在单独使用的时候,js语言其实是把它作为一个结构体来看待,而window.eval在使用的时候,却真真是一个函数。
下面附上jQuery里面globalEval的源码
//自己试着写的,顺便使用了经常使用的去除两端空格的方法。
String.prototype.trim = function(){
return this.replace(/^(\s+)|(\s)+$/g,'');
};
jQuery.globalEval = function(code){
var newScript,
newEval = eval; //获取对eval的使用
code = code.trim(); //去除字符串两端的空格
if(code){
if(code.indexOf("use strict")){
//说明是严格模式,不能直接使用window.eval函数
newScript = document.createElement('script');
newScript.createTextNode(code);
document.head.appendChild(newScript).parentNode.removeChild(newScript);
}else{
//非严格模式
newEval(code);
}
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。