深刻理解 JavaScript中的變量、值、傳參

圖片描述

1. demo

若是你對下面的代碼沒有任何疑問就能自信的回答出輸出的內容,那麼本篇文章就不值得你浪費時間了。javascript

var var1 = 1
var var2 = true
var var3 = [1,2,3]
var var4 = var3

function test (var1, var3) {
    var1 = 'changed'
    var3[0] = 'changed'
    var3 = 'changed'
}

test(var1, var3)

console.log(var1, var2, var3, var4)

2. 深刻理解原始類型

原始類型有5個 Undefinded, Null, Boolean, Number, Stringjava

2.1. 原始類型變量沒有屬性和方法

// 擡槓, 下面的length屬性,toString方法怎麼有屬性和方法呢?
var a = 'oooo'
a.length
a.toString

原始類型中,有三個特殊的引用類型Boolean, Number, String,在操做原始類型時,原始類型變量會轉換成對應的基本包裝類型變量去操做。參考JavaScript高級程序設計 5.6 基本包裝類型。node

因此說:在js中,也並非一切都是對象git

2.2. 原始類型值不可變

原始類型的變量的值是不可變的,只能給變量賦予新的值。github

下面給出例子web

// str1 開始的值是aaa
var str1 = 'aaa'
// 首先建立一個能容納6個字符串的新字符串
// 而後再這個字符串中填充 aaa和bbb
// 最後銷燬字符串 aaa和bbb
// 而不能理解成在str1的值aaa後追加bbb
str1 = str1 + 'bbb'

其餘原始類型的值也是不可變的, 例如數值類型的。segmentfault

2.3. 原始類型值是字面量

3. 變量和值有什麼區別?

  • 不是每個值都有地址,但每個變量有。《Go程序設計語言》
  • 變量沒有類型,值有。變量能夠用來保存任何類型的值。《You-Dont-Know-JS》

變量都是有內存地址的,變量有用來保存各類類型的值;不一樣類型的值,佔用的空間不一樣。數組

var a = 1
typeof a // 檢測的不是變量a的類型,而是a的值1的類型

4. 變量訪問有哪些方式?

變量訪問的方式有兩種:微信

  1. 按值訪問
  2. 按引用訪問

在JS中,五種基本類型Undefinded, Null, Boolean, Number, String是按照值訪問的。基本類型變量的值就是字面上表示的值。而引用類型的值是指向該對象的指針,而指針能夠理解爲內存地址。wordpress

能夠理解基本類型的變量的值,就是字面上寫的數值。而引用類型的值則是一個內存地址。可是這個內存地址,對於程序來講,是透明不可見的。不管是Get仍是Set都沒法操做這個內存地址。

下面是個示意表格。

語句 變量 Get 訪問類型
var a = 1 a 1 1 按值
var a = [] a 0x00000320 [] 按引用
擡槓 Undefinded, Null, Boolean, Number是基本類型能夠理解,由於這些類型的變量所佔用的內存空間都是大小固定的。可是 string類型的變量,字符串的長短都是不同的,也就是說,字符串佔用的內存空間大小是不固定的,爲何string被列爲按值訪問呢?

基本類型和引用類型的本質區別是,當這個變量被分配值時,它須要向操做系統申請內存資源,若是你向操做系統申請的內存空間的大小是固定的,那麼就是基本類型,反之,則爲引用類型。

5. 例子的解釋

var var1 = 1
var var2 = true
var var3 = [1,2,3]
var var4 = var3

function test (var1, var3) {
    var1 = 'changed' // a
    var3[0] = 'changed' // b
    var3 = 'changed' // c
}

test(var1, var3)

console.log(var1, var2, var3, var4)

上面的js分爲兩個調用棧,在

  • 圖1 外層的調用棧。有四個變量v一、v二、v三、v4
  • 圖2 調用test是傳參,內層的v一、v3會屏蔽外層的v一、v3。內層的v1,v3和外層的v一、v3內存地址是不一樣的。內層v1和外層v1已經沒有任何關係了,可是內層的v3和外層v3仍然指向同一個數組。
  • 圖3 內層的v1的值被改變成'changed‘, v3[0]的值被改變爲'changed'。
  • 圖4 內層v3的值被重寫爲字符串changed, 完全斷了與外層v3聯繫。
  • 圖5 當test執行完畢,內層的v1和v3將不會存在,ox75和ox76位置的內存空間也會被釋放

最終的輸出:

1 true ["changed", 2, 3] ["changed", 2, 3]

6. 如何深刻學習JS、Node.js

看完兩個stackoverflow上兩個按照投票數量的榜單

若是學習有捷徑的話,踩一遍別人踩過的坑,可能就是捷徑。

7. 參考

掃碼訂閱個人微信公衆號:洞香春天。天天一篇技術短文,讓知識再也不高冷。

相關文章
相關標籤/搜索