深究js(三)——变量

2024-03-15 16:48
文章标签 js 变量 深究

本文主要是介绍深究js(三)——变量,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、变量声明

    在JavaScript中,使用一个变量之前应当声明一个变量,变量是使用关键字var来声明的。如:

var a;
    声明了一个变量未赋值的时候,默认值为underfined。可能你会说,我没有用var声明,也可以直接用这个数也可以啊,如:

a = 10
alert(a)
    这里事先没有声明变量a,而是直接给变量a赋值,当运行的时候也是没问题,乍一看好像问题不大,其实还是有一些问题的。这样子未声明一个变量去使用这个变量的话,这个变量是全局变量,是JavaScript通过在全局对象中创建出来的一个同名属性,但是这是一个不好的习惯,会造成很多bug,在严格模式和ECMAScript标准中是严令禁止这样做的。在eslint中,如果声明了一个变量但是没有赋值也是会报错的。


二、变量作用域

   一个变量的作用域是程序源代码中定义这个变量的区域。全局对象拥有全局作用域,在JavaScript的任何地方都是有定义的,而在函数内声明的变量只在函数内有定义,他们称为局部变量。函数的参数也是一个局部变量,只在函数体内有定义。

    在函数体内,局部变量的优先级高于同名的全局 变量,也就是说当在函数体内局部变量与全局变量同名,全局变量会被局部变量所遮盖掉。如:

var a = 'a'
function ha () {var a = 'b'
    return a
}
alert(ha())    //返回的是b
    局部变量一定要用var声明,如果函数体内的一个变量没有用var声明,而函数体外恰好有这个同名变量,这个时候就能体现出这个陋习的bug了。如:

function ha () {a = 'b'
    return a
}
ha()
alert(a)    //返回的是b
    全局变量a在函数体内被修改了,所以声明变量的时候一定要加一个var,防止出现未知的bug。当声明了一个JavaScript全局变量的时候,实际上是定义了全局对象的一个属性。当使用var来声明变量时,这个创建的属性是不可配置的,也就是说这个变量是无法通过delete运算符删除的,但是没用var声明变量时,变量可以被delete删除。


三、声明提前和函数作用域 

    在java中,花括号内的每一段代码都有各自的作用域,并且变量在声明它们的作用域之外是不可见的,这称之为块级作用域。但是在JavaScript中是没有块级作用域这个概念,取而代之的是函数作用域。在函数作用域里面,变量在声明它们的函数体以及这个函数体嵌套的任意函数体内都是有定义的。如:

var o = new Date()
function test(o) {var i = 0
    if (typeof o == 'object') {var j = 0
        for (var k = 0;k < 10; k++) {console.log(k)}console.log(k)}console.log(j)
}
test(o)
    第一个输出从0到9,第二个输出的是10,第三个输出的是0。用过java的可能会对这个结果产生一些疑问,为什么k和j的值都能够输出来呢?是因为在test()函数内,i,j,k都在同一个函数作用域内,在函数作用域内变量在声明它们的函数体以及这个函数体嵌套的任意函数体内都是有定义的。也就是说,i,j,k变量声明提前了,这样的话上述的代码等价于:

var o = new Date()
function test(o) {var i = 0
    var kvar jif (typeof o == 'object') {j = 0
        for (k = 0;k < 10; k++) {console.log(k)}console.log(k)}console.log(j)
}
test(o)
    JavaScript的函数作用域指的是在函数内声明的所有变量在函数体内始终可见的,这样子会让变量在声明之前已经可用,这一特性被称为声明提前。一个典型的例子如下所示:

var a = 'a'
function aa() {console.log(a)var a = 'b'
    console.log(a)
}
aa()
    如果你以为第一个输出的是a就大错特错了,第一个输出的是underfined,第二个输出的是b。首先在JavaScript里,在函数体内定义一个变量是在整个函数内可见,也就是说即使你的变量声明放在最后写,它仍然会将这个变量声明提前。并且局部变量的优先级比全局变量的优先级高,在给变量a赋值之前它的初始值为underfined,所以上述的代码可以理解成这样:

var a = 'a'
function aa() {var aconsole.log(a)a = 'b'
    console.log(a)
}
aa()
    在JavaScript编程中,如果在函数体内声明变量,尽量的把变量放在前面,这样方便查找变量,也能真实的反映变量的作用域。


四、作用域链

    作用域链是一个对象列表或者链表,这组对象定义了代码中“作用域中”的变。当JavaScript需要查找变量x的值的时候,它会从链中的第一个对象开始查找,如果这个对象有一个名为x的属性,则会直接使用这个属性的值,如果没有则一直找,当作用域链上没有任何一个对象含有属性x,则会报一个引用错误的异常。下面有一个例子是举例说明作用域链的:

