作用域问题

下面这段javascript代码,


1

2

3

4

5

6

class="lang-js">var msg=‘hello‘;

for (var i=0; i<10; i++)

{

    var msg=‘hello‘+i*2+i;

}

alert(msg);

最后一句alert的输出结果是? //hello189

javascript只有函数域,没有块作用域的概念,所以在同一个作用域中同一个变量声明多次还是第一次声明那个!(所以for循环不会形成作用域)

编译器在解析的时候,会发现声明了两个变量,但是后面的那个发现前面的已经声明了所以被忽略。所以for循环中的msg的声明其实是无效的,从头至尾都是在操作同一个msg。

而for循环里面的var msg=‘hello‘+i*2+i;只是相当于再次赋值操作而已。

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

2.

现有如下html结构


1

2

3

4

5

6

<ul>

 <li>click me</li>

 <li>click me</li>

 <li>click me</li>

 <li>click me</li>

</ul>

运行如下代码:


1

2

3

4

5

6

7

    var elements=document.getElementsByTagName(‘li‘);

    var length=elements.length;

    for(var i=0;i<length;i++){

        elements[i].onclick=function(){

        alert(i);

    }

 }

依次点击4个li标签,哪一个选项是正确的运行结果()? //依次弹出4,4,4,4

每个li标签的onclick事件执行时,本身onclick绑定的function的作用域中没有变量i,i为undefined,则解析引擎会寻找父级作用域,发现父级作用域中有i,且for循环绑定事件结束后,i已经赋值为4,所以每个li标签的onclick事件执行时,alert的都是父作用域中的i,也就是4。这是作用域的问题。

解答:这里的事件,绑定的并非是i的值,而是i本身(alert里的i),所以当程序执行完,i的值变为4,去执行onclick事件时,执行alert(i) ,自动查找i,值为4,所以依次弹出4。

改正:


1

2

3

4

5

6

7

8

9

10

var elements=document.getElementsByTagName(‘li‘);

    var length=elements.length;

    var handler = function(i){

        return fucntion(){

            alert(i);

        }

    }

    for(var i=0;i<length;i++){

        elements[i].onclick= handler(i);

 }

避免在循环中创建函数,可以在循环之外创建一个辅助函数,让这个辅助函数返回一个绑定了当前i值得函数,避免混淆

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

3.

if(! "a" in window){

    var a = 1;

}

alert(a);

请问 a 的结果是什么? //undefined

