目录
JS变量包含两种不同的数据类型:基本数据类型(值类型)与引用数据类型(复杂数据类型)。
接下来我们分别看一下基本数据类型与引用类型的比较
再来看一下关于基本类型与引用类型作为函数中的参数问题
终于聊到作用域啦!JS变量作用域,就是指变量所影响的范围。JS中作用域分为全局作用域与局部作用域(函数作用域)。在全局作用域内定义的变量为全局变量,在局部作用域内定义的变量为局部变量。
变量的生命周期
首页 web前端 js教程 详解JavaScript的变量及作用域

详解JavaScript的变量及作用域

Jun 11, 2018 pm 05:47 PM
javascript

假如你没去过天安门、故宫、长城相当于你没到过北京。假如你搞不懂JS变量的作用域,相当于你没学过JS。关于JS变量作用域的重要性自己好好悟吧!提示:查看本文章记得看注释哦!

JS是一门弱类型(松散型)的语言,这也就是说其天生就与众不同,独领风骚!
在讲解变量作用域之前,我们先来了解一下JS中的变量。JS中的变量与其它语言有很大的不同,由于JS变量拥有松散(不强制)的本质,从而决定了其只是一个在特定阶段保持特定类型值的名字。

JS变量包含两种不同的数据类型:基本数据类型(值类型)与引用数据类型(复杂数据类型)。

基本数据类型的值保存在栈内存中。而引用数据类型的值则保存在堆内存中,在栈内存中只保留引用类型的指针地址。
基本类型值有以下五种:undefined,Null,Boolean,Number和String。基本数据类型的值保存在栈内存中。

//在栈内存中开辟一块空间存储值为"laotie"的变量namevar name="laotie";//在栈内存中开辟一块空间存储值为"laotie"的变量name2var name2=name;//name与name2是相对独立的,所以改变name2的值为"xiaozhang",而name的值不会受到影响var name2="xiaozhang";
console.log(name);//laotieconsole.log(name2);//xiaozhang
登录后复制

再来看一下引用类型:

/*在栈内存中存放 obj的地址
* 其值存放在堆内存中。
* 栈内存的地址的指向堆内存中的值。*/var obj={
    name:"zhangpeiyue"}/*将obj的地址赋值给obj2
所以在栈内存中存储的地址与obj的地址相同,
obj与obj2共享同一个值。
*/var obj2=obj;
obj2.name="xiaozhang";//因为obj与obj2共享同一个值,所以上行代码改变的是同一个值console.log(obj.name);//xiaozhang
 //你也可以认为obj即为obj2,引用类型比较的是地址,因此为trueconsole.log(obj==obj2);//true
登录后复制
接下来我们分别看一下基本数据类型与引用类型的比较
  • 基本数据类型的比较,比较的是值:

//基本数据类型比较的是值,只要值相等比较结果即为truevar a=1;var b=1;console.log(a==b);//truevar c=2;var d=c;console.log(c==d);//true
登录后复制
  • 引用类型的比较,比较的是地址:

var obj={
    age:12}var obj2={
    age:12}//引用类型比较的是地址,而不是值。//由于每次创建的引用类型地址都不同,所以结果为falseconsole.log(obj==obj2);//falsevar obj3={
    age:12}//将obj3的地址赋值给obj4。所以地址相同var obj4=obj3;//由于比较的是地址,且obj3与obj4的地址相同,所以结果为trueconsole.log(obj3==obj4);
登录后复制
再来看一下关于基本类型与引用类型作为函数中的参数问题
  • 基本类型作为参数,参数为局部变量

