国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發(fā) > JS > 正文

淺談js中的引用和復(fù)制(傳值和傳址)

2024-05-06 16:32:03
字體:
供稿:網(wǎng)友

好像一般很少人講到j(luò)s中的引用和復(fù)制,不過弄清楚這個概念可以幫助理解很多東西

先講一下很基礎(chǔ)的東西,看看js中幾種數(shù)據(jù)類型分別傳的什么

引用:對象、數(shù)組、函數(shù)

復(fù)制:數(shù)字、布爾

字符串單獨說明,因為它的特殊性,無法確定是傳遞引用還是復(fù)制數(shù)值(因為字符串的值是沒法改變的,所以糾結(jié)這個問題也是沒意義的)但是用于比較的時候顯然是屬于傳值比較(稍后具體說比較的事)

下面講一下在使用中的具體體現(xiàn)

最普通的使用就是賦值了

var a = 1;var b = a;  //賦的是a的復(fù)制值b ++;alert(a);  //"1"  b的修改不影響a/****************************************/var a = [1];var b = a;   //賦的是a的引用 b[0] ++;alert(a); //"2"  b的修改對a也有效  不過當(dāng)然b = [2];這種修改對a是沒用的。

函數(shù)的參數(shù)

傳值的傳遞:傳給函數(shù)的是數(shù)值的一個復(fù)制,函數(shù)中對其的修改外部不可見

var a = 1;var b = 2;function change(a,b) { var c = a; a = b;   //用新引用覆蓋 b = c; alert(a);  //"2"      alert(b);  //"1"}change(a,b);alert(a);  //"1"     alert(b);  //"2"

傳址的傳遞:傳給函數(shù)的是數(shù)值的一個引用,函數(shù)中對其屬性的修改外部可見,但用新引用覆蓋其則在外部不可見,比如

var a = [1, 2, 3];var b = [5, 6];function change(a,b) { a[0] = 4;  //對其屬性的修改外部可見  var c = a; a = b;   //用新引用覆蓋 b = c; alert(a);  //"5,6"      alert(b);  //"4,2,3"}change(a,b);alert(a);  //"4,2,3"alert(b);   //"5,6"

從結(jié)果可以看出a和b并沒有互換   因為用新引用覆蓋在外部不可見 這個很自然 因為函數(shù)只是拿到了引用 并沒有權(quán)力更改引用

下面這個就不同了

var a = [1, 2, 3];var b = [5, 6];function change() { var c = a; a[0] = 4; a = b; b = c;};change();alert(a);  //"5,6"alert(b);  //"4,2,3"

這里成功實現(xiàn)互換 

又得提到j(luò)s的塊級作用域了,這個放某些語言里定然是要報未定義錯誤的,因為js沒有塊級作用域,所以它在change里找不到變量a,b就會自覺的到上層去找,所以這里的a,b是全局變量的引用

而上面的那個a,b則是change函數(shù)中的變量,在調(diào)用函數(shù)時傳遞了a,b的引用賦給了這兩個變量,但是并不能改變?nèi)种械腶,b,這里換個名字大概就好理解多了

這個稍微提下    有些走題了。。。。

回到引用和復(fù)制 在比較運算中的注意事項

傳值的比較比較的是數(shù)值 而傳址的比較比較的是引用,引用不同即使數(shù)值相同也不等

1 == 1;  //true1 === 1;  //true[0] == [0]; //false[0][0] == [0][0];  //true[0][0] === [0][0];  //true[0].toString() == [0].toString();  //true 

閉包中。。。。

閉包大概是js中最糾結(jié)的東西 我們部門面試的經(jīng)典試題,常考不衰啊。。。。

這里我先不說閉包的東西,只說一下涉及傳值和引用的部分,等我哪天確定自己可以用清晰的條例、簡明的語言、生動的實例徹底的說清楚那個東西,再詳細(xì)介紹這個提js不能不提的家伙。。。

閉包中,內(nèi)部函數(shù)用外部函數(shù)的局部變量使用引用的方式而不是復(fù)制

其實這也是理解閉包的一個很重要的部分 可以用這個解釋一個很經(jīng)典的閉包現(xiàn)象,很多地方在說明閉包的時候都會用到的一個例子

/*構(gòu)造一個函數(shù),給數(shù)組中的節(jié)點設(shè)置事件處理程序,當(dāng)點擊一個節(jié)點時,alert出節(jié)點的序號*/var add_handlers = function (nodes) {  var i;  for (i = 0, l = nodes.length; i < l; i ++) {    nodes[i].onclick = function (e) {      alert(i);  // 當(dāng)然這里的結(jié)果必然是每次alert的都是節(jié)點總數(shù)。。。。    }  }};

為什么每次alert的都是節(jié)點總數(shù) 而不是預(yù)期的序號呢,這個如果用復(fù)制和引用解釋就相當(dāng)容易了

因為內(nèi)部函數(shù)在使用外部變量時使用引用的方式而不是復(fù)制,就是說我給每個節(jié)點設(shè)置onclick事件的時候?qū)的引用傳遞給了alert,當(dāng)我點擊節(jié)點觸發(fā)onclick事件的時候,i的值已經(jīng)變成了節(jié)點總數(shù)。。。

var add_handlers = function (nodes) {  var i;  for (i = 0, l = nodes.length; i < l; i ++) {     nodes[i].onclick = function (i) {      return function(){      alert(i);        } }(i);  }};

這樣修改后之所以正確是因為此時傳進(jìn)去的是i的值的復(fù)制,其實和普通函數(shù)是一樣的,不要因為加了閉包就迷糊了,回歸本源去思考就明白了,本源就是上面講到的傳址的傳遞

順便提一句,不要被閉包這個古怪的名字唬住了,其實它和我們平時用的函數(shù)原理是一樣的,拋開那些“更長的生命周期”“保護(hù)私有變量”等閉包所謂的特性,把它當(dāng)成一個普通的函數(shù)(也可以換個角度把全局函數(shù)看成一個特殊的閉包),很容易就可以理解了

關(guān)鍵是要放下所有的浮華,回歸最本質(zhì)。。。又跑題了。。。

以上這篇淺談js中的引用和復(fù)制(傳值和傳址)就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持VeVb武林網(wǎng)。


注:相關(guān)教程知識閱讀請移步到JavaScript/Ajax教程頻道。
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 江孜县| 宁南县| 襄城县| 米林县| 乌兰察布市| 青浦区| 屏南县| 台东市| 廉江市| 陆良县| 云阳县| 通道| 奈曼旗| 兴化市| 柘荣县| 镇安县| 泸州市| 海门市| 佳木斯市| 兰坪| 云阳县| 木里| 桓台县| 古浪县| 巴林右旗| 乌兰浩特市| 剑川县| 漾濞| 格尔木市| 宿迁市| 多伦县| 平谷区| 广平县| 邯郸市| 临江市| 乐至县| 柳林县| 横山县| 连云港市| 万载县| 广安市|