var x =1
function a() {var y = 2
    function aa() {var z = 3
        console.log(x + y + z)}aa()
}
a()

    当函数执行到aa()方法里的console,它会找aa()里面有没有变量x和y,没有的话,则向上一级去a()方法里面查找变量x和y,a()方法里有y但是没有x,于是继续向上查找,找到了x,所以输出的结果是6。下面有另一个常见的例子更能说明这个问题:

var a = []
for(var i = 0; i < 3; i ++ ) {a[i] = function () {console.log(i)}
}
a[0]()
a[1]()
a[2]()
    你认为会输出什么?如果你以为输出的是0,1,2其实就是大错特错了。因为在这个匿名函数里,根本就没有声明i这个变量,所以就通过作用域链来向上查找变量i,恰逢此时循环已经遍历完成,最终的i是等于3,所以最后这三个输出的结果为3。有关作用域链这个东西在《JavaScript权威指南》里并没有过多的讲述,由于本人水平有限可能讲的不够详细,特意推荐这两个不错的推文,都是讲作用域链的,作用域链对理解闭包和with语句有很大的帮助,下面就贴上那两个地址给大家参考。

http://www.cnblogs.com/lhb25/archive/2011/09/06/javascript-scope-chain.html

http://www.cnblogs.com/dolphinX/p/3280876.html



这篇关于深究js(三)——变量的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/812617

相关文章

一文全面详解Python变量作用域

《一文全面详解Python变量作用域》变量作用域是Python中非常重要的概念,它决定了在哪里可以访问变量,下面我将用通俗易懂的方式,结合代码示例和图表,带你全面了解Python变量作用域,需要的朋友... 目录一、什么是变量作用域?二、python的四种作用域作用域查找顺序图示三、各作用域详解1. 局部作

使用Python获取JS加载的数据的多种实现方法

《使用Python获取JS加载的数据的多种实现方法》在当今的互联网时代,网页数据的动态加载已经成为一种常见的技术手段,许多现代网站通过JavaScript(JS)动态加载内容,这使得传统的静态网页爬取... 目录引言一、动态 网页与js加载数据的原理二、python爬取JS加载数据的方法(一)分析网络请求1

java变量内存中存储的使用方式

《java变量内存中存储的使用方式》:本文主要介绍java变量内存中存储的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、介绍2、变量的定义3、 变量的类型4、 变量的作用域5、 内存中的存储方式总结1、介绍在 Java 中,变量是用于存储程序中数据

VSCode中配置node.js的实现示例

《VSCode中配置node.js的实现示例》本文主要介绍了VSCode中配置node.js的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着... 目录一.node.js下载安装教程二.配置npm三.配置环境变量四.VSCode配置五.心得一.no

JS+HTML实现在线图片水印添加工具

《JS+HTML实现在线图片水印添加工具》在社交媒体和内容创作日益频繁的今天,如何保护原创内容、展示品牌身份成了一个不得不面对的问题,本文将实现一个完全基于HTML+CSS构建的现代化图片水印在线工具... 目录概述功能亮点使用方法技术解析延伸思考运行效果项目源码下载总结概述在社交媒体和内容创作日益频繁的

Node.js 数据库 CRUD 项目示例详解(完美解决方案)

《Node.js数据库CRUD项目示例详解(完美解决方案)》:本文主要介绍Node.js数据库CRUD项目示例详解(完美解决方案),本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考... 目录项目结构1. 初始化项目2. 配置数据库连接 (config/db.js)3. 创建模型 (models/

使用Node.js制作图片上传服务的详细教程

《使用Node.js制作图片上传服务的详细教程》在现代Web应用开发中,图片上传是一项常见且重要的功能,借助Node.js强大的生态系统,我们可以轻松搭建高效的图片上传服务,本文将深入探讨如何使用No... 目录准备工作搭建 Express 服务器配置 multer 进行图片上传处理图片上传请求完整代码示例

用js控制视频播放进度基本示例代码

《用js控制视频播放进度基本示例代码》写前端的时候,很多的时候是需要支持要网页视频播放的功能,下面这篇文章主要给大家介绍了关于用js控制视频播放进度的相关资料,文中通过代码介绍的非常详细,需要的朋友可... 目录前言html部分:JavaScript部分:注意:总结前言在javascript中控制视频播放

Node.js net模块的使用示例

《Node.jsnet模块的使用示例》本文主要介绍了Node.jsnet模块的使用示例,net模块支持TCP通信,处理TCP连接和数据传输,具有一定的参考价值,感兴趣的可以了解一下... 目录简介引入 net 模块核心概念TCP (传输控制协议)Socket服务器TCP 服务器创建基本服务器服务器配置选项服

mac安装nvm(node.js)多版本管理实践步骤

《mac安装nvm(node.js)多版本管理实践步骤》:本文主要介绍mac安装nvm(node.js)多版本管理的相关资料,NVM是一个用于管理多个Node.js版本的命令行工具,它允许开发者在... 目录NVM功能简介MAC安装实践一、下载nvm二、安装nvm三、安装node.js总结NVM功能简介N