详解JavaScript的变量及作用域

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

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

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

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

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

登录后复制

再来看一下引用类型:

  1. /*在栈内存中存放 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

登录后复制

接下来我们分别看一下基本数据类型与引用类型的比较

基本数据类型的比较,比较的是值:

  1. //基本数据类型比较的是值,只要值相等比较结果即为truevar a=1;var b=1;console.log(a==b);//truevar c=2;var d=c;console.log(c==d);//true

登录后复制

引用类型的比较,比较的是地址:

  1. 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);

登录后复制

再来看一下关于基本类型与引用类型作为函数中的参数问题

基本类型作为参数,参数为局部变量

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

登录后复制

引用数据类型作为参数,参数为全局变量

  1. /*引用数据类型传递的是引用地址,因此函数体中的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对象的属性与方法!

  1. var color="red";//定义一个全局colorfunction fn(){    color="blue";//全局函数可以在函数内访问}fn();console.log(color);//blue

登录后复制

全局的变量和函数,都是window对象的属性和方法。

  1. var color="red";//定义一个全局colorfunction fn(){    color="blue";//全局函数可以在函数内访问}window.fn();console.log(window.color);//blue

登录后复制

函数作用域内的声明的变量与全局作用域内声明的变量同名

  1. var color="yellow";//定义全局变量colorfunction fn(){    //在函数体内如果拥有指定的变量,就不会去外层查找    var color="red";//这里是局部变量color,外面是访问不到的哦    console.log(color);//red}fn();console.log(color);//yellow

登录后复制

通过传参。传递的参数为基本类型,参数在函数体内是局部变量。传递的参数为引用类型,参数在函数体内是全局变量。文章开始已涉及过,在此不在解释!

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

  1. 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等语句用花括号包裹的代码!

  1. if(true){    var name="zhang";}console.log(name);//zhang

登录后复制

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

  1. 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关键字声明的,则该变量为局部变量,只能在该函数体内进行访问,函数体外是访问不到的。

  1. function fn(){    var a=12;    console.log(a);//12}fn();console.log(a);//报错:a is not defined

登录后复制

分享一道阿里关于作用域的面试题:

  1. var obj = {    b: 2};var fn = function () {};fn.= 3;function test(x, y, z) {    x = 4;    y.= 5;    z.= 6;    return z;}test(a, obj, fn);console.log(+ obj.+ fn.c);//12

登录后复制

变量的生命周期

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

  1. var fn=function(){    var a=1;//退出函数后,局部变量a会销毁    console.log(a);}fn();

登录后复制

JS环境中分配的内存一般有如下生命周期
内存分配:当我们声明变量、函数、对象的时候,系统会自动为他们分配内存
内存使用:即读写内存,也就是使用变量、函数等
内存回收:使用完毕,由垃圾回收自动回收不再使用的内存 

本文讲解了JavaScript的变量及作用域,更多相关内容请关注【创想鸟】。

相关推荐:

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

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

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

以上就是详解JavaScript的变量及作用域的详细内容,更多请关注【创想鸟】其它相关文章!

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。
编程技术

仿淘宝的JSsearch搜索(详细教程)

2025-3-31 22:24:40

编程技术

在jquery中on和click的区别有哪些?

2025-3-31 22:24:52

0 条回复 A文章作者 M管理员
欢迎您,新朋友,感谢参与互动!
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
私信列表
搜索