摘要:變量有兩種不同的數據類型基本類型,引用類型。知識一基本類型值就是簡單的數據段引用類型值保存的是對象的引用,不是實際的對象。
ECMAScirpt 變量有兩種不同的數據類型:基本類型,引用類型。
基本的數據類型有:undefined,boolean,number,string,null. 基本類型的訪問是按值訪問的,就是說你可以操作保存在變量中的實際的值。JavaScript中除了上面的基本類型之外就是引用類型了。
區別如下:
基本類型:
佔用空間固定,保存在棧中
保存與復製的是本身
使用typeof檢測數據類型
值類型
引用類型:
佔用空間不固定,保存在堆中
保存與復製的是指向對象的一個指針
使用instanceof檢測數據類型
使用new()方法構造出來的對象是引用類型(相關內容可參考關於Javascript中的new運算符,構造函數與原型鏈一些理解)
基本類型是不會改變,衹能重新賦值,而引用類型值是可以改變的
var a = "123456789", b = a; a = "321"; console.log(a) // 321 console.log(b) // 123456789
上面因為是把值保存在了變量了 而不是保存的是引用地址,所以他們兩個是相對獨立的整體,互不影響。但是如果換成引用類型的話
var a = { n: "123456789" }, b = a; a.n ="321"; console.log(a) // { n: "321" } console.log(b) // { n: "321" }
原因在於在javascript語言中創建的對象值中其保存的是對象的引用(也就是一個地址.引用類型值保存在內存中,而JS是不能直接訪問內存的,所以對於引用類型,操作的不是實際的對象而是對象的引用。)
這里有個小提示説一下,假如兩個相同的基本類型或引用類型(內容一樣)相比,看看結果是怎樣的?
var base1 = "123", base2 = "123", obj1 = { a: "123" }, obj2 = { a: "123" }; console.log(base1 === base2) // true console.log(obj1 === obj2) // false
如果你還錯了那就證明你沒理解透上面的東西了,因為前面是值之間直接比較,后面是指向地址的比較,即使兩個引用類型看起來一樣,衹要不是同一個聲明變量,它們就一定不同。
知識一:基本類型值就是簡單的數據段;引用類型值保存的是對象的引用,不是實際的對象。
但是在函數中的對象傳值又是不是同一回事呢?看看下面代碼
function setName(obj) { obj.name = "1"; obj = {}; obj.name = "2"; } var obj = {}; setName(obj); console.log("最終結果obj:", obj) // 最終結果obj: { name: "1" }
沒錯,結果出乎意料的是1.而不是大多數人剛開始認為的2.
接下來我們在一步步分析出在函數過程中對象發生了什么樣的變化?稍微修改下對象名便於區分。
function setName(innerObj) { console.log("初始的innerObj:", innerObj); // 初始的innerObj: {} innerObj.name = "1"; console.log("第一次設置屬性值的innerObj:", innerObj); // 第一次設置屬性值的innerObj: { name: "1" } //保存下原對象 var _innerObj = innerObj; innerObj = {}; console.log("重新賦值的innerObj:", innerObj); // 重新賦值的innerObj: {} innerObj.name = "2"; console.log("第二次設置屬性值的innerObj:", innerObj); // 第二次設置屬性值的innerObj: { name: "2" } console.log("兩者之間是不是同一個對象?:", _innerObj == innerObj) // 兩者之間是不是同一個對象?: false console.log("innerObj:", innerObj) // innerObj: { name: "2" } console.log("_innerObj: ", _innerObj) // _innerObj: { name: "1" } } var outerObj = {}; setName(outerObj); console.log("最終結果outerObj:", outerObj) // 最終結果outerObj: { name: "1" }
過程中可以看出在函數中間 innerObj = {} 之后;對象的指向就已經變了,也就是說這里相當於重新建立一個新的指向,后續的操作都是基於新指向之上進行的。
此時,outerObj === _innerObj !== innerObj, 所以最終輸出的是1而不是2.
如果還有些混亂的同學,看看如果不通過函數直接修改會是什么結果?
var obj = {"a":1} obj = {}; obj = {"a":2}; console.log(obj) // { a: 2 }
這次確確實實的是輸出2了。
知識二:JS中所有函數傳參都是按值傳遞的。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/106154.html
摘要:前言文章主要基于高級程序設計總結的基本重寫了全文補充知識點新增實例優化排版新增檢測方法技巧用法構造函數創建一個用護定義的對象類型的實例或具有構造函數的內置對象類型之一命令執行構造函數返回一個實例對象構造函數一個指定對象實例的類型的函數傳慘一 前言 文章主要基于>總結的!!!PS: 2018/05/09 基本重寫了全文,補充知識點,新增實例,優化排版PS: 2018/05/11 新增檢測...
摘要:作用域鏈的用途,是保證對執行環境有權訪問的所有變量和函數的有序訪問。作用域鏈的前端,始終都是當前執行的代碼所在環境的變量對象。對語句來說,會將指定的對象添加到作用域鏈中。 前言 ps: 2018/05/13 經指正之后發現惰性加載函數細節有問題,已改正在這里也補充一下,這些都是根據自己理解寫的例子,不一定說的都對,有些只能查看不能運行的要謹慎,因為我可能只是將方法思路寫出來,沒有實際跑...
摘要:沒有瀏覽器測試,所以不知道是不是有效,其實里面看起來比我寫的那個復雜,實際上多了個檢驗格式上兼容寫法所以不要怕,如果我錯了記得提醒下我啊。目前為止其實已經該說的都差不多覆蓋到了吧,動手能力強的話已經可以根據教程寫一個實例出來的了。 系列文章 關于前端上傳文件全面基礎掃盲貼(零)關于前端上傳文件全面基礎掃盲貼(一) ----- XMLHttpRequest關于前端上傳文件全面基礎掃盲貼(...
摘要:它們的區別之一就是在計算機中的存儲方式不同基本類型數據是將變量名及值存儲在變量對象中,而引用類型的數據是將變量名和地址存儲在變量對象中,真正的值是存儲在堆內存中。 showImg(https://segmentfault.com/img/remote/1460000017151449); 說點別的 這是《關于 JavaScript 你必須要知道的 33 個概念 》系列的第三篇文章,今天...
摘要:在此,我們首先根據變量的作用域,將變量劃分為三級,具體是全局變量局部變量和參數變量。 【摘要】本文是專為JavaScript入門者而總結的,總體上將JavaScript的基礎部分分成了九大塊,分別是變量、運算符、數組、流程控制結構、字符串函數、函數基礎、DOM操作基礎、文檔對象模型DOM和正則表達式。 【關鍵字】變量、運算符、數組、流程控制結構、函數、DOM、正則表達式。 本篇文章的主...
閱讀 961·2023-04-26 02:49
閱讀 1172·2021-11-25 09:43
閱讀 2541·2021-11-18 10:02
閱讀 2919·2021-10-18 13:32
閱讀 1281·2019-08-30 13:54
閱讀 2074·2019-08-30 12:58
閱讀 3008·2019-08-29 14:06
閱讀 2154·2019-08-28 18:10