javascript只有函数作用域, 没有块作用域,即if,for等语句里声明的变量和其外一层的变量的作用域是一样的(函数作用域,作用域的“局部"是相对于函数而言的)。

使用var声明的变量会被自动添加到最接近的环境的顶部(即全局作用环境中);变量提升仅提升变量声明,而不是变量赋值。

变量提前问题,等价于:


1

2

3

4

5

var a;

if(!"a"in window){

    a =1;

}

alert(a);

这题还有一个细节 ,在代码的顶部var声明的变量会被认为是window的属性,如果在代码中直接使用a=
"foo" ,变量同样会被认为是全局变量但是并不是window的属性。


1

2

3

4

5

6

7

if(! "a"in window){

    a = 1;

}

alert(a);

这样的话会弹出1

时间: 2024-08-30 04:11:50

作用域问题的相关文章

一招制敌 - 玩转 AngularJS 指令的 Scope (作用域),讲得特别好

学习了AngularJS挺长时间,最近再次回首看看指令这部分的时候,觉得比自己刚开始学习的时候理解的更加深入了,尤其是指令的作用域这部分. 步入正题: 每当一个指令被创建的时候,都会有这样一个选择,是继承自己的父作用域(一般是外部的Controller提供的作用域或者根作用域($rootScope)),还是创建一个新的自己的作用域,当然AngularJS为我们指令的scope参数提供了三种选择,分别是:false,true,{}:默认情况下是false. scope = false 首先我们来看

CSS作用域问题

今天去长虹面试,面试官问了一个问题,就是给一个div在三个地方设置不同的background,最后div显示的颜色是哪一个?当时我第一次回答的是最后一个,但是后来又改口说是第一个,回来一验证,证明自己错了,今天就总结一下CSS样式的作用域问题吧. 首先对HTML引入样式的优先级排序,数字越大优先级越高#### 样式优先级1. 浏览器缺省设置2. 外部样式表3. 内部样式表(位于 <head> 标签内部)4. 内联样式(在 HTML 元素内部) ---#### 外部样式表>浏览器缺省设置H

JavaScript的进阶之路(二)函数简介,变量、作用域和内存问题

<h3>ECMAScript中函数不存在函数签名的概念,没有重载</h3><h3>无需指定返回值,可以在任何时候返回任何值.未指定返回值的函数,返回的是一个特殊的undefined值</h3> <script type="text/javascript"> function sayHi(){ console.log("Hi"); }; sayHi(); function sayName(name,age){

JavaScript栈和堆内存,作用域

1.栈 stack"和"堆 heap": 简单的来讲,stack上分配的内存系统自动释放,heap上分配的内存,系统不释放,哪怕程序退出,那一块内存还是在那里.stack一般是静态分配内存,heap上一般是动态分配内存. 2.基本类型和引用类型: 基本类型:存放在栈内存中的简单数据段.数据大小确定,内存空间大小可以分配. 引用类型:存放在堆内存中的对象,变量中实际保存的是一个指针,这个指针指向另一个位置.每个空间大小不一样,要根据情况开进行特定的分配. 详见<Javas

深入理解javascript的作用域--函数声明为什么会前置

标签: javascript函数对象 这篇博文解决了以下迷惑 函数声明为什么前置 函数声明前置和变量前置优先级问题 为什么js文件开头就可以使用Math,String等库,而不需要导入头文件 1.变量对象VO 变量对象(Variable Object, 缩写为VO)是一个抽象 概念中的"对象",它用于存储执行上下文中的: 1. 变量 2. 函数声明 3. 函数参数 js解释器就是通过变量对象(VO)来找到我们定义的变量和函数的. 举个例子: var a = 10; function t

【JS】JavaScript中的执行环境与作用域

JavaScript中的执行环境定义了变量或函数有权访问的数据(每个函数都有自己的执行环境),全局执行环境是最外围的执行环境,在浏览器中,全局执行环境就是window对象,所以所有的全局变量和函数都是作为window对象的属性和方法创建的.当某一个执行环境中所有代码执行完成后,该环境就被销毁,保存在其中的变量和函数也将被销毁,全局执行环境在关闭网页或浏览器时才被销毁. 当代码在一个环境中执行时,会创建变量对象的一个作用域链(保证对执行环境有权访问的变量和函数的有序访问),如果环境是函数,将其活动

Python之路18-函数作用域、全局变量、局部变量

#全局变量 school = 'lianhedaxue' def test(name):     #强制修改全局变量     global school     school = 'haha'     print ('before change',name,school)     name = 'Jack'   #这个函数就是这个变量的作用域     print ('after change',name) name = 'Tom' test(name) print (name) print (s

javascript变量声明和作用域提升

以前的知识总是忘,遇到代码又看不懂.要再复习一下,顺便记录一下. 1 add(1,2); 2 function add(a,b){ 3 alert(a+b); 4 } 代码能输出3,为什么不是按顺序执行?应该是  //add is not defined ... javascript的变量声明具有hoisting机制,JavaScript引擎在执行的时候,会把所有变量的声明都提升到当前作用域的最前面. 也就是说,function add(a,b){alert(a+b)}是一个函数声明,告诉我们有

【】五句话搞定JavaScript作用域

JavaScript的作用域一直以来是前端开发中比较难以理解的知识点,对于JavaScript的作用域主要记住几句话,走遍天下都不怕... 一.“JavaScript中无块级作用域” 在Java或C#中存在块级作用域,即:大括号也是一个作用域.  Java  C# 在JavaScript语言中无块级作用域 1 2 3 4 5 6 7 function Main(){     if(1==1){         var name = 'seven';     }     console.log(n

面向对象之对象,作用域及this

object eg: var o = { a : 2, b : 3 }; console.log(o); console.log(typeof o); console.log(o.a.toFixed(2)); ==> var o = new Object(); o.a = 2; o.b = 3; console.log(o); console.log(typeof o); console.log(o.a.toFixed(2)); eg: var person = { name: “张三”, ag