js基礎(chǔ)陣營:變量篇之變量定義

這一次我們首先將視角投向js基礎(chǔ)知識之變量,下面看下變量的基礎(chǔ)信息
姓名:變量
類型:松散型
定義方式:var,const,let或者直接變量名
常見問題:變量覆蓋考传,變量提升,變量作用域
我們從上面的基礎(chǔ)信息來一點一點的剖析變量這士兵甲

1:變量的類型

var num = 14;//這個時候變量num的類型為數(shù)字
console.log(typeof num);//查看num的類型為number
num = '改成字符串';//這個時候變量num的類型為字符串
console.log(typeof num);//查看num的類型string

js的變量的松散類型(弱類型)其實是相對于java等其他語言的強(qiáng)類型來說的戳葵,強(qiáng)語言類型在定義變量的時候需要指定變量的類型筋量,如果試圖去修改變量類型的話就會報錯植袍。

2:變量定義的方法

2.1 var

在ES5的時候我們定義變量的方法是通過var關(guān)鍵字+變量名的方式定義一個變量筋遭,例如:

var name;//定義了變量name

當(dāng)然也可以直接通過變量名的方法來定義一個全局變量搓萧,不過不是很推薦這種做法,例如:

name;//定義了一個全局變量

不過隨著時光的飛逝宛畦,規(guī)則也在悄悄的發(fā)生了變化,出現(xiàn)了ES6語法揍移,在ES6語法中出現(xiàn)了通過let,和const來定義變量的方法次和,首先我們來看const

2.2 const

const是定義常量的方法,定義的時候必須初始化那伐,且定義后不可以修改踏施。常量通常是大寫的方式,并且通過const定義的常量是不允許被修改的罕邀,如果嘗試修改會報錯畅形,例如:

const NAME;
NAME = '來瓶二鍋頭';

將上面代碼復(fù)制到瀏覽器控制臺運(yùn)行,會直接報錯


同樣的下面也會報錯

const PI = 3.14;
console.log(PI);
PI= 3.1415;

那么我們設(shè)想一下诉探,如果我們將常量定義為一個對象日熬,嘗試修改對象屬性的話會發(fā)生什么情況呢?心動不如行動肾胯。

const USER = {
    name:'來瓶二鍋頭'
};
console.log(USER);
USER.name="再來瓶二鍋頭";
console.log(USER);

這個時候我覺得下面這個圖片挺適合的



上面我們已經(jīng)說過了const定義的是一個常量竖席,常量是不允許修改的,修改的話就會報錯敬肚,但是為什么修改對象屬性就可以的呢毕荐?這里就需要從原理來說了,每次聽到原理這個詞的時候都覺得好高大上艳馒,這就跟我們看到張無忌使用乾坤大羅移在光明頂大戰(zhàn)六大派的時候一樣憎亚,哇塞,乾坤大挪移好膩害啊弄慰。但是為什么厲害呢第美?不知道,反正就是厲害陆爽。我們今天就要去好好剖析一下乾坤大挪移為啥子那么膩害斋日,不對是const為什么可以修改對象的屬性。其實這里為什么能夠修改對象類型需要引入兩個概念(真煩墓陈,一個東西說不清楚非要再來一個東西恶守,嘿嘿):引用類型和基本類型第献。我們下面先來說明下這兩個概念,等著兩個概念弄通了兔港,你就會了乾坤大挪移了庸毫,咳咳,滾犢子衫樊,是理解了為什么可以修改對象屬性

2.2.1 基本類型

基本類型指的是簡單的數(shù)據(jù)段飒赃,按照數(shù)據(jù)類型(這玩意后面介紹)來說就是基本的數(shù)據(jù)類型都是基本類型,包括undefined,Null,Boolean,Number,String科侈。這些類型的值都是按值訪問的载佳,操作的話就是實際的值。什么叫操作的是實際的值呢臀栈?那么我們看下一下的例子:

var num1 = 5;
console.log('num1的值為:' + num1);
var num2 = num1;
console.log('num2的值為:' + num2);
num1 = 10;
console.log('修改后num1的值為:' + num1);
console.log('num2的值為:' + num2);

我們把代碼復(fù)制到控制臺蔫慧,查看運(yùn)行結(jié)果如下:



我們可以看到將num1的值賦值給num2,相當(dāng)于直接將5賦值過去,修改num1的值不會造成num2值得改變权薯。那么我們就可以得到以下一個結(jié)論:操作基本類型的數(shù)據(jù)的時候?qū)嶋H上操作的就是實際的值姑躲。

2.2.2 引用類型

引用類型指的是多個值構(gòu)成的對象。按照數(shù)據(jù)類型來劃分的那就是Object類型(數(shù)組也是object類型的數(shù)據(jù)哦)的數(shù)據(jù)盟蚣。那么我們操作引用類型的值的時候是實際的值嗎黍析?我們看下一下例子:

var obj1 = {
    name:'二鍋頭'
};
console.log('obj1的數(shù)據(jù)為' + JSON.stringify(obj1));
var obj2 = obj1;
console.log('obj2的數(shù)據(jù)為' + JSON.stringify(obj2));
obj1.name='我愛二鍋頭';
console.log('修改后obj1的數(shù)據(jù)為' + JSON.stringify(obj1));
console.log('修改后obj2的數(shù)據(jù)為' + JSON.stringify(obj2));

復(fù)制到控制臺中看結(jié)果為



這個時候腦海里肯定會有以下的表情



這個就要說到引用類型變量值的問題了。按照js規(guī)定屎开,js不允許直接訪問內(nèi)存中的位置阐枣,而Object類型的數(shù)據(jù)是放在內(nèi)存中的,所以我們這個時候定義的引用類型的變量是一個指針奄抽,指向改對象所在內(nèi)存的位置侮繁。舉個例子吧,就是我們都有銀行卡如孝,銀行卡里有自己的錢宪哩,我們可以直接從銀行卡里把錢取出來嗎?肯定不能(違法行為不在考慮范圍內(nèi)哈)第晰,我們需要去銀行锁孟,然后取出我們的錢,我們能操作的只是我們的銀行卡茁瘦。而銀行卡就是一個中介品抽,一個指向我們錢的中介。我們可以用一下圖來表示上面寫的obj1和obj2的例子

因此當(dāng)我們復(fù)制一個引用類型數(shù)據(jù)賦值給另一個變量的時候其實只是創(chuàng)建了一個副本甜熔,這個副本就是一個指針圆恤。指向堆棧內(nèi)存中的一個對象。
到此為止我們搞懂了什么是引用類型什么是基本類型腔稀,那么我們回歸到我們的主體中盆昙,為什么const定義的對象類型的常量可以修改羽历。答案就是對象類型的常量是引用類型的,此時我們定義的常量其實就是一個指針淡喜,指向堆棧內(nèi)存中一個對象的指針秕磷,這個指針是不能修改的,但是堆棧內(nèi)存中的變量可以隨便變炼团。驚不驚喜意不意外澎嚣。哇咔咔。那么我們看下面的例子:

const OBJ1 = {
   name:'二鍋頭'
};
console.log('OBJ1的數(shù)據(jù)為:' + JSON.stringify(OBJ1));
OBJ1 = {
   name:'我愛二鍋頭'
};

復(fù)制到控制臺中看結(jié)果



哇咔咔瘟芝。收功易桃。

2.3 let

在ES5時代沒有塊級作用域這一說(又來了一作用域的概率,嘿嘿嘿锌俱,后面專門介紹這一老哥)晤郑,在ES5那個時代只有全局作用域和函數(shù)內(nèi)作用域,所以在ES6的時候引入了塊級作用域嚼鹉。通過let來定義變量,定義的就是一塊級作用域驱富,我們來看以下的例子:

if(true){
   let num = 5;
   console.log('num的值為:' + num);
}
console.log('num的值為:' + num);

復(fù)制到控制臺來看下結(jié)果



