亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JavaScript > 正文

深入理解JavaScript的值傳遞和引用傳遞

2019-11-19 12:38:24
字體:
來源:轉載
供稿:網友

JavaScript有5種基本的數據類型,分別是:布爾、null、undefined、String和Number。這些基本類型在賦值的時候是通過值傳遞的方式。值得注意的是還有另外三種類型: Array、Function和Object,它們通過引用來傳遞。從底層技術上看,它們三都是對象。

基本數據類型

如果一個基本的數據類型綁定到某個變量,我們可以認為該變量包含這個基本數據類型的值。

var x = 10;var y = 'abc';var z = null;

當我們使用=將這些變量賦值到另外的變量,實際上是將對應的值拷貝了一份,然后賦值給新的變量。我們把它稱作值傳遞。

var x = 10;var y = 'abc';var a = x;var b = y;console.log(x, y, a, b) // 10, 'abc', 10, 'abc'

a和x都包含10,b和y都包含'abc',并且它們是完全獨立的拷貝,互不干涉。如果我們將a的值改變,x不會受到影響。

var x = 10;var y = 'abc';var a = x;var b = y;a = 5;b = 'def';console.log(x, y, a, b); // 10, 'abc', 5, 'def'

對象

如果一個變量綁定到一個非基本數據類型(Array, Function, Object),那么它只記錄了一個內存地址,該地址存放了具體的數據。注意之前提到指向基本數據類型的變量相當于包含了數據,而現在指向非基本數據類型的變量本身是不包含數據的。

對象在內存中被創建,當我們聲明arr = [],我們在內存中創建了一個數組。arr記錄的是該內存的地址。

var arr = []; // (a)arr.push(1); // (b)

當執行完(a)之后,內存中創建了一個空的數組對象,其內存地址為#001,arr指向該地址。

變量 地址 對象
arr #001 []

當執行完(b)之后,數組對象中多了一個元素,但是數組的地址依然沒有變,arr也沒有變。

變量 地址 對象
arr #001 [1]

引用傳遞

對象是通過引用傳遞,而不是值傳遞。也就是說,變量賦值只會將地址傳遞過去。

var reference = [1];var refCopy = reference;

變量 地址 對象
reference #001 [1]
refCopy #001

reference和refCopy指向同一個數組。 如果我們更新reference,refCopy也會受到影響。

reference.push(2);console.log(reference, refCopy); // [1, 2], [1, 2]

變量 地址 對象
reference #001 [1, 2]
refCopy #001

引用重新賦值

如果我們將一個已經賦值的變量重新賦值,那么它將包含新的數據或則引用地址。

var obj = { first: 'fundebug.com'};obj = { second: 'fundebug.cn'};

obj從指向第一個對象變為指向第二個對象。

變量 地址 對象
obj #001 {first: ‘fundebug.com'}
#002 {second: ‘fundebug.cn'}

