深究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

相关文章

前端原生js实现拖拽排课效果实例

《前端原生js实现拖拽排课效果实例》:本文主要介绍如何实现一个简单的课程表拖拽功能,通过HTML、CSS和JavaScript的配合,我们实现了课程项的拖拽、放置和显示功能,文中通过实例代码介绍的... 目录1. 效果展示2. 效果分析2.1 关键点2.2 实现方法3. 代码实现3.1 html部分3.2

JS 实现复制到剪贴板的几种方式小结

《JS实现复制到剪贴板的几种方式小结》本文主要介绍了JS实现复制到剪贴板的几种方式小结,包括ClipboardAPI和document.execCommand这两种方法,具有一定的参考价值,感兴趣的... 目录一、Clipboard API相关属性方法二、document.execCommand优点:缺点:

浅析Rust多线程中如何安全的使用变量

《浅析Rust多线程中如何安全的使用变量》这篇文章主要为大家详细介绍了Rust如何在线程的闭包中安全的使用变量,包括共享变量和修改变量,文中的示例代码讲解详细,有需要的小伙伴可以参考下... 目录1. 向线程传递变量2. 多线程共享变量引用3. 多线程中修改变量4. 总结在Rust语言中,一个既引人入胜又可

Node.js 中 http 模块的深度剖析与实战应用小结

《Node.js中http模块的深度剖析与实战应用小结》本文详细介绍了Node.js中的http模块,从创建HTTP服务器、处理请求与响应,到获取请求参数,每个环节都通过代码示例进行解析,旨在帮... 目录Node.js 中 http 模块的深度剖析与实战应用一、引言二、创建 HTTP 服务器:基石搭建(一

java如何调用kettle设置变量和参数

《java如何调用kettle设置变量和参数》文章简要介绍了如何在Java中调用Kettle,并重点讨论了变量和参数的区别,以及在Java代码中如何正确设置和使用这些变量,避免覆盖Kettle中已设置... 目录Java调用kettle设置变量和参数java代码中变量会覆盖kettle里面设置的变量总结ja

Perl 特殊变量详解

《Perl特殊变量详解》Perl语言中包含了许多特殊变量,这些变量在Perl程序的执行过程中扮演着重要的角色,:本文主要介绍Perl特殊变量,需要的朋友可以参考下... perl 特殊变量Perl 语言中包含了许多特殊变量,这些变量在 Perl 程序的执行过程中扮演着重要的角色。特殊变量通常用于存储程序的

使用Vue.js报错:ReferenceError: “Vue is not defined“ 的原因与解决方案

《使用Vue.js报错:ReferenceError:“Vueisnotdefined“的原因与解决方案》在前端开发中,ReferenceError:Vueisnotdefined是一个常见... 目录一、错误描述二、错误成因分析三、解决方案1. 检查 vue.js 的引入方式2. 验证 npm 安装3.

JS常用组件收集

收集了一些平时遇到的前端比较优秀的组件,方便以后开发的时候查找!!! 函数工具: Lodash 页面固定: stickUp、jQuery.Pin 轮播: unslider、swiper 开关: switch 复选框: icheck 气泡: grumble 隐藏元素: Headroom

变量与命名

引言         在前两个课时中,我们已经了解了 Python 程序的基本结构,学习了如何正确地使用缩进来组织代码,并且知道了注释的重要性。现在我们将进一步深入到 Python 编程的核心——变量与命名。变量是我们存储数据的主要方式,而合理的命名则有助于提高代码的可读性和可维护性。 变量的概念与使用         在 Python 中,变量是一种用来存储数据值的标识符。创建变量很简单,

在JS中的设计模式的单例模式、策略模式、代理模式、原型模式浅讲

1. 单例模式(Singleton Pattern) 确保一个类只有一个实例,并提供一个全局访问点。 示例代码: class Singleton {constructor() {if (Singleton.instance) {return Singleton.instance;}Singleton.instance = this;this.data = [];}addData(value)