JavaScript - 疯子的紫梦's 学习窝

深入认识javascript中的eval函数[转载]

发现为本文起一个合适的标题还不是那么容易,呵呵,所以在此先说明下本文的两个目的:
(1)介绍javascript中的eval函数的用法
(2)如何在函数内执行全局代码

 

►先来说eval的用法,内容比较简单,熟悉的可以跳过。
eval函数接收一个参数s,如果s不是字符串,则直接返回s。否则执行s语句。如果s语句执行结果是一个值,则返回此值,否则返回undefined。
需要特别注意的是对象声明语法“{}”并不能返回一个值,需要用括号括起来才会返回值,简单示例如下:
var code1='"a" + 2';    //表达式
var code2='{a:2}';      
//语句
alert(eval(code1));     
//->'a2'
alert(eval(code2));     
//->undefined
alert(eval('(' + code2 + ')'));    //->[object Object]
        可以看到,对于对象声明语句来说,仅仅是执行,并不能返回值。为了返回常用的“{}”这样的对象声明语句,必须用括号括住,以将其转换为表达式,才能返回其值。这也是使用JSON来进行Ajax开发的基本原理之一。在例子中可以清楚的看到,第二个alert语句输出的是undefined,而第三个加了括号后输出的是语句表示的对象。
            ►现在来说本文的重点,如何在函数内执行全局代码。为了说明这个问题,先看一个例子:
var s='global';    //定义一个全局变量
function demo1(){
    eval('var s="local"');
}
demo1();
alert(s);    //->global
         很好理解,上面的demo1函数等价于:function demo1(){var s='local';},其中定义了一个局部变量s。
        所以最后的输出是global并不是什么奇怪的事情,毕竟大家都能很清楚的区分局部变量和全局变量。
        仔细体会一下,可以发现eval函数的特点,它总是在调用它的上下文变量空间(也称为:包,closure)内执行,无论是变量定义还是函数定义都是如此,所以如下的代码会产生函数未定义的错误:
var s='function test(){return 1;}';     //一个函数定义语句
function demo2(){
    eval(s);
}
demo2();
alert(test());    //->error:test is not defined
        这是因为test函数在局部空间定义,demo2函数内可以访问到,外面就访问不到了。

         而在实际的Ajax开发中,有时我们需要从服务器动态获取代码来执行,以减轻一次载入代码过多的问题,或者是一些代码是通过Javascript自身生成的,希望用eval函数来使其执行。
但这样的动态获取代码的工作一般在函数内完成,比如:
function loadCode(){
    var code=getCode();
    eval(code);
}
       可见eval不可能在全局空间内执行,这就给开发带来了不少问题,也看到过很多人为此郁闷。
        不过现在偶终于找到了解决办法,嘿嘿,可以同时兼容IE和Firefox,方法如下:
var X2={}    //my namespace:)
X2.Eval=function(code){
 if(!!(window.attachEvent && !window.opera)){
  
//ie
  execScript(code); 
 }else{
  
//not ie
  window.eval(code);
 }
}
        现在如果要想在函数内定义全局代码,就可以通过调用X2.Eval(code)方法,一个例子如下:
var s='global';
function demo3(){
 X2.Eval('var s="local"');
}
demo3();
alert(s); //->'local'
        可见,在demo3函数内重新定义了全局变量s="local"。
        需要注意的是X2.Eval并不返回值,如果要进行表达式的求值,还是用系统的eval函数。X2.Eval设计为仅做全局代码定义用。
        其实看到这里,或许有人感觉问题也太容易解决了点,呵呵,但发现这个办法倒是需要些运气和技巧的:
(1)对于IE浏览器,默认已经提供了这样的函数:execScript,用于在全局空间执行代码,只是知道的人还不多。
(2)对于Firefox浏览器,直接调用eval函数,则在调用者的空间执行;如果调用       window.eval则在全局空间执行。这个知道的人估计就更少了。毕竟alert(eval==window.eval)返回true!
         Firefox的eval函数的特点的确是很令人奇怪的,但从javascript规范中倒也能找到其来源:
