h函數為什麼叫h?

語言: CN / TW / HK

title:h函數為什麼叫h? tags: js categories: js theme: channing-cyan highlight:


看 vue 源碼的時候,提到了snabbdom,而這個庫裏有個很重要的函數h

我就好奇了,為啥用hh是什麼的縮寫,表示的到底是什麼?

然後就翻到hyperScript這個詞,然後找到了解釋

Create HyperText with JavaScript, on client or server

htmlHyperText Markup Language的縮寫,超文本標記語言,本質是文本,但用的是特殊的標記語言寫的,其可以表示 純文本和媒體資源、表單等其他的非文本,所以是超文本。

那麼hyperScript其實是用 js 創建超文本,這裏的超文本特指HTML,而 JS 裏可以用DOM(document object model)表示HTML,但 js 本身是有DOM API的,為什麼作者還要寫這個庫?

舉個例子就明白了:

創建這樣的結構:

```html

顏醬真酷

```

傳統的方式:

js function createDiv() { const span = document.createElement("span"); span.className = "son"; const div = document.createElement("div"); div.className = "parent"; div.appendChild(span); return div; }

顯然這還是結構簡單,屬性少的情況,如果很多的話,非常繁瑣,而且可讀性差。

於是想到了,用簡單的語句描述,想要的 DOM 結構,然後用函數統一生成想要的結構

其實一個元素的三斧頭:標籤名、標籤的其他自身信息、子元素

js function hyperScript(tagName, attrs, children) { // .... } const h = hyperScript; // 這樣執行這個方法就可以生成上面的div了 h("div", { className: "parent" }, h("span", { className: "son" }, "顏醬真酷"));

這樣可讀性強很多,所以這個庫的,h函數,是用節點的描述(標籤名、屬性和事件、子元素)去創建真實節點的,並返回這個真實節點。

snabbdom這個庫是處理vnode的,所以它的的h函數,是用節點的描述(標籤名、標籤的其他自身信息、子元素)創建虛擬節點的,並返回這個虛擬節點。

於是平時看到h 函數的時候,心裏的聯想是Create Virtual HyperText with JavaScript

大白話,h函數就是用節點的描述(標籤名、標籤的其他自身信息、子元素)創建虛擬節點。

為什麼有了 h 函數還要 vnode 函數?

其實 h 函數,更多的時候,是便於用户傳參,用户只需要考慮三個要素:標籤名、標籤的其他自身信息、子元素。

但是一個vnode有 6 種屬性,其中的 key 是從 data 來的,所以vnode函數需要 5 個參數,用户調用的話,顯然增加理解門檻,所以用h函數簡化了傳參,降低調用門檻,而h函數內部調用vnode函數生成vnode

vnode2 vnode3

h函數的參數最多三個,但只有第一個是必傳項,第二個參數和第三個都是可傳項,所以內部對各種情況作了判斷,已生成正確的vnode

```js // npm i snabbdom 可以快速在編輯器控制枱看下,h三個參數,必填的是第一個,data始終是對象,children可以是數組也可以是字符串 const { h } = require("snabbdom");

console.log(h("div.only-sel")); console.log(h("div.only-data", { name: "demo" })); console.log(h("div.only-text", "qqq")); console.log( h("div.only-text", { key: "data這裏設置key" }, [h("span"), "子text"]) ); ```

vnode4

引用