前言:
JavaScript中有五種基本數據類型(也叫做簡單數據類型)分別為:undefined、null、bolean、number、string;另外還含有一種復雜的數據類型:object.
深入分析:
基本類型數據
1.基本數據類型值是指簡單的數據段,五種基本類型都是按值訪問的(可以操作保存在變量中的實際值);
2.基本類型的值在內存中占據固定大小的空間,被保存在棧內存中。(從一個變量向另一個變量復制基本類型的值,會創建這個值的一個副本);
3.不能給基本類型的值添加屬性。
------------------------------------------------------------------------------------------------------------------------------------------------------
引用類型數據:object(還有array、function)
1.引用類型值是指那些可以由多個值構成的對象。js不允許直接訪問內存中的位置,也就是不能直接訪問操作對象的內存空間,在操作對象時,實際上是在操作對象的引用而不是實際的對象;
2.引用類型的值是對象,保存在堆內存中,包含引用類型值的變量實際上包含的並不是對象本身,而是指向該對象的指針。從一個變量向另一個變量復制引用類型的值,復制的其實是指針,因此兩個變量最終指向同一個對象。
3.對於引用類型的值,可以為其添加屬性和方法,也可以改變和刪除其屬性和方法。
------------------------------------------------------------------------------------------------------------------------------------------------------
在ECMAScript中用var關鍵字來定義變量,因為
js
是弱類型的,所以無法確定變量一定會存儲什么值,也就不知道變量到底會是什么類型,而且變量的類型可以隨時改變。這就是ECMAScript
是松散類型的來由,所謂松散類型就是可以用來保存任何類型的數據。在es6中新增了let命令來聲明變量,const命令聲明一個只讀的常量
let的用法類似於var,但是所聲明的變量,只有在let代碼塊內才有效;const一旦聲明,常量的值就不能改變。
------------------------------------------------------------------------------------------------------------------------------------------------------
復習了這些知識,恰好遇到了一些關於js的經典例子:
var a = {name: 1}; var b = a; console.log(a); console.log(b); b.name = 2; console.log(a); console.log(b); var b = {name: 3}; console.log(a); console.log(b);於是我的答案變成了:
其實每次做這些的時候,自己總是知其然而不知其所以然,於是又從大神同事CZ那里get到了新技能:關於this指向的問題。
var name = "yeye"; var person = { name: "doudou", pro: { name: "wanwan", getName: function() { return this.name; } } }; console.log(person.pro.getName()); var pepole = person.pro.getName; console.log(pepole());上面的這個例子是不是很面熟?沒錯,這道題就是很經典的js的面試題,從自己接觸js到現在,看到同種題型就不下十余次,可惜的是每次自己都會被“坑”,尤其是第二問,總是深陷其中不能自拔,直到現在終於找到了“小竅門”:
console.log(person.pro.getName());//類似於這種的,getName()前有“層級“關系調用的時候,就一層層的往上找,直到找到它的父類。一般,這里不會有人做錯(嘻嘻*-*) var pepole = person.pro.getName; console.log(pepole()); //而這種的,出錯幾率就稍微大一點了。但是在這里只要記住,“直接調用,無任何層級關系的”它的this都是指window對象,於是很容易的就得出 ... console.log(person.pro.getName()); //wanwan var pepole = person.pro.getName; console.log(pepole()); //yeye而關於最上面的那道題,理解了上面縮寫的,回過頭來在思考的話:
a 是一個對象,b 是對 a 的引用,即 a 和 b 指向同一塊內存,所以前兩個輸出一樣。 當對 b 作修改時,即 a 和 b 指向同一塊內存地址的內容發生了改變,所以 a 也會體現出來,所以第三四個輸出一樣。 當 b 被覆蓋時,b 指向了一塊新的內存,a 還是指向原來的內存,所以最后兩個輸出不一樣。