/*接收的所有基本数据类型,接收的是其值。
接收的参数都是函数体中的局部变量。
在函数体内改变值,对外部不会产生任何影响*/function fn(a){
    a+=1;
    console.log(a);//14}
var a=13;fn(a);
console.log(a);//13
登录后复制
  • 引用数据类型作为参数,参数为全局变量

/*引用数据类型传递的是引用地址,
因此函数体中的obj与函数外的obj的引用地址相同。
所以函数体中的obj与函数外的obj共享同一值,
改变其中一个值,其它的也会随之改变
*/function fn(obj){
    obj.name="laowang"
    console.log(obj.name);//laowang}
var obj={
    name:"laotie"}fn(obj);
console.log(obj.name);//laowang
登录后复制
终于聊到作用域啦!JS变量作用域,就是指变量所影响的范围。JS中作用域分为全局作用域与局部作用域(函数作用域)。在全局作用域内定义的变量为全局变量,在局部作用域内定义的变量为局部变量。

全局作用域是最外围定义的作用域,在web浏览器中全局作用域指的是window对象。因此在全局作用域定义的变量和函数,你可以认为是window对象的属性与方法!

var color="red";//定义一个全局colorfunction fn(){
    color="blue";//全局函数可以在函数内访问}fn();
console.log(color);//blue
登录后复制
  • 全局的变量和函数,都是window对象的属性和方法。

var color="red";//定义一个全局colorfunction fn(){    color="blue";//全局函数可以在函数内访问}window.fn();
console.log(window.color);//blue
登录后复制
  • 函数作用域内的声明的变量与全局作用域内声明的变量同名

var color="yellow";//定义全局变量colorfunction fn(){    //在函数体内如果拥有指定的变量,就不会去外层查找
    var color="red";//这里是局部变量color,外面是访问不到的哦
    console.log(color);//red}fn();
console.log(color);//yellow
登录后复制
  • 通过传参。传递的参数为基本类型,参数在函数体内是局部变量。传递的参数为引用类型,参数在函数体内是全局变量。文章开始已涉及过,在此不在解释!

  • 如果函数体内存在子函数,则只有该函数才可以访问子函数。

var color="green";function fn(){
    //子函数是建议以下划线开头
    function _fn2(){
        var color2="orange";
        console.log(color);//green
        console.log(color2);//orange
    }
    _fn2();//_fn2()的作用域在fn()内}
fn();
_fn2();//在此处调用fn2()是调取不到的
登录后复制

注意:当在一个作用域内执行代码时,就会有一个被称为作用域链的东西。它的作用是保证对变量与方法访问的有序性。也就是当前执行环境中存在指定的变量或方法就不会去外围查找,如果没有则会向外围查找,直到找到为止!如果找不到会报错!一层层向外寻找指定变量和方法的行为,形成了一个作链条。这个链条就是作用域链。访问局部变量要比全局变量快许多,因为不需要向外围查找(向上查找)指定的变量。
* JS没有块级作用域,所谓块级作用域指的是if,for等语句用花括号包裹的代码!

if(true){    var name="zhang";
}
console.log(name);//zhang
登录后复制

当你在函数中声明一个没有带上var关键字的变量时,这个变量就会成为全局变量。不过这种行为很容易造成命名冲突,所以非常不推荐大家使用!

function fn(){    //此处a=12相当于window.a=12。
    a=12;//声明一个不带var关键字的变量}fn();
console.log(a);//12
登录后复制

这是因为fn函数是在window环境下运行的,由此函数体内的a=12相当于执行了window.a=12。而window是JS的顶级对象。也可以认为我们为顶级对象增加了值为12的a属性。所以变量a就成为了全局变量。
另外如果函数体内的变量是通过var关键字声明的,则该变量为局部变量,只能在该函数体内进行访问,函数体外是访问不到的。

function fn(){
    var a=12;
    console.log(a);//12}fn();
console.log(a);//报错:a is not defined
登录后复制
  • 分享一道阿里关于作用域的面试题:

var obj = {
    b: 2};var fn = function () {};
fn.c = 3;function test(x, y, z) {
    x = 4;
    y.b = 5;
    z.c = 6;    return z;
}
test(a, obj, fn);
console.log(a + obj.b + fn.c);//12
登录后复制
变量的生命周期

所谓变量的生命周期指的是变量由声明到销毁。
对于全局变量来讲,其生命周期是永久的,除非我们主动去销毁这个全局变量。而在函数体内声明的局部变量,当函数运行完以后,局部变量就失去了任何价值,它们也会随着函数的执行完毕而销毁。

var fn=function(){
    var a=1;//退出函数后,局部变量a会销毁
    console.log(a);
}fn();
登录后复制
  • JS环境中分配的内存一般有如下生命周期
    内存分配:当我们声明变量、函数、对象的时候,系统会自动为他们分配内存
    内存使用:即读写内存,也就是使用变量、函数等
    内存回收:使用完毕,由垃圾回收自动回收不再使用的内存 

  • 本文讲解了JavaScript的变量及作用域,更多相关内容请关注php中文网。

  • 相关推荐:

  • 关于$.ajax()方法参数详解

  • 讲解数学对象Math相关内容

  • 关于JS和JSP的区别讲解

以上是详解JavaScript的变量及作用域的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解锁Myrise中的所有内容
4 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

如何使用WebSocket和JavaScript实现在线语音识别系统 如何使用WebSocket和JavaScript实现在线语音识别系统 Dec 17, 2023 pm 02:54 PM

如何使用WebSocket和JavaScript实现在线语音识别系统引言:随着科技的不断发展,语音识别技术已经成为了人工智能领域的重要组成部分。而基于WebSocket和JavaScript实现的在线语音识别系统,具备了低延迟、实时性和跨平台的特点,成为了一种被广泛应用的解决方案。本文将介绍如何使用WebSocket和JavaScript来实现在线语音识别系

WebSocket与JavaScript:实现实时监控系统的关键技术 WebSocket与JavaScript:实现实时监控系统的关键技术 Dec 17, 2023 pm 05:30 PM

WebSocket与JavaScript:实现实时监控系统的关键技术引言:随着互联网技术的快速发展,实时监控系统在各个领域中得到了广泛的应用。而实现实时监控的关键技术之一就是WebSocket与JavaScript的结合使用。本文将介绍WebSocket与JavaScript在实时监控系统中的应用,并给出代码示例,详细解释其实现原理。一、WebSocket技

如何利用JavaScript和WebSocket实现实时在线点餐系统 如何利用JavaScript和WebSocket实现实时在线点餐系统 Dec 17, 2023 pm 12:09 PM

如何利用JavaScript和WebSocket实现实时在线点餐系统介绍:随着互联网的普及和技术的进步,越来越多的餐厅开始提供在线点餐服务。为了实现实时在线点餐系统,我们可以利用JavaScript和WebSocket技术。WebSocket是一种基于TCP协议的全双工通信协议,可以实现客户端与服务器的实时双向通信。在实时在线点餐系统中,当用户选择菜品并下单

如何使用WebSocket和JavaScript实现在线预约系统 如何使用WebSocket和JavaScript实现在线预约系统 Dec 17, 2023 am 09:39 AM

如何使用WebSocket和JavaScript实现在线预约系统在当今数字化的时代,越来越多的业务和服务都需要提供在线预约功能。而实现一个高效、实时的在线预约系统是至关重要的。本文将介绍如何使用WebSocket和JavaScript来实现一个在线预约系统,并提供具体的代码示例。一、什么是WebSocketWebSocket是一种在单个TCP连接上进行全双工

JavaScript和WebSocket:打造高效的实时天气预报系统 JavaScript和WebSocket:打造高效的实时天气预报系统 Dec 17, 2023 pm 05:13 PM

JavaScript和WebSocket:打造高效的实时天气预报系统引言:如今,天气预报的准确性对于日常生活以及决策制定具有重要意义。随着技术的发展,我们可以通过实时获取天气数据来提供更准确可靠的天气预报。在本文中,我们将学习如何使用JavaScript和WebSocket技术,来构建一个高效的实时天气预报系统。本文将通过具体的代码示例来展示实现的过程。We

简易JavaScript教程:获取HTTP状态码的方法 简易JavaScript教程:获取HTTP状态码的方法 Jan 05, 2024 pm 06:08 PM

JavaScript教程:如何获取HTTP状态码,需要具体代码示例前言:在Web开发中,经常会涉及到与服务器进行数据交互的场景。在与服务器进行通信时,我们经常需要获取返回的HTTP状态码来判断操作是否成功,根据不同的状态码来进行相应的处理。本篇文章将教你如何使用JavaScript获取HTTP状态码,并提供一些实用的代码示例。使用XMLHttpRequest

javascript中如何使用insertBefore javascript中如何使用insertBefore Nov 24, 2023 am 11:56 AM

用法:在JavaScript中,insertBefore()方法用于在DOM树中插入一个新的节点。这个方法需要两个参数:要插入的新节点和参考节点(即新节点将要被插入的位置的节点)。

如何在JavaScript中获取HTTP状态码的简单方法 如何在JavaScript中获取HTTP状态码的简单方法 Jan 05, 2024 pm 01:37 PM

JavaScript中的HTTP状态码获取方法简介:在进行前端开发中,我们常常需要处理与后端接口的交互,而HTTP状态码就是其中非常重要的一部分。了解和获取HTTP状态码有助于我们更好地处理接口返回的数据。本文将介绍使用JavaScript获取HTTP状态码的方法,并提供具体代码示例。一、什么是HTTP状态码HTTP状态码是指当浏览器向服务器发起请求时,服务

See all articles