如果一個對象沒有被任何變量指向,就如第一個對象(地址為#001),JavaScript引擎的垃圾回收機制會將該對象銷毀并釋放內存。

== 和 ===

對于引用類型的變量,==和===只會判斷引用的地址是否相同,而不會判斷對象具體里屬性以及值是否相同。因此,如果兩個變量指向相同的對象,則返回true。

var arrRef = ['Hi!'];var arrRef2 = arrRef;console.log(arrRef === arrRef2); // true

如果是不同的對象,及時包含相同的屬性和值,也會返回false。

var arr1 = ["Hi!"];var arr2 = ["Hi!"];console.log(arr1 === arr2); // false

如果想判斷兩個不同的對象是否真的相同,一個簡單的方法就是將它們轉換為字符串然后判斷。

var arr1str = JSON.stringify(arr1);var arr2str = JSON.stringify(arr2);console.log(arr1str === arr2str); // true

另一個方法就是遞歸地判斷每一個屬性的值,直到基本類型位置,然后判斷是否相同。

函數參數

當我們將基本類型數據傳入函數,函數會將這些數據拷貝賦值給函數的參數變量。

var hundred = 100;var two = 2;function multiply(x, y) { return x * y;}var twoHundred = multiply(hundred, two);

hundred的值拷貝給變量x,two的值拷貝給變量y。

純函數

對于一個函數,給定一個輸入,返回一個唯一的輸出。除此之外,不會對外部環境產生任何附帶影響。我們機會稱該函數為純函數。所有函數內部定義的變量在函數返回之后都被垃圾回收掉。

但是,如果函數的輸入是對象(Array, Function, Object),那么傳入的是一個引用。對該變量的操作將會影響到原本的對象。這樣的編程手法將產生附帶影響,是的代碼的邏輯復雜和可讀性變低。

因此,很多數組函數,比如Array.map和Array.filter是以純函數的形式實現。雖然它們的參數是一個數組變量,但是通過深度拷貝并賦值給一個新的變量,然后在新的數組上操作,來防止原始數組被更改。

我們來看一個例子:

function changeAgeImpure(person) { person.age = 25; return person;}var alex = { name: 'Alex', age: 30};var changedAlex = changeAgeImpure(alex);console.log(alex); // { name: 'Alex', age: 25 }console.log(changedAlex); // { name: 'Alex', age: 25 }

在非純函數changeAgeImpure中,將對象person的age更新并返回。原始的alex對象也被影響,age更新為25。

讓我們來看如何實現一個純函數:

function changeAgePure(person) { var newPersonObj = JSON.parse(JSON.stringify(person)); newPersonObj.age = 25; return newPersonObj;}var alex = { name: 'Alex', age: 30};var alexChanged = changeAgePure(alex);console.log(alex); // { name: 'Alex', age: 30 }console.log(alexChanged); // { name: 'Alex', age: 25 }

我們通過JSON.sringify將對象變為一個字符串,然后再通過JSON.parse將字符串變回對象。通過該操作會生成一個新的對象。

一道簡單的面試題

值傳遞和引用傳遞經常在面試中被問到,來嘗試回答一下如下代碼如何輸出:

function changeAgeAndReference(person) { person.age = 25; person = { name: 'John', age: 50 }; return person;}var personObj1 = { name: 'Alex', age: 30};var personObj2 = changeAgeAndReference(personObj1);console.log(personObj1); // -> ?console.log(personObj2); // -> ?

總結

以上所述是小編給大家介紹的JavaScript的值傳遞和引用傳遞,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對武林網網站的支持!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产亚洲精品成人av久久ww| 黑人巨大精品欧美一区免费视频| 亚洲天堂网在线观看| 精品久久在线播放| 国产一区二区精品丝袜| 亚洲少妇中文在线| 欧美夫妻性生活视频| 中文字幕日韩在线播放| 国产精品美女主播| 国产精品女人久久久久久| 久久亚洲春色中文字幕| 欧美性猛交xxxx免费看漫画| 中文字幕一精品亚洲无线一区| 97超级碰碰碰| 成人免费观看49www在线观看| 国产精品香蕉在线观看| 欧美日韩美女在线| 日韩女优在线播放| 国内免费精品永久在线视频| 日韩在线小视频| 欧美日韩中国免费专区在线看| 国产精品美女久久久免费| 欧美激情第一页xxx| 久久精品中文字幕| 精品美女久久久久久免费| 精品国产福利在线| 日韩成人激情影院| 成人午夜在线影院| 日本精品久久久久久久| 久久在线视频在线| 国产有码在线一区二区视频| 精品国模在线视频| 日韩av中文字幕在线免费观看| 国产精品久久久久久久久免费| 尤物九九久久国产精品的特点| 国产成人精品av| 久久久午夜视频| 国产精品99久久99久久久二8| 国产精品爱啪在线线免费观看| 国产精品成久久久久三级| 日韩人体视频一二区| 美女精品视频一区| 成人精品一区二区三区电影免费| 久久精品亚洲94久久精品| 色一区av在线| 午夜伦理精品一区| 在线免费看av不卡| 日韩在线www| 国产第一区电影| 欧美丰满老妇厨房牲生活| 亚洲精品成人久久电影| 国语自产精品视频在线看抢先版图片| 日韩av免费在线播放| 国产一区二区黑人欧美xxxx| 最近2019年手机中文字幕| 亚洲国产精品资源| 91国产精品视频在线| 亚洲久久久久久久久久久| 九九久久久久久久久激情| 亚洲色图美腿丝袜| 日日骚久久av| 亚洲一级免费视频| 国产精品久久久久免费a∨大胸| 色综合久久久久久中文网| 欧美大学生性色视频| 国产精品 欧美在线| 亚洲二区中文字幕| 欧美国产日韩精品| 国产精品第3页| 久热国产精品视频| 91久久夜色精品国产网站| 国产在线精品自拍| 91久久久亚洲精品| 黑人欧美xxxx| 777国产偷窥盗摄精品视频| 中文字幕亚洲精品| 日韩免费观看av| 在线日韩中文字幕| 欧美日韩在线第一页| 久久成人综合视频| 琪琪第一精品导航| 欧美日韩裸体免费视频| 曰本色欧美视频在线| 亚洲成色777777在线观看影院| 国产成人精品视频在线| 欧美视频免费在线观看| 欧美成人激情图片网| 91免费综合在线| 亚洲欧洲在线视频| 中文字幕日韩av电影| 欧美黑人国产人伦爽爽爽| 日韩电影中文字幕| 91亚洲va在线va天堂va国| 精品偷拍各种wc美女嘘嘘| 亚洲国产一区二区三区四区| 国产精品稀缺呦系列在线| 欧美精品国产精品日韩精品| 久久99精品久久久久久青青91| 精品久久久视频| 欧美一区第一页| 91在线视频精品| 色偷偷9999www| 中文在线资源观看视频网站免费不卡| 视频在线观看99| 日本精品性网站在线观看| 欧美体内谢she精2性欧美| 亚洲福利在线观看| 成人欧美一区二区三区在线| 国语自产在线不卡| 国产精品v日韩精品| 欧美电影免费观看高清| 亚洲欧美激情精品一区二区| 日韩高清av一区二区三区| 国产精品热视频| 国产日产久久高清欧美一区| 国产精品第一视频| 日本国产欧美一区二区三区| 欧美精品激情在线| 91影院在线免费观看视频| 成人在线视频网站| 日韩电影免费在线观看中文字幕| 亚洲精品国产精品国产自| 77777少妇光屁股久久一区| 亚洲精品一区二区三区婷婷月| 欧美中文字幕精品| 日韩欧美在线视频日韩欧美在线视频| 久久精品中文字幕免费mv| 亚洲在线视频观看| 精品福利一区二区| 国产精品一区二区av影院萌芽| 中文字幕欧美在线| 色av吧综合网| 97国产在线观看| 亚洲激情在线观看| 国产91在线高潮白浆在线观看| 欧美精品999| 欧美成人免费一级人片100| 亚洲欧洲日产国产网站| 日韩在线视频网| 久久久久久久一区二区| 欧日韩不卡在线视频| 国产成人极品视频| 91成人在线视频| 国产网站欧美日韩免费精品在线观看| 这里只有视频精品| 欧美在线一级va免费观看| 久久久99久久精品女同性| 国产成人在线一区| 国产精品久久91| 秋霞av国产精品一区| 国产91色在线|免| 亚洲午夜av久久乱码| 97精品一区二区视频在线观看| 色在人av网站天堂精品| 97久久精品人搡人人玩| 国模吧一区二区| 日韩在线激情视频| 亚洲伊人久久大香线蕉av| 尤物yw午夜国产精品视频明星| 国产色综合天天综合网| 欧美尺度大的性做爰视频| 亚洲欧美精品一区二区| 最近2019年日本中文免费字幕| 欧美—级a级欧美特级ar全黄|