vue源碼分析(一):準(zhǔn)備知識

1纵穿、節(jié)點(diǎn)類型

常用節(jié)點(diǎn)一共分為三種下隧,分別是元素節(jié)點(diǎn)(element)、屬性節(jié)點(diǎn)(attribute)政恍、文本節(jié)點(diǎn)(text)汪拥。

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <div id="test">

    </div>
</body>
</html>
<script>
    const elementNode = document.getElementById('test')
    const attrNode = elementNode.getAttributeNode('id')
    const textNode = elementNode.firstChild

    console.log(elementNode.nodeType) // 1 元素節(jié)點(diǎn)
    console.log(attrNode.nodeType) // 2 元素節(jié)點(diǎn)
    console.log(textNode.nodeType) // 3 文本節(jié)點(diǎn)
</script>

2、Object.defineProperty

給對象添加屬性:
Object.defineProperty(obj,prop,{descriptor})
obj:要定義屬性的對象
prop:要定義或修改的屬性名稱
descriptor:屬性的描述信息

屬性描述符:

1)configurable: (屬性)是否可重新定義
2)enumerable: (屬性)是否可枚舉
3)value: (屬性)對應(yīng)的初始值
4)writable: (屬性)是否可被修改

let obj = {
    firstName:'A',
    lastName:'B'

}
Object.defineProperty(obj,'fullName',{
    configurable: true, // 可以重新定義屬性
    enumerable:false,// 不能枚舉屬性
    value:'G-H',
    writable:false // 不能修改屬性
})
//writable
console.log(obj.fullName) //value G-H
obj.fullName = 'J-K'//修改了屬性值
console.log(obj.fullName)//仍舊是G-H篙耗,不可修改

//configurable
Object.defineProperty(obj,'fullName',{
    enumerable:false,
    value:'M-N',
}) //如果configurable設(shè)置為false迫筑,則會拋異常-->TypeError: Cannot redefine property: fullName

//enumerable
const names = Object.keys(obj)
console.log(names) //[ 'firstName', 'lastName' ]宪赶,fullName屬性無法枚舉出來

訪問描述符:

5)get: 回調(diào)函數(shù),根據(jù)其他相關(guān)的屬性脯燃,動態(tài)計算得到當(dāng)前屬性值
6)set: 回調(diào)函數(shù)搂妻,監(jiān)視當(dāng)前屬性值的變化,更新其他相關(guān)屬性

    Object.defineProperty(obj,'fullName',{
        get(){
            return this.firstName + '-' + this.lastName
        },
        set(val){
            const names = val.split('-')
            this.firstName = names[0]
            this.lastName = names[1]
        }
    })
    //get
    console.log(obj.fullName) // A-B
    obj.firstName = 'C'
    obj.lastName = 'D'
    console.log(obj.fullName) // C-D get動態(tài)獲取值
    //set
    obj.fullName = 'E-F'
    console.log(obj.firstName,obj.lastName) //E F

3辕棚、obj.hasOwnProperty(prop)

判斷對象自身屬性中规惰,是否具有指定的屬性

var obj = {
    firstName: 'A'
}
console.log(obj.hasOwnProperty('firstName')) // true
console.log(obj.hasOwnProperty('toString')) // false

4棕所、文檔碎片DocumentFragment

文檔碎片的api可以參考這篇文檔:
https://developer.mozilla.org/zh-CN/docs/Web/API/DocumentFragment
document和fragment的區(qū)別:
document:對應(yīng)顯示的頁面,包含n個element,一旦更新了document內(nèi)部的某個元素劫映,整個界面都要更新房午;
fragment:內(nèi)存中保存n個element的容器蹋绽,不與界面關(guān)聯(lián)拍霜,如果更新fragment中的某個element,界面不變挽铁。
有了文檔碎片伟桅,我們就可以更為高效的批量更新多個節(jié)點(diǎn)了。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div>
    <ul id="frag">
        <li>test1</li>
        <li>test2</li>
        <li>test3</li>
    </ul>
</div>
</body>
</html>
<script>
    //document:對應(yīng)顯示的頁面叽掘,包含n個element楣铁,一旦更新了document內(nèi)部的某個元素,整個界面都要更新
    //documentFragment:內(nèi)存中保存n個element的容器更扁,不與界面關(guān)聯(lián)盖腕,如果更新fragment中的某個element,界面不變
    const ul = document.getElementById('frag')
    console.log(ul.innerHTML)
    //1.創(chuàng)建fragment
    const fragment = document.createDocumentFragment()
    //2.取出ul中所有子節(jié)點(diǎn),(包含換行等文本子節(jié)點(diǎn))
    let child = null
    while (child = ul.firstChild) { // 一個節(jié)點(diǎn)只有一個父親(節(jié)點(diǎn)或隸屬document疯潭,或隸屬fragment赊堪,二選一)
        fragment.appendChild(child) // 先將child從document移除,然后放入fragment
    } //每迭代一次竖哩,ul中的節(jié)點(diǎn)出棧
    console.log(ul.innerHTML) // 空哭廉,已經(jīng)將節(jié)點(diǎn)全部轉(zhuǎn)移到fragment中了
    //3.更新fragment中的所有l(wèi)i的內(nèi)容
    let nodes = [].slice.call(fragment.childNodes)
    nodes.forEach(node => {
        if (node.nodeType === 1) {
            node.textContent = 'hello'
        }
    })
    //4.將fragment插回ul
    ul.appendChild(fragment)
</script>

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市相叁,隨后出現(xiàn)的幾起案子遵绰,更是在濱河造成了極大的恐慌,老刑警劉巖增淹,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件椿访,死亡現(xiàn)場離奇詭異,居然都是意外死亡虑润,警方通過查閱死者的電腦和手機(jī)成玫,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人哭当,你說我怎么就攤上這事猪腕。” “怎么了钦勘?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵陋葡,是天一觀的道長。 經(jīng)常有香客問我彻采,道長腐缤,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任肛响,我火速辦了婚禮岭粤,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘终惑。我一直安慰自己绍在,他們只是感情好门扇,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布雹有。 她就那樣靜靜地躺著,像睡著了一般臼寄。 火紅的嫁衣襯著肌膚如雪霸奕。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天吉拳,我揣著相機(jī)與錄音质帅,去河邊找鬼。 笑死留攒,一個胖子當(dāng)著我的面吹牛煤惩,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播炼邀,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼魄揉,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了拭宁?” 一聲冷哼從身側(cè)響起洛退,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎杰标,沒想到半個月后兵怯,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡腔剂,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年媒区,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,785評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡袜漩,死狀恐怖谅畅,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情噪服,我是刑警寧澤毡泻,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站粘优,受9級特大地震影響仇味,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜雹顺,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一丹墨、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧嬉愧,春花似錦贩挣、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至裕便,卻和暖如春绒净,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背偿衰。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工挂疆, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人下翎。 一個月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓缤言,卻偏偏與公主長得像,于是被迫代替她去往敵國和親视事。 傳聞我的和親對象是個殘疾皇子胆萧,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評論 2 354