鏈接:https://time.geekbang.org/column/intro/154
(一HTML語義)
這里我們可以介紹一下 em 標(biāo)簽。
今天我吃了一個<em>蘋果</em>劈猿。
今天我吃了<em>一個</em>蘋果拙吉。
章 - 回顯示
<h1>HTML語義</h1>
<p>balah balah balah balah</p>
<h2>弱語義</h2>
<p>balah balah</p>
<h2>結(jié)構(gòu)性元素</h2>
<p>balah balah</p>
......
h1-h6 是最基本的標(biāo)題,它們表示了文章中不同層級的標(biāo)題揪荣。有些時候筷黔,我們會有副標(biāo)題,為了避免副標(biāo)題產(chǎn)生額外的一個層級仗颈,我們使用 hgroup 標(biāo)簽佛舱。
<hgroup>
<h1>JavaScript對象</h1>
<h2>我們需要模擬類嗎?</h2>
</hgroup>
<p>balah balah</p>
......
從 HTML 5 開始挨决,我們有了 section 標(biāo)簽请祖,這個標(biāo)簽可不僅僅是一個“有語義的 div”,它會改變 h1-h6 的語義凰棉。section 的嵌套會使得其中的 h1-h6 下降一級损拢,因此,在 HTML5 以后撒犀,我們只需要 section 和 h1 就足以形成文檔的樹形結(jié)構(gòu):
<section>
<h1>HTML語義</h1>
<p>balah balah balah balah</p>
<section>
<h1>弱語義</h1>
<p>balah balah</p>
</section>
<section>
<h1>結(jié)構(gòu)性元素</h1>
<p>balah balah</p>
</section>
......
</section>
作為整體結(jié)構(gòu)的語義類標(biāo)簽
<body>
<header>
<nav>
……
</nav>
</header>
<aside>
<nav>
……
</nav>
</aside>
<section>……</section>
<section>……</section>
<section>……</section>
<footer>
<address>……</address>
</footer>
</body>
article 是一種特別的結(jié)構(gòu)福压,它表示具有一定獨(dú)立性質(zhì)的文章掏秩。所以,article 和 body 具有相似的結(jié)構(gòu)荆姆,同時蒙幻,一個 HTML 頁面中,可能有多個 article 存在胆筒。一個典型的場景是多篇新聞?wù)故驹谕粋€新聞專題頁面中邮破,這種類似報(bào)紙的多文章結(jié)構(gòu)適合用 article 來組織。
article 是一種特別的結(jié)構(gòu)仆救,它表示具有一定獨(dú)立性質(zhì)的文章抒和。所以,article 和 body 具有相似的結(jié)構(gòu)彤蔽,同時摧莽,一個 HTML 頁面中,可能有多個 article 存在顿痪。一個典型的場景是多篇新聞?wù)故驹谕粋€新聞專題頁面中镊辕,這種類似報(bào)紙的多文章結(jié)構(gòu)適合用 article 來組織。
body 里面有自己的 header 和 footer蚁袭,然后里面是豎篇的 article征懈,每一個 article 里面都有自己的 header、section揩悄、footer卖哎。這是一個典型的多文章結(jié)構(gòu)。在這個結(jié)構(gòu)里删性,我們看到了一些新標(biāo)簽棉饶,我也來逐個介紹一下。header镇匀,如其名照藻,通常出現(xiàn)在前部,表示導(dǎo)航或者介紹性的內(nèi)容汗侵。footer幸缕,通常出現(xiàn)在尾部,包含一些作者信息晰韵、相關(guān)鏈接发乔、版權(quán)信息等。header 和 footer 一般都是放在 article 或者 body 的直接子元素雪猪,但是標(biāo)準(zhǔn)中并沒有明確規(guī)定栏尚,footer 也可以和 aside,nav只恨,section 相關(guān)聯(lián)(header 不存在關(guān)聯(lián)問題)译仗。aside 表示跟文章主體不那么相關(guān)的部分抬虽,它可能包含導(dǎo)航、廣告等工具性質(zhì)的內(nèi)容纵菌。aside 很容易被理解為側(cè)邊欄阐污,實(shí)際上二者是包含關(guān)系,側(cè)邊欄是 aside咱圆,aside 不一定是側(cè)邊欄笛辟。aside 和 header 中都可能出現(xiàn)導(dǎo)航(nav 標(biāo)簽),二者的區(qū)別是序苏,header 中的導(dǎo)航多數(shù)是到文章自己的目錄手幢,而 aside 中的導(dǎo)航多數(shù)是到關(guān)聯(lián)頁面或者是整站地圖。最后 footer 中包含 address忱详,這是個非常容易被誤用的標(biāo)簽弯菊。address 并非像 date 一樣,表示一個給機(jī)器閱讀的地址踱阿,而是表示“文章(作者)的聯(lián)系方式”,address 明確地只關(guān)聯(lián)到 article 和 body钦铁。
(二 如何運(yùn)用語義類標(biāo)簽來呈現(xiàn)Wiki網(wǎng)頁)
類型轉(zhuǎn)換
裝箱轉(zhuǎn)換每一種基本類型 Number软舌、String、Boolean牛曹、Symbol 在對象中都有對應(yīng)的類佛点,所謂裝箱轉(zhuǎn)換,正是把基本類型轉(zhuǎn)換為對應(yīng)的對象黎比,它是類型轉(zhuǎn)換中一種相當(dāng)重要的種類超营。前文提到,全局的 Symbol 函數(shù)無法使用 new 來調(diào)用阅虫,但我們?nèi)钥梢岳醚b箱機(jī)制來得到一個 Symbol 對象演闭,我們可以利用一個函數(shù)的 call 方法來強(qiáng)迫產(chǎn)生裝箱。我們定義一個函數(shù)颓帝,函數(shù)里面只有 return this米碰,然后我們調(diào)用函數(shù)的 call 方法到一個 Symbol 類型的值上,這樣就會產(chǎn)生一個 symbolObject购城。我們可以用 console.log 看一下這個東西的 type of吕座,它的值是 object,我們使用 symbolObject instanceof 可以看到瘪板,它是 Symbol 這個類的實(shí)例吴趴,我們找它的 constructor 也是等于 Symbol 的,所以我們無論從哪個角度看侮攀,它都是 Symbol 裝箱過的對象:
/** 裝箱*/
var symbolObject = (function(){ return this; }).call(Symbol("a"));
console.log(typeof symbolObject); //object
console.log(symbolObject instanceof Symbol); //true
console.log(symbolObject.constructor == Symbol); //true
var symbolObject = Object(Symbol("a")); console.log(typeof symbolObject); //object console.log(symbolObject instanceof Symbol); //true console.log(symbolObject.constructor == Symbol); //true
var symbolObject = Object(Symbol("a"));
console.log(Object.prototype.toString.call(symbolObject)); //[object Symbol]
/拆箱*/
在 JavaScript 標(biāo)準(zhǔn)中锣枝,規(guī)定了 ToPrimitive 函數(shù)厢拭,它是對象類型到基本類型的轉(zhuǎn)換(即,拆箱轉(zhuǎn)換)惊橱。對象到 String 和 Number 的轉(zhuǎn)換都遵循“先拆箱再轉(zhuǎn)換”的規(guī)則蚪腐。通過拆箱轉(zhuǎn)換,把對象變成基本類型税朴,再從基本類型轉(zhuǎn)換為對應(yīng)的 String 或者 Number回季。拆箱轉(zhuǎn)換會嘗試調(diào)用 valueOf 和 toString 來獲得拆箱后的基本類型。如果 valueOf 和 toString 都不存在正林,或者沒有返回基本類型泡一,則會產(chǎn)生類型錯誤 TypeError。
var o = {
valueOf : () => {console.log("valueOf"); return {}},
toString : () => {console.log("toString"); return {}}
}
o * 2
// valueOf
// toString
// TypeError
我們定義了一個對象 o觅廓,o 有 valueOf 和 toString 兩個方法鼻忠,這兩個方法都返回一個對象,然后我們進(jìn)行 o2 這個運(yùn)算的時候杈绸,你會看見先執(zhí)行了 valueOf帖蔓,接下來是 toString,最后拋出了一個 TypeError瞳脓,這就說明了這個拆箱轉(zhuǎn)換失敗了塑娇。到 String 的拆箱轉(zhuǎn)換會優(yōu)先調(diào)用 toString。我們把剛才的運(yùn)算從 o2 換成 String(o)劫侧,那么你會看到調(diào)用順序就變了埋酬。
···
var o = {
valueOf : () => {console.log("valueOf"); return {}},
toString : () => {console.log("toString"); return {}}
}
String(o)
// toString
// valueOf
// TypeError
···
在 ES6 之后,還允許對象通過顯式指定 @@toPrimitive Symbol 來覆蓋原有的行為烧栋。
···
var o = {
valueOf : () => {console.log("valueOf"); return {}},
toString : () => {console.log("toString"); return {}}
}
o[Symbol.toPrimitive] = () => {console.log("toPrimitive"); return "hello"}
console.log(o + "")
// toPrimitive
// hello
···
JavaScript 對象的特征
對象具有唯一標(biāo)識性:即使完全相同的兩個對象写妥,也并非同一個對象。
對象有狀態(tài):對象具有狀態(tài)审姓,同一對象可能處于不同狀態(tài)之下珍特。
對象具有行為:即對象的狀態(tài),可能因?yàn)樗男袨楫a(chǎn)生變遷魔吐。
var o1 = { a: 1 };
var o2 = { a: 1 };
console.log(o1 == o2); // false
對 JavaScript 來說次坡,屬性并非只是簡單的名稱和值,JavaScript 用一組特征(attribute)來描述屬性(property)画畅。先來說第一類屬性砸琅,數(shù)據(jù)屬性。它比較接近于其它語言的屬性概念轴踱。數(shù)據(jù)屬性具有四個特征症脂。
value:就是屬性的值。
writable:決定屬性能否被賦值。
enumerable:決定 for in 能否枚舉該屬性诱篷。
configurable:決定該屬性能否被刪除或者改變特征值
第二類屬性是訪問器(getter/setter)屬性壶唤,它也有四個特征。getter:函數(shù)或 undefined棕所,在取屬性值時被調(diào)用闸盔。setter:函數(shù)或 undefined,在設(shè)置屬性值時被調(diào)用琳省。enumerable:決定 for in 能否枚舉該屬性迎吵。configurable:決定該屬性能否被刪除或者改變特征值。
如果所有對象都有私有字段[[prototype]]针贬,就是對象的原型击费;讀一個屬性,如果對象本身沒有桦他,則會繼續(xù)訪問對象的原型蔫巩,直到原型為空或者找到為止。
這個模型在 ES 的各個歷史版本中并沒有很大改變快压,但從 ES6 以來圆仔,JavaScript 提供了一系列內(nèi)置函數(shù),以便更為直接地訪問操縱原型蔫劣。三個方法分別為:Object.create 根據(jù)指定的原型創(chuàng)建新對象坪郭,原型可以是 null;Object.getPrototypeOf 獲得一個對象的原型拦宣;Object.setPrototypeOf 設(shè)置一個對象的原型。
在 JavaScript 中信姓,我們把不帶控制能力的語句稱為普通語句鸵隧。普通語句有下面幾種。聲明類語句var 聲明const 聲明let 聲明函數(shù)聲明類聲明表達(dá)式語句空語句debugger 語句這些語句在執(zhí)行時意推,從前到后順次執(zhí)行(我們這里先忽略 var 和函數(shù)聲明的預(yù)處理機(jī)制)豆瘫,沒有任何分支或者重復(fù)執(zhí)行邏輯。普通語句執(zhí)行后菊值,會得到 [[type]] 為 normal 的 Completion Record外驱,JavaScript 引擎遇到這樣的 Completion Record,會繼續(xù)執(zhí)行下一條語句腻窒。這些語句中昵宇,只有表達(dá)式語句會產(chǎn)生 [[value]],當(dāng)然儿子,從引擎控制的角度瓦哎,這個 value 并沒有什么用處。如果你經(jīng)常使用 Chrome 自帶的調(diào)試工具,可以知道蒋譬,輸入一個表達(dá)式割岛,在控制臺可以得到結(jié)果,但是在前面加上 var犯助,就變成了 undefined癣漆。Chrome 控制臺顯示的正是語句的 Completion Record 的[[value]]。