目錄
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脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++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與WebSocket:打造高效率的即時影像處理系統 JavaScript與WebSocket:打造高效率的即時影像處理系統 Dec 17, 2023 am 08:41 AM

JavaScript是一種廣泛應用於Web開發的程式語言,而WebSocket則是一種用於即時通訊的網路協定。結合二者的強大功能,我們可以打造一個高效率的即時影像處理系統。本文將介紹如何利用JavaScript和WebSocket來實作這個系統,並提供具體的程式碼範例。首先,我們需要明確指出即時影像處理系統的需求和目標。假設我們有一個攝影機設備,可以擷取即時的影像數

See all articles