這個時候定義的變量num的作用域為塊級作用域锚赤,只在if代碼塊中起作用,在外部就不起作用了褐鸥,我們來對比下var定義變量线脚,同樣的方式,小二叫榕,上代碼

if(true){
   var num = 5;
   console.log('num的值為:' + num);
}
console.log('num的值為:' + num);

復(fù)制到控制臺看結(jié)果



看到不同了吧浑侥,那么通過let就能解決一個很老套的問題了,小二上問題,以下程序運(yùn)行出現(xiàn)的結(jié)果是什么晰绎?

for(var i = 0;i<5;i++){
    setTimeout(function(){
        console.log(i);
    },100);
}

結(jié)果是什么寓落?輸出5個5,為什么呢荞下?具體原因涉及到宏任何和微任務(wù)伶选,后面單獨(dú)介紹(嘿嘿嘿,又埋坑了)那么怎么解決呢尖昏?答案很顯然仰税,用let來定義變量就可(這是最簡單的,當(dāng)然還有其他方法抽诉,后面別的章節(jié)會說到)陨簇,上代碼

for(let i = 0;i<5;i++){
    setTimeout(function(){
        console.log(i);
    },100);
}

答案是什么呢?自己復(fù)制到控制臺就能看到結(jié)果了
這個時候關(guān)于變量定義的相關(guān)問題都已經(jīng)結(jié)束了迹淌。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末河绽,一起剝皮案震驚了整個濱河市己单,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌葵姥,老刑警劉巖荷鼠,帶你破解...
    沈念sama閱讀 211,817評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異榔幸,居然都是意外死亡允乐,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評論 3 385
  • 文/潘曉璐 我一進(jìn)店門削咆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來牍疏,“玉大人,你說我怎么就攤上這事拨齐×墼桑” “怎么了?”我有些...
    開封第一講書人閱讀 157,354評論 0 348
  • 文/不壞的土叔 我叫張陵瞻惋,是天一觀的道長厦滤。 經(jīng)常有香客問我,道長歼狼,這世上最難降的妖魔是什么掏导? 我笑而不...
    開封第一講書人閱讀 56,498評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮羽峰,結(jié)果婚禮上趟咆,老公的妹妹穿的比我還像新娘。我一直安慰自己梅屉,他們只是感情好值纱,可當(dāng)我...
    茶點故事閱讀 65,600評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著坯汤,像睡著了一般虐唠。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上惰聂,一...
    開封第一講書人閱讀 49,829評論 1 290
  • 那天凿滤,我揣著相機(jī)與錄音,去河邊找鬼庶近。 笑死翁脆,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的鼻种。 我是一名探鬼主播反番,決...
    沈念sama閱讀 38,979評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了罢缸?” 一聲冷哼從身側(cè)響起篙贸,我...
    開封第一講書人閱讀 37,722評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎枫疆,沒想到半個月后爵川,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,189評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡息楔,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,519評論 2 327
  • 正文 我和宋清朗相戀三年寝贡,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片值依。...
    茶點故事閱讀 38,654評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡圃泡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出愿险,到底是詐尸還是另有隱情颇蜡,我是刑警寧澤,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布辆亏,位于F島的核電站风秤,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏扮叨。R本人自食惡果不足惜缤弦,卻給世界環(huán)境...
    茶點故事閱讀 39,940評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望甫匹。 院中可真熱鬧甸鸟,春花似錦惦费、人聲如沸兵迅。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,762評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽怀吻。三九已至趁耗,卻和暖如春辈挂,著一層夾襖步出監(jiān)牢的瞬間家凯,已是汗流浹背遵倦。 一陣腳步聲響...
    開封第一講書人閱讀 31,993評論 1 266
  • 我被黑心中介騙來泰國打工梦抢, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留鞍匾,地道東北人交洗。 一個月前我還...
    沈念sama閱讀 46,382評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像橡淑,于是被迫代替她去往敵國和親构拳。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,543評論 2 349

推薦閱讀更多精彩內(nèi)容