JavaScript七大語言類型你知多少?

{"type":"doc","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"雖然JavaScript語言對大多數人來說已經非常熟悉了,但有些問題依然值得深入討論。比如下面這些:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"爲什麼有的編程規範要求用 "},{"type":"codeinline","content":[{"type":"text","text":"void 0"}]},{"type":"text","text":" 代替 "},{"type":"codeinline","content":[{"type":"text","text":"undefined"}]},{"type":"text","text":" ?"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"字符串有最大長度嗎?"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"0.1 + 0.2 不是等於0.3麼?爲什麼JavaScript裏不是這樣的?"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"ES6新加入的Symbol是個什麼東西?"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"爲什麼給對象添加的方法能用在基本類型上?"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果你還對這些問題還不是很熟悉,那麼請往下看。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"7種語言類型"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"JavaScript作爲一種OOP,其每一個值都有對應的數據類型。JavaScript共有7中語言類型,如下:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"numberedlist","attrs":{"start":"1","normalizeStart":1},"content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":1,"align":null,"origin":null},"content":[{"type":"text","text":"Undefined"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":2,"align":null,"origin":null},"content":[{"type":"text","text":"Null"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":3,"align":null,"origin":null},"content":[{"type":"text","text":"Boolean"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":4,"align":null,"origin":null},"content":[{"type":"text","text":"String"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":5,"align":null,"origin":null},"content":[{"type":"text","text":"Number"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":6,"align":null,"origin":null},"content":[{"type":"text","text":"Symbol"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":7,"align":null,"origin":null},"content":[{"type":"text","text":"Object"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"Undefined"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"Undefined"}]},{"type":"text","text":" 表示未定義,它只有一個值 "},{"type":"codeinline","content":[{"type":"text","text":"undefined"}]},{"type":"text","text":"。任何變量在賦值前都是 "},{"type":"codeinline","content":[{"type":"text","text":"Undefined"}]},{"type":"text","text":" 類型,值爲 "},{"type":"codeinline","content":[{"type":"text","text":"undefined"}]},{"type":"text","text":",就是 "},{"type":"codeinline","content":[{"type":"text","text":"Undefined"}]},{"type":"text","text":" 類型的唯一值。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"但是問題就出在 "},{"type":"codeinline","content":[{"type":"text","text":"undefined"}]},{"type":"text","text":" 在JavaScript語言中是一個"},{"type":"text","marks":[{"type":"strong"}],"text":"變量"},{"type":"text","text":",而非一個"},{"type":"text","marks":[{"type":"strong"}],"text":"關鍵字"},{"type":"text","text":",這就導致一個致命的結果,可能在有意無意中被修改。這是JavaScript公認的設計失誤之一。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"所以,爲了避免異常情況的發生,建議使用 "},{"type":"codeinline","content":[{"type":"text","text":"void 0"}]},{"type":"text","text":" 來獲取 "},{"type":"codeinline","content":[{"type":"text","text":"undefined"}]},{"type":"text","text":" 的值。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"Null"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"Null"}]},{"type":"text","text":" 表示空類型,也只有一個值 "},{"type":"codeinline","content":[{"type":"text","text":"null"}]},{"type":"text","text":",表示“定義了,但是爲空”。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"和undefined不同的是,"},{"type":"codeinline","content":[{"type":"text","text":"null"}]},{"type":"text","text":" 是JavaScript中的一個關鍵字,所以可以放心的用 "},{"type":"codeinline","content":[{"type":"text","text":"null"}]},{"type":"text","text":" 獲取 "},{"type":"codeinline","content":[{"type":"text","text":"null"}]},{"type":"text","text":" 的值。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"Boolean"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"布爾類型,只有兩個值"},{"type":"codeinline","content":[{"type":"text","text":"true"}]},{"type":"text","text":","},{"type":"codeinline","content":[{"type":"text","text":"false"}]},{"type":"text","text":"。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"String"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"字符串類型,用於表示文本數據。String的最大長度是2^53-1,這在一般程序中是夠用的。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"但是,這個長度並不是字符實際的長度。因爲String的真實意義並非字符串,而是字符串的UTF16編碼,我們字符串的操作 "},{"type":"codeinline","content":[{"type":"text","text":"charAt"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"charCodeAt"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"length"}]},{"type":"text","text":" 等方法針對的都是UTF16 編碼。所以,字符串的最大長度,實際上是受字符串的編碼長度影響的。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"現行的字符集國際標準,字符是以 Unicode 的方式表示的,每一個 Unicode 的碼點表示一個字符,理論上,Unicode 的範圍是無限的。UTF是Unicode的編碼方式,規定了碼點在計算機中的表示方法,常見的有 UTF16 和 UTF8。 Unicode 的碼點通常用 U+??? 來表示,其中 ??? 是十六進制的碼點值。 0-65536(U+0000 - U+FFFF)的碼點被稱爲基本字符區域(BMP)。"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"JavaScript中的字符串一旦創建出來,則不能修改,所以它也有值類型特性。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"Number"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Number類型表示通常意義上的數字,和數學中的有理數大致對應。由於在計算機中涉及到精度問題,JavaScript中的Number有 "},{"type":"codeinline","content":[{"type":"text","text":"18437736874454810627"}]},{"type":"text","text":" (即2^64 - 2^53 + 3) 個值。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"除了表示常規數字,JavaScript還規定了幾個例外情況:"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"NaN"}]},{"type":"text","text":",佔用了 9007199254740990,這原本是符合IEEE規則的數字;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"Infinity"}]},{"type":"text","text":",無窮大;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"-Infinity"}]},{"type":"text","text":",負無窮大。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"由於在JavaScript中有"},{"type":"codeinline","content":[{"type":"text","text":"+0"}]},{"type":"text","text":" 和 "},{"type":"codeinline","content":[{"type":"text","text":"-0"}]},{"type":"text","text":"之分,對於涉及到0的除運算要格外小心,需藉助 "},{"type":"codeinline","content":[{"type":"text","text":"Infinity"}]},{"type":"text","text":" 和 "},{"type":"codeinline","content":[{"type":"text","text":"-Infinity"}]},{"type":"text","text":" 來區分。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這樣,由於精度限制問題,在浮點數運算中有時候會出現類似 "},{"type":"codeinline","content":[{"type":"text","text":"0.1+0.2 != 0.3"}]},{"type":"text","text":" 的問題。實際上,這裏錯誤的並不是結果,而是浮點數比較方法。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"ruby"},"content":[{"type":"text","text":"> console.log( Math.abs(0.1 + 0.2 - 0.3) <= Number.EPSILON);\n true"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"Symbol"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Symbol 是 ES6 中引入的新類型,它是一切非字符串的對象key的集合,在ES6規範中,整個對象系統被用Symbol 重塑。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"根據我個人的理解,正如它的字面意思:符號、標誌,它表示JavaScript中所有對象的唯一標識符,就像身份證號碼一樣,解決的是變量區分和資源定位的問題。比如,對象的屬性名如何和屬性值建立關聯。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"創建 Symbol 的方式是使用全局的 Symbol 函數。例如:"}]},{"type":"codeblock","attrs":{"lang":"shell"},"content":[{"type":"text","text":"var mySymbol = Symbol(\"my symbol\");"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"例如,我們可以使用 "},{"type":"codeinline","content":[{"type":"text","text":"Symbol.iterator"}]},{"type":"text","text":" 來自定義"},{"type":"codeinline","content":[{"type":"text","text":"for…of"}]},{"type":"text","text":" 在對象上的行爲:"}]},{"type":"codeblock","attrs":{"lang":"javascript"},"content":[{"type":"text","text":"var o = new Object\n\no[Symbol.iterator] = function() {\n var v = 0\n return {\n next: function() {\n return { value: v++, done: v > 10 }\n }\n } \n};\n\nfor(var v of o) \n console.log(v); // 0 1 2 3 ... 9"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"Object"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"JavaScript作爲一門面向對象編程語言,類是整個語言的基礎。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"但是,JavaScript中的類和其他語言(Java、C++等)中的類有一定差異。因爲,JavaScript的類是基於原型實現的;而其他諸如Java的語言是基於預先定義的類實現的。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"由於是基於原型的實現方式,JavaScript中的類只是對象的一個私有屬性,而原型則成爲至關重要的一員,用於構建JavaScript的整個繼承體系。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"JavaScript中的幾個基本類型,都在對象類型中有一個“親戚”。它們是:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Number;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"String;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Boolean;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Symbol。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"所以,必須知道 "},{"type":"codeinline","content":[{"type":"text","text":"2"}]},{"type":"text","text":" 和 "},{"type":"codeinline","content":[{"type":"text","text":"new Number(2)"}]},{"type":"text","text":" 是完全不同的值,前者是Number類型,後者是對象Object類型。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Number、String、Boolean三個類型比較特殊,當和"},{"type":"codeinline","content":[{"type":"text","text":"new"}]},{"type":"text","text":"搭配時,表示新建對象;當直接調用時,表示類型轉換。但是,Symbol比較特殊,它只能作爲構造器使用,和 "},{"type":"codeinline","content":[{"type":"text","text":"new"}]},{"type":"text","text":" 搭配會報錯。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"實際上,JavaScript語言在設計上視圖模糊對象和基本類型的關係。比如,在基本類型上可以調用對應類型的對象方法,甚至在原型上添加的方法可以在基本類型上使用,比如下面的代碼:"}]},{"type":"codeblock","attrs":{"lang":"javascript"},"content":[{"type":"text","text":"\"abc\".charAt(0); // a\n\nSymbol.prototype.hello = () => console.log(\"hello\");\n\nvar a = Symbol(\"a\");\nconsole.log(typeof a); //symbol,a並非對象\na.hello(); //hello,有效"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"爲什麼會這樣呢? "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這是因爲諸如 "},{"type":"codeinline","content":[{"type":"text","text":"a.b"}]},{"type":"text","text":" 的行爲都涉及到“裝箱”操作,它會根據基礎類型生成一個臨時對象,使得我們能夠在基礎類型上調用對應對象的方法。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"請注意:"},{"type":"text","marks":[{"type":"strong"}],"text":"裝箱機制會頻繁產生臨時對象,在一些對性能要求較高的場景下,我們應該儘量避免對基本類型做裝箱轉換。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"類型轉換"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"因爲JavaScript是弱類型語言,所以類型轉換髮生非常頻繁,大部分常見運算都會先進行類型轉換。大部分類型轉換符合人類的直覺,但是如果我們不去理解類型轉換的嚴格定義,很容易造成一些代碼中的判斷失誤。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"比如 "},{"type":"codeinline","content":[{"type":"text","text":"=="}]},{"type":"text","text":" 比較運算,它屬於設計失誤,在實踐中通常被禁止使用,轉而使用 "},{"type":"codeinline","content":[{"type":"text","text":"==="}]},{"type":"text","text":" 。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"下面是常見類型之間的轉換規則:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/68/6846bb62a347b633698f3764c46bea70.jpeg","alt":null,"title":"","style":[{"key":"width","value":"100%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"除此之外,還有一些可以顯式調用的類型轉換方法:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"`parseInt`、`parseFloat`"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在不傳入第二個參數的情況下,"},{"type":"codeinline","content":[{"type":"text","text":"parseInt"}]},{"type":"text","text":" 只支持16進制前綴 "},{"type":"codeinline","content":[{"type":"text","text":"0x"}]},{"type":"text","text":",而且會忽略非數字字符,也不支持科學計數法。在一些古老的瀏覽器環境中,"},{"type":"codeinline","content":[{"type":"text","text":"parseInt"}]},{"type":"text","text":" 還支持0開頭的數字作爲8進制前綴,這是很多錯誤的來源。所以在任何環境下,都建議傳入parseInt的"},{"type":"text","marks":[{"type":"strong"}],"text":"第二個參數"},{"type":"text","text":"。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"javascript"},"content":[{"type":"text","text":"parseInt(\"10\");\t\t\t // 10\nparseInt(\"19\",10);\t\t// 19 (10+9)\nparseInt(\"11\",2);\t\t // 3 (2+1)\nparseInt(\"17\",8);\t\t // 15 (8+7)\nparseInt(\"1f\",16);\t\t// 31 (16+15)\nparseInt(\"010\");\t\t // 未定:10 或 8"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"parseFloat()"}]},{"type":"text","text":" 函數可解析一個字符串,並返回一個浮點數。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"該函數先判斷指定字符串中的首個字符是否是數字。如果是,則對字符串進行解析,直到到達數字的末端爲止;否則返回"},{"type":"codeinline","content":[{"type":"text","text":"NaN"}]},{"type":"text","text":"。建議通過調用 "},{"type":"codeinline","content":[{"type":"text","text":"isNaN()"}]},{"type":"text","text":" 函數來判斷 "},{"type":"codeinline","content":[{"type":"text","text":"parseFloat"}]},{"type":"text","text":" 的返回結果是否是 NaN。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"拆箱操作"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"和裝箱操作對應的是“拆箱”操作,也就是說把對象轉變爲基本類型,比如Number和String之間的轉換,都要先進行拆箱操作,取出基本類型,然後再把基本類型轉換爲對應地String或者Number。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在JavaScript標準中,規定了 "},{"type":"codeinline","content":[{"type":"text","text":"ToPrimitive"}]},{"type":"text","text":" 內置函數,用於實現拆箱,它有一個參數 "},{"type":"codeinline","content":[{"type":"text","text":"hint"}]},{"type":"text","text":",用來表示要轉換的類型,有三個取值:"},{"type":"codeinline","content":[{"type":"text","text":"number"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"string"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"default"}]},{"type":"text","text":"。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"但是,如果沒有實現 "},{"type":"codeinline","content":[{"type":"text","text":"ToPrimitive"}]},{"type":"text","text":",則會嘗試調用 "},{"type":"codeinline","content":[{"type":"text","text":"valueOf"}]},{"type":"text","text":" 和 "},{"type":"codeinline","content":[{"type":"text","text":"toString"}]},{"type":"text","text":" 來獲得拆箱後的基本類型。如果 "},{"type":"codeinline","content":[{"type":"text","text":"valueOf"}]},{"type":"text","text":" 和 "},{"type":"codeinline","content":[{"type":"text","text":"toString"}]},{"type":"text","text":" 都不存在,或者沒有返回基本類型,則會產生類型錯誤 "},{"type":"codeinline","content":[{"type":"text","text":"TypeError"}]},{"type":"text","text":"。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"javascript"},"content":[{"type":"text","text":"let user = {\n name: \"John\",\n money: 1000,\n\n [Symbol.toPrimitive](hint) {\n alert(`hint: ${hint}`);\n return hint == \"string\" ? `{name: \"${this.name}\"}` : this.money;\n }\n};\n\nalert(user); // hint: string -> {name: \"John\"}\nalert(+user); // hint: number -> 1000\nalert(user + 500); // hint: default -> 1500\n\nlet user = {\n name: \"John\",\n money: 1000,\n\n // for hint=\"string\"\n toString() {\n return `{name: \"${this.name}\"}`;\n },\n\n // for hint=\"number\" or \"default\"\n valueOf() {\n return this.money;\n }\n\n};\n\nalert(user); // toString -> {name: \"John\"}\nalert(+user); // valueOf -> 1000\nalert(user + 500); // valueOf -> 1500"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"詳細解說可以參考"},{"type":"link","attrs":{"href":"https://javascript.info/object-toprimitive","title":""},"content":[{"type":"text","text":"這裏"}]},{"type":"text","text":"。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"對象"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"JavaScript的對象和其他語言有很多不同之處,比如其他語言都要定義好“類”,纔可以創建對象,而JavaScript則可以不用預先定義類;反而,它卻可以動態給對象添加屬性,而其他語言卻有點困難…"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"前面已經說了,JavaScript的對象系統是以“原型”這一概念實現的,除過原型,還有下面兩種方式可以用來實現對象系統:"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"類,預先定義好“類”,然後批量生成對象,如Java、C++、Objective-C等;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"duck-typing,只要走起來像鴨子、游泳像鴨子、叫起來也像鴨子,那麼它就是一隻鴨子,動態語言通常會支持,比如Python、Go。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"那麼,我們先來看看在人類思維模式下,對象究竟是什麼。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":">對象這一概念在人類的幼兒期形成,這遠遠早於我們編程邏輯中常用的值、過程等概念。在幼年期,我們總是先認識到某一個蘋果能喫(這裏的某一個蘋果就是一個對象),繼而認識到所有的蘋果都可以喫(這裏的所有蘋果,就是一個類),再到後來我們才能意識到三個蘋果和三個梨之間的聯繫,進而產生數字“3”(值)的概念。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"JavaScript使用的原型概念,實際上非常符合我們人類在經過萬億年進化之後才形成的認知模式。從小時候一無所知開始,慢慢接觸的事物越來越多,自我得到擴展,慢慢地又可以舉一反三,進行類比,物理世界的所有客觀存在都被映射到我們的大腦中,並形成了獨特的標記。這樣不斷擴充我們自己的認知,最終形成一套獨特而高效的世界觀。原型的含義就是這樣,在概念和範圍上從小到大,不斷擴展,從已知到未知,從直觀到抽象,最終延伸出整個體系。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"只不過,JavaScript推出之時受管理層之命被要求模仿Java,所以,JavaScript創始人Brendan Eich在“原型運行時”的基礎上引入了new、this等語言特性,使之“看起來更像Java”。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"對象特徵"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"不管是何種OOP,總結來看,它們都有這些特徵:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"numberedlist","attrs":{"start":"1","normalizeStart":1},"content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":1,"align":null,"origin":null},"content":[{"type":"text","text":"對象具有唯一標識性:即使完全相同的兩個對象,也並非同一個對象。"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":2,"align":null,"origin":null},"content":[{"type":"text","text":"對象有狀態:對象具有狀態,同一對象可能處於不同狀態之下。"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":3,"align":null,"origin":null},"content":[{"type":"text","text":"對象具有行爲:即對象的狀態,可能因爲它的行爲產生變遷。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"JavaScript同樣也滿足這三條。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"一般而言,各種語言的對象唯一標識性都是用內存地址來體現的。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"關於對象的第二個和第三個特徵“狀態和行爲”,不同語言會使用不同的術語來抽象描述它們,比如C++中稱它們爲“成員變量”和“成員函數”,Java中則稱它們爲“屬性”和“方法”。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在 JavaScript中,將狀態和行爲統一抽象爲“屬性”,考慮到 JavaScript中將函數設計成一種特殊對象,所以 JavaScript中的行爲和狀態都能用屬性來抽象。例如下面的對象就含有兩個屬性:"}]},{"type":"codeblock","attrs":{"lang":"javascript"},"content":[{"type":"text","text":"var student = {\n age: 10,\n study() {\n console.log(\"I'm studying\");\n }\n};"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在這種方式下,JavaScript對象擁有了極高的動態特性,這是因爲"},{"type":"text","marks":[{"type":"strong"}],"text":"JavaScript賦予了使用者在運行時爲對象添改狀態和行爲的能力"},{"type":"text","text":"。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"兩類屬性"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"JavaScript對象的屬性可以分爲兩類,一類是"},{"type":"text","marks":[{"type":"strong"}],"text":"數據屬性"},{"type":"text","text":",一類是"},{"type":"text","marks":[{"type":"strong"}],"text":"訪問器屬性"},{"type":"text","text":"。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"數據屬性,比較接近於其它語言的屬性概念,核心是屬性值。數據屬性具有四個特徵。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"value:就是屬性的值。"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"writable:決定屬性能否被賦值。"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"enumerable:決定 "},{"type":"codeinline","content":[{"type":"text","text":"for in"}]},{"type":"text","text":" 能否枚舉該屬性。"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"configurable:決定該屬性能否被刪除或者改變特徵值。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"訪問器(getter/setter)屬性,它也有四個特徵:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"getter:函數或undefined,在取屬性值時被調用。"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"setter:函數或undefined,在設置屬性值時被調用。"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"enumerable:決定"},{"type":"codeinline","content":[{"type":"text","text":"for in"}]},{"type":"text","text":"能否枚舉該屬性。"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"configurable:決定該屬性能否被刪除或者改變特徵值。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"通常用於定義屬性的代碼會產生數據屬性,其中的 "},{"type":"codeinline","content":[{"type":"text","text":"writable"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"enumerable"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"configurable"}]},{"type":"text","text":" 都默認爲"},{"type":"codeinline","content":[{"type":"text","text":"true"}]},{"type":"text","text":"。我們可以使用內置函數 "},{"type":"codeinline","content":[{"type":"text","text":"Object.getOwnPropertyDescripter"}]},{"type":"text","text":" 來查看,可以使用 "},{"type":"codeinline","content":[{"type":"text","text":"Object.defineProperty"}]},{"type":"text","text":" 定義屬性屬性,如以下代碼所示:"}]},{"type":"codeblock","attrs":{"lang":"javascript"},"content":[{"type":"text","text":"var student = {\n age: 10,\n get study() {\n console.log(\"getter I'm studying\");\n },\n set study(a) {\n console.log(\"setter I'm studying\");\n }\n};\n> Object.getOwnPropertyDescriptor(student, 'age')\n{value: 10, writable: true, enumerable: true, configurable: true}\n\n> Object.getOwnPropertyDescriptor(student, 'study')\n{enumerable: true, configurable: true, get: ƒ, set: ƒ}"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這樣,我們就理解了,實際上JavaScript對象在運行時是一個“屬性的集合”,屬性以字符串或者Symbol爲key,以數據屬性特徵值或者訪問器屬性特徵值爲value。對象也是這些屬性集合的索引結構。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"內置對象"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果只有用戶自定義的對象,還不能寫出一個合法且有用的程序。例如,和數據相關的Array,和時間相關的Date,缺少這些對象,實在算不上一個讓人滿意的程序。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"幸好,JavaScript已經提供了這些內置對象,它們可以被分爲很多種,下面就一一介紹。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"可以把JavaScript對象分爲以下幾類:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"宿主對象(host Objects):由JavaScript宿主環境提供的對象,它們的行爲完全由宿主環境決定。"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"內置對象(Built-in Objects):由JavaScript語言提供的對象,也就是除過宿主對象之外的所有對象。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" - 固有對象(Intrinsic Objects ):由標準規定,隨着JavaScript運行時被創建而自動創建的對象。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" - 原生對象(Native Objects):用戶可以通過Array、RegExp等內置構造器或者特殊語法創建的對象。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" - 普通對象(Ordinary Objects):用戶通過{}語法、Object構造器或者class關鍵字定義類創建的對象,它能夠被原型繼承。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"宿主對象"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"ECMAScript給出的定義如下:"}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"object supplied by the host environment to complete the execution environment of ECMAScript. NOTE: Any object that is not native is a host object."}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"宿主對象就是,由宿主環境提供,用以構建完整的ECMAScript執行環境的對象。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"JavaScript宿主中最熟悉的就是瀏覽器了,當然也有操作系統,比如node的執行引擎V8。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在瀏覽器環境中,所有的BOM和DOM都是宿主對象,BOM中的window上又有很多屬性,如document。實際上,這個全局對象window上的屬性,一部分來自瀏覽器環境,另一部分則來自JavaScript語言(用"},{"type":"codeinline","content":[{"type":"text","text":"var"}]},{"type":"text","text":"定義的全局變量,最終都會變成"},{"type":"codeinline","content":[{"type":"text","text":"window"}]},{"type":"text","text":"對象的屬性)。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"BOM"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Browser Object Model (BOM)是Web的重要組成部分,裏面包含衆多對象,如下:"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Window"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Location"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Navigator"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Screen"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"History"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"DOM"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"JavaScript Document Object Model (DOM)提供了衆多API用於操作DOM元素。包括:"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"選擇元素,"},{"type":"codeinline","content":[{"type":"text","text":"getElementBy*"}]},{"type":"text","text":";"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"遍歷元素,"},{"type":"codeinline","content":[{"type":"text","text":"parentNode"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"firstChild"}]},{"type":"text","text":"等;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"操作元素,"},{"type":"codeinline","content":[{"type":"text","text":"createElement"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"innerHTML"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"append"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"insertBefore"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"replaceChild"}]},{"type":"text","text":"等;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"操作屬性,"},{"type":"codeinline","content":[{"type":"text","text":"setAttribute"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"getAttribute"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"hasAttribute"}]},{"type":"text","text":"等;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"操作CSS樣式,"},{"type":"codeinline","content":[{"type":"text","text":"style"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"getComputedStyle"}]},{"type":"text","text":" 、"},{"type":"codeinline","content":[{"type":"text","text":"height"}]},{"type":"text","text":"等;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"事件處理,"},{"type":"codeinline","content":[{"type":"text","text":"onclick"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"onscroll"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"load"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"addEventListener"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"mouseover"}]},{"type":"text","text":"、"},{"type":"codeinline","content":[{"type":"text","text":"keyup"}]},{"type":"text","text":"等;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"表單處理。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"內置對象"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"ECMA-262 把內置對象(built-in object)定義爲:由 ECMAScript 提供的、獨立於宿主環境的所有對象,在 ECMAScript 程序開始執行時出現。所以,在JavaScript引擎初始化的時候就會創建好,我們直接拿來用即可。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"固有對象"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"固有對象是由標準規定,隨着JavaScript運行時啓動而自動創建的對象實例。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"固有對象在任何JS代碼執行前就已經被創建出來了,它們通常扮演者類似基礎庫的角色。我們前面提到的“類”其實就是固有對象的一種。ECMA標準爲我們提供了一份固有對象表,裏面含有150+個"},{"type":"link","attrs":{"href":"https://www.ecma-international.org/ecma-262/9.0/index.html#sec-well-known-intrinsic-objects","title":""},"content":[{"type":"text","text":"固有對象"}]},{"type":"text","text":"。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"原生對象"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"ECMAScript給出的定義:"}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"object in an ECMAScript implementation whose semantics are fully defined by this specification rather than by the host environment. NOTE Standard native objects are defined in this specification. Some native objects are built-in; others may be constructed during the course of execution of an ECMAScript program."}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"也就是說,能夠通過語言本身的構造器創建的對象稱作原生對象。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在JavaScript標準中,提供了30多個構造器。按照不同應用場景,分成了以下幾個種類。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/68/6830ca56e9faac32f8ec9aca1775b853.png","alt":null,"title":"","style":[{"key":"width","value":"100%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這些對象可以用 "},{"type":"codeinline","content":[{"type":"text","text":"new"}]},{"type":"text","text":" 運算符創建新對象,但是卻無法用 "},{"type":"codeinline","content":[{"type":"text","text":"extends"}]},{"type":"text","text":" 繼承。可以這麼認爲:這些對象都是爲了特定能力或者性能,而設計出來的特權對象。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章