If value of the eval property is used in any way other than a direct call (that is, other than by the explicit use of its
name as an Identifier which is the MemberExpression in a CallExpression), or if the eval property is assigned to,
an EvalError exception may be thrown.
      意思大概就是说eval函数的执行是和调用者相关的,但并没有说其执行上下文的问题。所以IE和Firefox孰是孰非也就很难说了,大家知道解决办法就好。

 

JavaScript 字符串转换数字

方法主要有三种

转换函数、强制类型转换、利用js变量弱类型转换。

1. 转换函数

js提供了parseInt()和parseFloat()两个转换函数。前者把值转换成整数,后者把值转换成浮点数。只有对String类型调用这些方法,这两个函数才能正确运行;对其他类型返回的都是NaN(Not a Number)。

在判断字符串是否是数字值前,parseInt()和parseFloat()都会仔细分析该字符串。parseInt()方法首先查看位置0处的 字符,判断它是否是个有效数字;如果不是,该方法将返回NaN,不再继续执行其他操作。但如果该字符是有效数字,该方法将查看位置1处的字符,进行同样的 测试。这一过程将持续到发现非有效数字的字符为止,此时parseInt()将把该字符之前的字符串转换成数字。

例如,如果要把字符串 "1234blue "转换成整数,那么parseInt()将返回1234,因为当它检测到字符b时,就会停止检测过程。字符串中包含的数字字面量会被正确转换为数字,因此 字符串 "0xA "会被正确转换为数字10。不过,字符串 "22.5 "将被转换成22,因为对于整数来说,小数点是无效字符。一些示例如下:

parseInt("1234blue");   //returns   1234
parseInt("0xA");   //returns   10
parseInt("22.5");   //returns   22
parseInt("blue");   //returns   NaN

parseInt()方法还有基模式,可以把二进制、八进制、十六进制或其他任何进制的字符串转换成整数。基是由parseInt()方法的第二个参数指定的,所以要解析十六进制的值,需如下调用parseInt()方法:
parseInt("AF",   16);   //returns   175
当然,对二进制、八进制,甚至十进制(默认模式),都可以这样调用parseInt()方法:
parseInt("10",   2);   //returns   2
parseInt("10",   8);   //returns   8
parseInt("10",   10);   //returns   10
如果十进制数包含前导0,那么最好采用基数10,这样才不会意外地得到八进制的值。例如:
parseInt("010");   //returns   8
parseInt("010",   8);   //returns   8
parseInt("010",   10);   //returns   10
在这段代码中,两行代码都把字符串 "010 "解析成了一个数字。第一行代码把这个字符串看作八进制的值,解析它的方式与第二行代码(声明基数为8)相同。最后一行代码声明基数为10,所以iNum3最后等于10。

parseFloat()方法与parseInt()方法的处理方式相似,从位置0开始查看每个字符,直到找到第一个非有效的字符为止,然后把该字 符之前的字符串转换成数字。不过,对于这个方法来说,第一个出现的小数点是有效字符。如果有两个小数点,第二个小数点将被看作无效 的,parseFloat()方法会把这个小数点之前的字符串转换成数字。这意味着字符串 "22.34.5 "将被解析成22.34。
使用parseFloat()方法的另一不同之处在于,字符串必须以十进制形式表示浮点数,而不能用八进制形式或十六进制形式。该
方法会忽略前导0,所以八进制数0908将被解析为908。对于十六进制数0xA,该方法将返回NaN,因为在浮点数中,x不是有效字符。此外,parseFloat()也没有基模式。

下面是使用parseFloat()方法的示例:
parseFloat("1234blue");   //returns   1234.0
parseFloat("0xA");   //returns   NaN
parseFloat("22.5");   //returns   22.5
parseFloat("22.34.5");   //returns   22.34
parseFloat("0908");   //returns   908
parseFloat("blue");   //returns   NaN

2. 强制类型转换

