变量作用域

一个变量的作用域(scope)是程序源代码中定义这个变量的区域。

全局变量拥有全局作用域,在JavaScript代码中的任何地方都是有定义的。然而在函数内声明的变量只是函数体内有定义。

他们是局部变量,作用域是局部性的。函数参数也是局部变量,它们只是函数体内有定义。

在函数体内,局部变量的优先级高于同名的全局变量。

如果在函数内声明的一个局部变量或者函数参数中带有的变量和全局变量重名,那么全局变量就被局部变量所遮盖。

var scope ="global";                      //声明一个全局变量
function checkscope()
{
var scope ="local"; //声明一个同名的局部变量
return scope; //返回局部变量的值,而不是全局变量的值
}
checkscope() //=> "local"

尽管在全局作用域编写代码是可以不写var 语句,但声明局部变量是则必须使用var语句。

如果在申明局部变量是不使用 var :

scope="global";                            //声明一个全局变量,甚至不用var来声明
function checkscope2()
{
scope="local"; //糟糕!我们刚刚修改全局变量
myscope="local"; //这里显示地声明了一个新的全局变量
return [scope,myscope]; //返回两个值
}
checkcope2(); //=>["local","local"] :
scope; //=>"local" : 全局变量修改了
myscope; //=>"local" : myscope成为了全局变量

函数作用域和声明提前(置顶解析)

在一些类似C语言的编程语言中,花括号内的每一段代码都具有各自的作用域,而且变量在声明它们的代码段之外是不可见的,我们称之为块级作用域(block scope),

而JavaScript 中没有块级作用域。JavaScript取而代之的使用了函数作用域(function scope):变量在声明它们的函数体内以及这个函数体嵌套的任意函数体内都是有定义的。

如下代码:

function test(o)
{
var i = 0; // i 在整个函数test内都是有定义的
if ( typeof o =="object")
{
var j = 0; // j 在函数test内都是有定义的
for ( var k=0; k < 10; k++ ) // K 在函数test内都是有定义的 不仅仅是在循环内
{
console.log( k ); // 输出数字0~9
}
console.log(k); // k 已经定义了,输出10
}
console(j); //j 已经定义了,输出 undefined 或0
}

JavaScript 的函数作用域是指 在函数内声明的所有变量在函数体内始终是可见的。

有意思的是,这意味着变量在声明之前甚至已经可用了。

JavaScript 的这个特性呗非正式的称为 声明提前 (hoisting) ---------我喜欢称为 置顶解析

即JavaScript 函数里声明的所有变量(不涉及赋值)都被“提前” 值函数体的顶部,看一下如下代码:

var scope ="global";
function f ()
{
console.log(scope); //输出 “undefined ” 而不是 “global”
var scope = "local"; //变量在这里赋值,但是变量在 f 函数顶部已经有定义了
console.log(scope); //输出 “local"
}

其实上面代码可以这样理解

var scope ="global";
function f ()
{
var scope ; //在函数顶部声明可局部变量 scope
console.log(scope); //输出 “undefined ” 而不是 “global”
scope = "local"; //变量在这里赋值
console.log(scope); //输出 “local" 这里有了我们期望的值
}

作为属性的变量(隐式全局变量)

当声明一个JavaScript 全局变量时,实际上是定义了全局对象的一个属性。

当使用var 声明一个变量时,创建的这个属性是不可配置的,也就是说这个变量无法通过 delete 运算符删除。

隐式全局变量和明确定义的全局变量间有些小的差异,就是通过delete操作符让变量未定义的能力。

  • 通过var创建的全局变量(任何函数之外的程序中创建)是不能被删除的。
  • 无var创建的隐式全局变量(无视是否在函数中创建)是能被删除的。

这表明,在技术上,隐式全局变量并不是真正的全局变量,但它们是全局对象的属性。属性是可以通过delete操作符删除的,而变量是不能的:

// 定义三个全局变量
var global_var = 1;
global_novar = 2; // 反面教材
(function () {
global_fromfunc = 3; // 反面教材
}()); // 试图删除
delete global_var; // false
delete global_novar; // true
delete global_fromfunc; // true // 测试该删除
typeof global_var; // "number"
typeof global_novar; // "undefined"
typeof global_fromfunc; // "undefined"

