`
dacoolbaby
  • 浏览: 1266109 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

JavaScript 中的变量作用域问题

阅读更多

备注:这里的内容有转载的部分,有我自己理解的部分。

 

首先来一道题:

function foo(){ 
  foo.abc = function(){alert('def')} 
  this.abc = function(){alert('xyz')} 
  abc = function(){alert('@@@@@')}; 
  var abc = function(){alert('$$$$$$')} 
} 
foo.prototype.abc = function(){alert('456');} 
foo.abc = function(){alert('123');} 
var f = new foo(); 
f.abc(); 
foo.abc(); 
abc(); 

 

都是abc,看懵了吧?

慢慢来理解吧。

var a=100;   
var b=true;   
function test(){   
    alert(a);   //undefined
    alert(b);   //true
    b=false;   
    alert(b);   //false
    var a=200;   
    alert(a/2);   //100
    alert(++Math.PI);    //4.14...
    alert(Math.PI++);   //3.14...
}   
test(); 

 这里为什么会输出undefined呢?

 

像javascript这样的解释型语言,基本分为两个阶段,编译期(下面为符合大多数语言的称呼习惯,改叫预编译)与运行期

在预编译阶段,它是用函数来划分作用域,然后逐层为其以 var 声明的变量(下略称为var变量)函数定义开辟内存空间,再然后对var变量进行特殊处理,统统赋初始值为undefined。

 

我们都明白局部变量的优先级大于全局变量,或者说内围作用域的变量的优先级比外围的高。

当JS引擎在当前作用域找不到此变量时,它就往外围的作用域找。

不过,在这之前,有一个严肃的问题是,究竟当前作用域存不存在这个变量。

 

第1行——它为外围作用域的a赋值为100
第2行——它为外围作用域的b赋值为true
第3行——进行test的作用域,我们简称为内围作用域。
第4行——就立即调用内围作用域的a,这时它还没有来得及赋值呢!
              不过它已经声明过了,因此默认为其赋值为undefined(在预编译阶段,见图),
              于是alert为undefined
第5行——就调用b时,JS引擎就拿起我画的图看了(笑),
              发现test的作用域内没有b,眼睛往外望,发现b了,
              而b在第二行就赋值为true,于是alert为true。
第6行——为一个赋值操作,把外围的b变量改赋为false。
第7行——alert为false。以下说法不说了。

 

那么,如果我把var a = 200;注释掉会怎样呢?

是的,那么JS引擎则在预编译阶段则找不到作用域里面的a,转而直接使用Global变量。

 

好的,那么复习一下:

var scope = "global";   
function f() {   
    alert(scope);               
    var scope = "local";        
    alert(scope);               
}   
f(); 

你做对了吗?

 

第一个是 undefined

第二个是 local

 

那么再来看这个、

Object.test = "bbb"; 
Object.prototype.test = 'ccc'; 
window.test = "aaa"; 
(function f() { 
    alert(test); 
})(); 

 

或许很多人会猜是bbb

但实际上呢,是aaa。

 

JS引擎为了速度优化,所以在所有没有声明的变量前面自动加上window.

其中的window.test 其实等同于 var test = "aaa";

 

另外像Object.test = “XXX”这样定义,为类属性,或称静态属性。类属性优先级都是比实例属性低的

关于prototype的使用机制在后面会给出。

 

再回过头来看最前面的题目:

第一个为xyz,
f.abc很明显就是调用其实例属性,通常构造函数是这样定义实例方法与实例属性的:
this.XXX = "XXXXXXXX"

(实例属性 优先级比 类属性

 

第二个就是构造函数内部的foo.abc还是外部的foo.abc的问题了。
我们只要搞清楚一点就可以,写在外面的那个(foo.abc=function(){alert('123');})是"极晚绑定"的成员,
优先级极低,覆盖不了内部的同名成员。

 

第三个为什么会报错呢?!
因为在预编译阶段,
foo()的作用域就有了一个abc变量,
因此abc = function(){alert('@@@@@')}
就变不了window.abc = function(){alert('@@@@@')},
而下面那一行就更甭提了。

而我们调用的是abc,全局变量的abc,
浏览器会自动给它加上window.abc,就算不加上,
沿途的Objcet也没有abc这个变量,
因此它在f()的作用域外找不到abc,就报未定义错误!

 

内容参考自:http://blog.csdn.net/kingwolfofsky/article/details/6581944

http://www.cnblogs.com/rubylouvre/archive/2009/08/21/1551270.html

分享到:
评论

相关推荐

    javascript变量作用域

    JavaScript 变量作用域详解 JavaScript 变量作用域是基于其特有的作用域链的。在 JavaScript 中,变量作用域是指变量可以被访问和修改的范围。 JavaScript 没有块级作用域,而是基于函数作用域和全局作用域的。 ...

    基于JavaScript的变量作用域的辨析.pdf

    本文探讨了JavaScript中的变量作用域问题,通过对两种变量的特性从不同角度进行分析和测试,讨论了如何控制变量作用域的有效方法。 变量作用域是JavaScript编程过程中经常遇到的问题之一,对于编程人员来说是一个...

    js变量作用域

    ### JavaScript 变量作用域详解 #### 一、引言 在探讨JavaScript的面向对象特性之前,理解变量作用域的概念至关重要。本篇文章旨在通过一系列示例和解释,帮助读者掌握JavaScript中的变量作用域机制。 #### 二、...

    理解JavaScript变量作用域.pdf

    理解JavaScript变量作用域.pdf 本人还有几十本经典javascript书籍以及无数javascript资料,要的加我qq 568094881,本人网址:www.maoshanhai.com

    深入理解变量作用域

    本文将从JavaScript权威指南出发,深入探讨变量作用域的相关知识点,包括全局作用域、局部作用域、以及闭包等高级概念。 #### 二、全局作用域与局部作用域 1. **全局作用域** - 定义:在JavaScript中,如果一个...

    JavaScript程序设计-变量作用域.pdf

    JavaScript是一种广泛用于网页和网络应用的编程语言,其核心特性之一就是变量作用域。变量作用域决定了变量在何处可以被访问以及何时会被销毁。本文将深入探讨JavaScript中的全局变量、局部变量、变量提升、词法作用...

    JavaScript程序设计变量作用域共4页.pdf.zi

    本文将深入探讨JavaScript中的变量作用域,以及它如何影响代码的运行和组织。 首先,我们来理解什么是变量作用域。在JavaScript中,变量作用域决定了变量在何处可以被访问和识别。主要有三种类型的作用域:全局作用...

    JavaScript 基础函数_深入剖析变量和作用域

    JavaScript是一种广泛用于网页开发的脚本语言,它的函数和作用域是实现代码逻辑结构和模块...理解JavaScript中的变量作用域非常重要,它有助于避免变量命名冲突和意外的变量修改,从而编写出更加健壮和易于维护的代码。

    Javascript中的作用域及块级作用域

     javascript的变量作用域,与平时使用的类C语言不同,例如C#中的代码: static void Main(string[] args) { if(true) { int number=10; } Console.WriteLine(number); }  这段代码进行编译,是无法通过的,...

    JavaScript的变量作用域深入理解

    在学习JavaScript的变量作用域之前,我们应当明确几点: a、JavaScript的变量作用域是基于其特有的作用域链的。 b、JavaScript没有块级作用域。 c、函数中声明的变量在整个函数中都有定义。 1、JavaScript的作用域链...

    一道关于JavaScript变量作用域的面试题_.docx

    JavaScript变量作用域是编程语言中一个非常核心的概念,它决定了变量在何处可被访问以及其生命周期。在这道面试题中,我们看到的是如何在不同作用域下声明和使用变量,特别是与for循环相结合的情况。 首先,我们要...

    深入浅析JavaScript中的作用域和上下文

    3. **块级作用域**:在ES6之前,JavaScript没有块级作用域,但ES6引入了`let`关键字,使得变量能够在特定代码块(如`if`、`for`或`while`语句内)中定义并保持其作用域限制。 - 示例: ```javascript function ...

    浅谈Javascript变量作用域问题

    Js中的变量作用域问题: 1、没有块级作用域。Js中的变量作用域不是以{}为界的,不像C/C++/Java。 如: 代码如下:  if(true){  var name = “qqyumidi”;  }    alert(name); // 结果:qqyumidi Js会...

    深入理解JavaScript作用域和作用域链

    JavaScript作用域是编程中至关重要的概念,它规定了变量和函数的可见性及生命周期。JavaScript主要有两种作用域:全局作用域和局部作用域。 全局作用域是指在代码的任何位置都可以访问的变量或函数,这通常包括在最...

    javascript执行环境,作用域理解

    在 JavaScript 中,执行环境和作用域是两个非常重要和基本的概念,理解了这两个概念对于 JavaScript 中很多脚本的运行结果就能明白其中的道理了。执行环境是一个概念,一种机制,用来完成 JavaScript 运行时在作用域...

    深化浅析JavaScript中的作用域和上下文_.docx

    **变量作用域**: 在JavaScript中,变量可以存在于全局作用域或局部作用域。全局变量在整个程序运行期间都是可访问的,而局部变量只在定义它的函数内部有效。在ES6之前,JavaScript没有块级作用域,但ES6引入了`let`...

    JavaScript中作用域链的概念及用途讲解

    接着查找`fruit`,不在当前作用域,于是继续在全局作用域中找到`fruit`并使用。 而在全局环境中,当尝试访问`fruit`和`color`时,由于全局作用域的变量对象只包含`fruit`,所以`color`会导致一个`undefined`的错误...

    JavaScript变量的作用域全解析

    变量作用域是程序中定义这个变量的区域。 先来看一段示例: /* 代码1 */ var scope = "global "; function checkScope() { var scope = "local "; function childCheck() { var scope = "childLocal "; ...

Global site tag (gtag.js) - Google Analytics