还可使用强制类型转换(type casting)处理转换值的类型。使用强制类型转换可以访问特定的值,即使它是另一种类型的。
ECMAScript中可用的3种强制类型转换如下:
Boolean(value)——把给定的值转换成Boolean型;
Number(value)——把给定的值转换成数字(可以是整数或浮点数);
String(value)——把给定的值转换成字符串。
用这三个函数之一转换值,将创建一个新值,存放由原始值直接转换成的值。这会造成意想不到的后果。
当要转换的值是至少有一个字符的字符串、非0数字或对象(下一节将讨论这一点)时,Boolean()函数将返回true。如果该值是空字符串、数字0、undefined或null,它将返回false。

可以用下面的代码段测试Boolean型的强制类型转换。

Boolean("");   //false   –   empty   string
Boolean("hi");   //true   –   non-empty   string
Boolean(100);   //true   –   non-zero   number
Boolean(null);   //false   -   null
Boolean(0);   //false   -   zero
Boolean(new   Object());   //true   –   object

Number()的强制类型转换与parseInt()和parseFloat()方法的处理方式相似,只是它转换的是整个值,而不是部分值。还记 得吗,parseInt()和parseFloat()方法只转换第一个无效字符之前的字符串,因此 "4.5.6 "将被转换为 "4.5 "。用Number()进行强制类型转换, "4.5.6 "将返回NaN,因为整个字符串值不能转换成数字。如果字符串值能被完整地转换,Number()将判断是调用parseInt()方法还是调用 parseFloat()方法。下表说明了对不同的值调用Number()方法会发生的情况:

用  法  结  果
Number(false)  0
Number(true)  1
Number(undefined) NaN
Number(null)  0
Number( "5.5 ")  5.5
Number( "56 ")  56
Number( "5.6.7 ") NaN
Number(new   Object())  NaN
Number(100)  100 

最后一种强制类型转换方法String()是最简单的,因为它可把任何值转换成字符串。要执行这种强制类型转换,只需要调用作为参数传递进来的值的 toString()方法,即把1转换成   "1 ",把true转换成 "true ",把false转换成 "false ",依此类推。强制转换成字符串和调用toString()方法的唯一不同之处在于,对null或undefined值强制类型转换可以生成字符串而不引 发错误:

var   s1   =   String(null);   //"null"
var   oNull   =   null;
var   s2   =   oNull.toString();   //won’t   work,   causes   an   error

3. 利用js变量弱类型转换

举个小例子,一看,就会明白了。
<script>
var   str= '012.345 ';
var   x   =   str-0;
x   =   x*1;
</script>

上例利用了js的弱类型的特点,只进行了算术运算,实现了字符串到数字的类型转换,不过这个方法还是不推荐的。

图片不存在的时候,显示一个默认图片

 

<img src="noexist.gif" onerror="this.src='http://www.lanrentuku.com/images/logo.jpg'" />
<p>查找更多代码,请访问:<a href="http://www.lanrentuku.com" target="_blank">懒人图库</a></p>

通过这个方法,就可以实现当没有图片或图片丢失的情况,显示一个默认图片。以后,不用通过程序来判断图片是否存在了

javascript 里面 隐藏页面控件的方法

<script language="javascript">
function hidd1(){        
	div1.style.visibility="hidden";}
function hidd2(){
	div2.style.display="none";}
    </script>
<div id="div1" onclick="hidd1()" style="width:200px;height:300px;background:#F00;">div1</div> 
<div id="div2" onclick="hidd2()" style="width:200px;height:300px;background:#00F;">div2</div>
<div style="width:200px;height:300px;background:#F30;">div3</div>

visibility 占位并隐藏 值:visable:显示  hidden:隐藏 inherit:继承父对象的可见性

display 不占位  隐藏

 

javascript 函数命名不能与页面里面其它元素的name id 相同

javascript中window和document

