2018-02-08新增Number和String部分
為什麼一個陣列可以有多種建立方法,他們的含義都是一樣的嗎?
number、String等這些資料型別的本質是什麼,為什麼有時候它們又能使用new來建立?
為什麼說函式也是物件?普通函式也可以使用new來建立一個物件嗎?
....
對這些問題的答案是否清晰,好像並不會在實際開發中影響你的專案,遇到疑惑渾水摸魚也就過去了。
最近在看重新翻看《JavaScript物件導向程式設計指南》,深覺溫故知新之意,半年前只看懂了前幾章的基本概念,對後面幾章所講的原型,方法擴充套件,設計模式等看的雲裡霧裡。現在再來回顧這本書,有種被點醒的感覺,對於很多一些平日裡學習時遇到的模稜兩可的概念通透了不少。
而在時候實際運用的時候,思路也自然而然的更加清晰了
整本書所講的核心,也是我們經常掛在嘴邊的:
Javascript
是一種物件導向的程式語言,所有的一切都是物件
本書第四章詳細地講了“物件”這個概念,能讓人更深刻地理解js中所有的資料型別,以下為章節筆記。從物件的角度,重新認識各個資料型別
所有的物件都繼承自Object物件
js中所有的型別都繼承自
Object
這句話也可以說,Object為所有型別的原型,即所有物件的父級物件。就像是我們自己new一個物件,然後子類可以繼承,獲取原型的屬性和方法,也能重寫自己的屬性和方法一樣。
從物件的角度,其實更應該這麼表述:以上所有型別都屬於object的內建物件。更為精確的說法是,內建物件分為三大類:
- 資料封裝類物件:包括Array,String,Boonlean,Number以及Object本身
- 工具類物件:包括Math,Date。RegExp等
- 錯誤類物件:在某些異常發生時可以幫助我們糾正程式的錯誤狀態
所以首先,object
有自己的屬性和方法(列舉常用的部分)
-
o.constructor:返回構造器的引用
-
o.toString():返回物件的字串描述,包含物件的內部類名,object返回
“[object object]”
, -
o.valueOf():反饋物件的單值描述資訊,通常是物件本身
無論多複雜的物件,它都是繼承自Object物件,並且擁有其所有的方法和屬性
Array物件
小標題這句話想必大家肯定也不陌生。 我們當然可以通過構造器Array建立一個陣列物件
var b = new Array()
複製程式碼
length,join(),slice(),split(),sort()
等方法是陣列物件特有的方法,他們也都十分有用。剛好之前也整理過一些陣列的內建方法
陣列內建方法大全(一)
陣列內建方法大全(二)
那對於繼承自父類的方法,它也有進行重寫,更符合陣列的特點
- arr.toString().將陣列轉為字串,陣列內容用逗號隔開
Function物件
函式也是一種特殊的資料物件
所以我們當然也能這麼寫,函式的引數和函式體都用字串的形式,當做Function建構函式的引數傳入。
var C = new Function()
//此時的引數和函式體都需要通過字串傳參的形式,如:
//var C = new Function("a","b","return a+b")
複製程式碼
不過這種寫法並不推薦,因為Js需要對這段程式碼進行兩次解析(首先將字串解析為函式引數和函式體,再執行程式碼)
另外同樣展示一下Function物件繼承自父類的toString和valueOf方法和屬性,雖然意義並不大
函式物件的prototype屬性
- prototype屬性指向一個物件
- 只有在函式為構造器時才會發揮作用
- 該函式所建立的所有物件,都會持有該prototype屬性的引用,並可以將其當做自身的屬性
var o = {
name:"TRY",
say():function(){"I'm"+this.name}
}
var F = function(){}; //建立一個函式
F.prototype = o; //把物件o賦給F的prototype屬性
var f = new F() //以F為構造器建立新的物件f
//f可以直接使用,F的prototype屬性所引用物件 的屬性和方法
f.name //"TRY"
f.say() //I'm TRY
複製程式碼
推斷物件型別
當我們使用typepf去判斷資料型別,返回值有以下6種情況:
undefined boolean function object string number
,和基本資料型別對應了之後,你會發現少了Array和null
。實際上,這兩個使用typeof
判斷後返回的都是object
Object.prototype.toString.call([]);
//返回值:"[object Array]"
複製程式碼
也能判斷arguments的型別
function a(){
return Object.prototype.toString.call(arguments);
}
//返回值:"[object Arguments]"
複製程式碼
甚至是DOM元素
Object.prototype.toString.call(document.body);
//返回值:"[object HTMLBodyElement]"
複製程式碼
是不是屌炸天哈哈哈!
Boolean物件
布林物件除了繼承自父級物件的屬性和方法之外,並沒有額外的方法和屬性。在使用時還容易造成混淆,因為使用Boolean構造的是一個物件,如果一不小心直接用來作為布林值使用,得到的結果永遠是true(因為所有的物件都為true),所以還是建議使用基本型別來表示布林值比較妥當。
var a = new Boolean();
複製程式碼
Number物件
Number物件和Boolean物件類似,即
- 當被當做建構函式時(使用new),他會建立一個物件
- 在被當做一個一般函式時,它會試圖將任何值轉化為數字,這與
parseInt()、parseFloat()
的作用基本相同
<!-- ———number當做一般函式——— --!>
var n = Number("12.12"); //12.12
typeof n //Number
<!-- ———number當做建構函式——— --!>
var n = new Number("12.12") //Number{12.12}
typeof n //object
n.toString() //"12.12"
n.valueOf() //12.12
複製程式碼
注:Number物件的toString(radix)方法中的內建引數,表示轉化進位制
Number物件還有一些自身的方法(下列例子並沒有建立Number物件,但也可以使用其方法,Number物件均在後臺進行建立和銷燬)
//保留小數位
(12.333).toFixed(1) // 12.3
//科學計數法
(12345).toExponential() //"1.2345e+4"
複製程式碼
另外,由於函式本身也是物件,會擁有一些屬性。在Number()
函式中,有一些值得注意的內建屬性,他們是隻讀的
Number.MAX_VALUE //1.797631348623457e+308
Number.MIN_VALUE //5e-324
Number.POISTIVE_INFINITY //Infinity
Number.NEGATIVE_INFINITY //-Infinity
Number.NAN // NAN
複製程式碼
String物件
String物件實際上就像是一個字元陣列,它也有索引和length屬性(早期版本的IE可能還不支援)
同樣,可以使用兩種方式建立String,一種是物件,一種是使用String函式,再次強調,String物件永遠為true呀~
var s1 = String() //建立一個空字串
typeof s1 //"string"
Boolean(s1 ) //false
var s2 = new String(); //建立一個空字串
typeof s2 //"object"
Boolean(s ) //true
複製程式碼
字串的內建方法也有很多,如split()
、substring()
等等,本篇主要圍繞物件的角度,所以就不對這些常用方法進行展開了。
總結
js中就是物件
的天下,各種資料型別都是繼承自Object,並衍生出自己的方法和屬性。理解透徹這一點,就能把各種資料型別玩的飛起,才能真正明白,自己平時在使用的東西到底是個啥