当前位置:编程学习 > JS >>

JavaScript变量作用域的问题

写了一个JAVA script 其中一个变量作用域问题想问问……

下面一段java script代码 这个代码能运行正常 作用是把一副图片做一个漂浮广告

位置不因用户拉滚动条而变

 

<script language="javascript">

function floating()
 {

  var ImgY=50;
  var targetImage = document.getElementById('floatingImg');
  

  // Set the floating image's position
  targetImage.style.top = ImgY+document.documentElement.scrollTop+"px";

}

window.onscroll = floating;

</script>

 

然后如果我改改这个代码

 

<script language="javascript">

  var targetImage = document.getElementById('floatingImg');

 

function floating()
 {

  var ImgY=50;

  

  // Set the floating image's position
  targetImage.style.top = ImgY+document.documentElement.scrollTop+"px";

}

window.onscroll = floating;

</script>

 

我把targetImage的定义写在了函数的外面,这时就会运行出错了,floating函数里面会说我找不到targetImage对象……

 

问题就是 java script变量的作用域是什么?

为什么写在函数外面就不能访问呢?

追问:感谢您上面的回答,看了确实受益匪浅,

您说道:上面说了。函数中调用的一切属性,都被当作obj的属性来处理,当用到该属性时,会从obj对象的scope chain中查找。

就是说,javascript和java一样,不允许像C、C++传统意义上的全局变量的存在,而必须封包在类里面吗?我不懂太多的编译原理,只对JAVA有点研究,是否可以把javascript里面的函数看成java里面的类,里面调用的所有属性都是自己的成员变量?

如果是这样,java里面可以调用其他类的静态方法和public的静态变量,javascript如果把函数看成一个类,调用如上面targetImage这个变量的时候,是否有办法可以把targetImage变为全局变量,或者把它变为其他类的静态方法让它可以被到处访问而不需多次定义?

答案:我来大概给你说一下,这个问题说起来有点复杂也有点绕了。你好好体会。

在javascript中,一切都是对象,函数也不例外。

在一个函数被定义的时候, 会将它定义时刻的scope chain链接到这个函数对象的[[scope]]属性.
在一个函数对象被调用的时候,会创建一个活动对象(也就是一个对象), 然后对于每一个函数的形参,都命名为该活动对象的命名属性, 然后将这个活动对象做为此时的作用域链(scope chain)最前端, 并将这个函数对象的[[scope]]加入到scope chain中.

举个例子来说,假设有下面这样一个函数。该函数定义在<script>标签内,是一个全局函数

var func = function(lps, rps){

          var name = 'laruence';

          ........

}

在调用函数的时候会创建一个活动对象,假如叫做obj,那么lps和rps会作为obj对象的两个属性存在。

对于每一个在这个函数中申明的局部变量和函数定义, 都作为该活动对象的同名命名属性.

然后将调用参数赋值给形参数,对于缺少的调用参数,赋值为undefined。

然后将这个活动对象做为scope chain的最前端, 并将func的[[scope]]属性所指向的,定义func时候的顶级活动对象, 加入到scope china.(作用域链)

有了上面的作用域链, 在发生标识符解析的时候, 就会逆向查询当前scope chain列表的每一个活动对象的属性,如果找到同名的就返回。找不到,那就是这个标识符没有被定义。

所以,我们根据上述的原理来看一下你的函数。

函数float在被调用时创建了一个对象obj(当然,这些是js编译器在后台执行的,我们无法见到)。函数没有参数,那么也就是说仅仅创建了一个对象obj,而这个对象是没有属性的。上面说了。函数中调用的一切属性,都被当作obj的属性来处理,当用到该属性时,会从obj对象的scope chain中查找。很显示你的obj对象是一个空对象,所以肯定无法获得targetImage 对象的。

这里有点乱,虽然我已经尽量说的明白,但是你可能还需要自己体会一下

希望我的回答能帮到你吧!~

上一个:Javascript不支持gbk编码
下一个:Java和JavaScript什么关系?

CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,