【JavaScript 从零开始】变量作用域的更多相关文章

  1. [转]深入理解JavaScript的变量作用域

    1.JavaScript的作用域链 2.函数体内部,局部变量的优先级比同名的全局变量高. 3.JavaScript没有块级作用域. 4.函数中声明的变量在整个函数中都有定义. 5.未使用var关键字定 ...

  2. 深入理解JavaScript的变量作用域(转载Rain Man之作)

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

  3. 深入理解JavaScript的变量作用域

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

  4. JavaScript函数变量作用域

    变量作用域 在JavaScript中,用var申明的变量实际上是有作用域的. 如果一个变量在函数体内部申明,则该变量的作用域为整个函数体,在函数体外不可引用该变量. 如果两个不同的函数各自申明了同一变 ...

  5. Javascript之变量作用域

    分析: 无论是强类型语言c#.c++.java等语言,还是弱类型语言如Javascript,所有变量可以抽象为两种类型,即局部变量和全局变量. 全局变量:整个作用域可见. 局部变量:局部可见,退出作用 ...

  6. javascript的变量作用域--对比js、php和c的for循环

    为什么要写这篇文章呢?主要是给自己提个醒,js的水很深,需要小心点儿才能趟过去,更何况自己不是专业人士,那就得更加小心了. 看下面的js代码: <!DOCTYPE html> <ht ...

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

    ShineJaie 原创,转载请注明出处. 昨晚在一个交流群里看到有位网友提了一个他的面试题求助答疑.刚好我也有看到,就对这个问题思考了一下,觉得这道题对理解 JavaScript 作用域还是很有帮助 ...

  8. 浅谈javascript中变量作用域和内存(2)

    1.无块级作用域 javascript没有块级作用域,这会让其他程序员在理解js代码上很痛苦.在其他很多语言,比如C,大括号括起来的代码块都有自己的作用域 举个例子 if(true) { var na ...

  9. JavaScript的变量作用域

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  10. 浅谈javascript的变量作用域

    1.变量遵循先声明再使用. console.log(b); b=123; 代码运行结果: Uncaught ReferenceError: b is not defined 2.方法内定义的局部变量外 ...

随机推荐

  1. 在Windows安装Reids 详解

    今天安装了redis,记录点经验 因为Redis项目没有正式支持Windows. 但Microsoft开发和维护一个针对Windows 64版的redis. 下载地址在微软的GitHub上,地址:ht ...

  2. silverlight chart 折线图 的线颜色如何修改???

    silverlight  chart 折线图 的线颜色如何修改??? 我做出来都是这些偏黄色,请问如何修改线的颜色,以及线的宽度?谢谢

  3. Reservoir Sampling-382. Linked List Random Node

    Given a singly linked list, return a random node's value from the linked list. Each node must have t ...

  4. MySQL数据库中的字段类型varchar和char的主要区别是什么?哪种字段查找效率要高?

    1,varchar与char的区别?(1)区别一,定长和变长,char表示定长,长度固定:varchar表示变长,长度可变.当插入字符串超出长度时,视情况来处理,如果是严格模式,则会拒绝插入并提示错误 ...

  5. Python中获取当前时间 获取当前时间前几天的代码

    当然 需要引入 datetime import datetime 获取当前日期:datetime.datetime.now().strftime('%Y-%m-%d') 获取当前日期前七天日期: no ...

  6. 本地数据库导入线上服务器的mongodb中

    更改默认端口 sudo vi /etc/mongod.conf 进入conf文件,修改port值为19999保存并退出. 重启mongodb sudo service mongod restart 进 ...

  7. Java爬虫——Gecco简单入门程序(根据下一页一直爬数据)

    为了完成作业,所以学习了一下爬虫Gecco,这个爬虫集合了以往所有的爬虫的特点,但是官方教程中关于Gecco的教程介绍的过于简单,本篇博客是根据原博客的地址修改的,原博客中只有程序的截图,而没有给出一 ...

  8. [BZOJ2758] [SCOI2012]Blinker的噩梦 扫描线+set

    题目大意:有n个圆或凸多边形,这些图形不会相交,每当走入或走出一个图形时需要异或上一个代价,有m组操作: 询问操作,每次询问从一个点走到另一个点时,需要的代价(初始代价为0) 修改操作,每次修改一个图 ...

  9. 手机端布局,rem布局动态获取根字体大小

    手机端布局,rem布局动态获取根字体大小. 以下代码: //rem布局动态获取根字体大小 function remDynamicLayout(){ var $windowWidth = $(windo ...

  10. linux初始

    运维 IT运维,指IT公司中,运行和维护服务器的工作 核心工作: ​ 数据不能丢失 ​ 7*24小时运行 ​ 提高用户访问效率 一句换 管服务器的 服务器 要管服务器那就得先了解服务器 服务器也称为伺 ...