问一下各位大虾们,我在看JS时开始说ECMAScript中使用变量之前不用声明的。但为什么后面alter(oTemp2==undefined);时错误的呢??

解决方案 »

  1.   

    alert(typeof oTemp2=="undefined");
      

  2.   


    这里说的是不需要申明,但不是说变量不需要创建。
    在其它强类型语言中,所有变量使用前必须说明它的数据类型;JS是弱类型语言,因此使用前可以不说明它的数据类型。
    但是变量使用前,还是必须创建的,在使用变量名称之前,该变量符号必须在作用域中存在,也就是必须先创建变量。本来,在JS引擎中,如果变量符号不存在,也可以缺省创建一个新变量符号,但这样会造成系统无非区分到底是程序员疏忽写错了变量名称,还是确实是变量没有预先定义。如果系统贸然创建一个新的变量,对于前一种情形下的程序调试是非常不利的,因此不如报告变量对象不存在,让程序员自己判断是属于哪种情况。上面的选择,其实取决于JS引擎设计者的一念之差之间。另外:
    alter(oTemp2==undefined); //这里需要实际引用oTemp2变量符号,因此会报不存在
    alert(typeof oTemp2=="undefined"); 
    //这里测试符号oTemp2名称是否在作用域中存在,不需要真正引用该符号,因此不会报告错误。
      

  3.   


    这里window.oTemp2是计算window对象的oTemp2属性值,如果不存在,则返回undefined。因此这是JS允许的。
    虽然JS中定义变量前如果不加var限制,该变量对象的实际运行效果是在全局对象(window)中增加该变量名的属性(个人认为这并不是个好主意,个人偏好会把它解释到当前的作用域)。
    从符号查找以及作用域的角度来看,JS对于window.oTemp2和oTemp2是解释成完全不同的两个东西的
    windows.oTemp2:明确访问全局作用域windows的oTemp2属性,如果它不存在,则返回undefined,因此可访问。
    oTemp2:访问未知的作用域的符号oTemp2。因为不知道它的作用域在哪(实际和if(...)语句所处的位置相关),因此JS不能贸然(强制)定义这种情况下oTemp2的作用域就是windows(基于前一个回复的理由),它仍然会报告对象不存在。附JS标识符查找算法
    (1)获取Scope Chain(作用域链)的下一个对象。如果没有对象了,则转到第5步
    (2)调用Result(1)的[[HasProperty]]方法, 传递Identifier作为参数
    (3)如果Result(2)是true, 则返回一个Reference(引用)类型的值,它的base object是Result(1),而它的property name是Identifier
    (4)跳到第1步
    (5)返回一个Reference类型,它的base object是null,它的property name是Identifier