[window对象] 

  它是一个顶层对象,而不是另一个对象的属性,即浏览器的窗口。 

  属性 

  defaultStatus 缺省的状态条消息 

  document 当前显示的文档(该属性本身也是一个对象) 

  frame 窗口里的一个框架((FRAME>)(该属性本身也是一个对象) 

  frames array 列举窗口的框架对象的数组,按照这些对象在文档中出现的顺序列出(该属性本身也是一个 

对象) 

  history 窗口的历史列表(该属性本身也是一个对象) 

  length 窗口内的框架数 

  location 窗口所显示文档的完整(绝对)URL(该属性本身也是一个对象)不要把它与如document.location 

混淆,后者是当前显示文档的URL。用户可以改变window.location(用另一个文档取代当前文档),但却不能改变 

document.location (因为这是当前显示文档的位置) 

  name 窗口打开时,赋予该窗口的名字 

  opener 代表使用window.open打开当前窗口的脚本所在的窗口(这是Netscape Navigator 3.0beta 3所引 

入的一个新属性) 

  parent 包含当前框架的窗口的同义词。frame和window对象的一个属性 

  self 当前窗口或框架的同义词 

  status 状态条中的消息 

  top 包含当前框架的最顶层浏览器窗口的同义词 

  window 当前窗口或框架的同义词,与self相同 

  方法 

  alert() 打开一个Alert消息框 

  clearTimeout() 用来终止setTimeout方法的工作 

  close() 关闭窗口 

  confirm() 打开一个Confirm消息框,用户可以选择OK或Cancel,如果用户单击OK,该方法返回true,单击

Cancel返回false 

  blur() 把焦点从指定窗口移开(这是Netscape Navigator 3.0 beta 3引入的新方法) 

  focus() 把指定的窗口带到前台(另一个新方法) 

  open() 打开一个新窗口 

  prompt() 打开一个Prompt对话框,用户可向该框键入文本,并把键入的文本返回到脚本 

  setTimeout() 等待一段指定的毫秒数时间,然后运行指令事件处理程序事件处理程序 

  Onload() 页面载入时触发 

  Onunload() 页面关闭时触发 

[document对象] 

  该对象是window和frames对象的一个属性,是显示于窗口或框架内的一个文档。 

  属性 

  alinkColor 活动链接的颜色(ALINK) 

  anchor 一个HTMI锚点,使用<A NAME=>标记创建(该属性本身也是一个对象) 

  anchors array 列出文档锚点对象的数组(<A NAME=>)(该属性本身也是一个对象) 

  bgColor 文档的背景颜色(BGCOLOR) 

  cookie 存储于cookie.txt文件内的一段信息,它是该文档对象的一个属性 

  fgColor 文档的文本颜色(<BODY>标记里的TEXT特性) 

  form 文档中的一个窗体(<FORM>)(该属性本身也是一个对象) 

  forms anay 按照其出现在文档中的顺序列出窗体对象的一个数组(该属性本身也是一个对象) 

  lastModified 文档最后的修改日期 

  linkColor 文档的链接的颜色,即<BODY>标记中的LINK特性(链接到用户没有观察到的文档) 

  link 文档中的一个<A HREF=>标记(该属性本身也是一个对象) 

  links array 文档中link对象的一个数组,按照它们出现在文档中的顺序排列(该属性本身也是一个对象) 

  location 当前显示文档的URL。用户不能改变document.location(因为这是当前显示文档的位置)。但是, 

可以改变 window.location (用其它文档取代当前文档)window.location本身也是一个对象,而 

document.location不是对象 

  referrer 包含链接的文档的URL,用户单击该链接可到达当前文档 

  title 文档的标题((TITLE>) 

  vlinkColor 指向用户已观察过的文档的链接文本颜色,即<BODY>标记的VLINK特性 

  方法 

  clear 清除指定文档的内容 

  close 关闭文档流 

  open 打开文档流 

  write 把文本写入文档 

  writeln 把文本写入文档,并以换行符结尾 

区别:1、window指窗体。document指页面。document是window的一个子对象。

       2、用户不能改变 document.location(因为这是当前显示文档的位置)。但是,可以改变window.location (用其它文档取代当前文档)window.location本身也是一个对象,而document.location不是对象