JavaScript 核心觀念(58) - 物件屬性延伸章節:屬性的特徵 - 屬性特徵與主流框架的關係

前言

接下來這一章節將會實際來看看框架跟本章節所教的關聯性。

屬性特徵與主流框架的關係

接下來主要是想說明物件屬性特徵的觀念在主流框架上有多重要這件事情,這邊我們可以從 Vue.js 來了解求證。

首先我們可以先進入到 Vue.js 的儲存庫

Vue.js

基本上我們常用的 Vue.js CDN,例如:

1
2
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>

這些都是被編譯過的檔案,什麼是被編譯過的檔案呢?還沒有編譯前的 Vue.js 是需要透過編譯工具所編譯,其中 Vue.js 使用了相當多的 ES6 與以上等語法製作出來,因此就會需要使用一些工具來額外編譯。

舉例來講,你可以到儲存庫打開這個路徑 vue/src/core/index.js 來觀看:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import Vue from './instance/index'
import { initGlobalAPI } from './global-api/index'
import { isServerRendering } from 'core/util/env'
import { FunctionalRenderContext } from 'core/vdom/create-functional-component'

initGlobalAPI(Vue)

Object.defineProperty(Vue.prototype, '$isServer', {
get: isServerRendering
})

Object.defineProperty(Vue.prototype, '$ssrContext', {
get () {
/* istanbul ignore next */
return this.$vnode && this.$vnode.ssrContext
}
})

// expose FunctionalRenderContext for ssr runtime helper installation
Object.defineProperty(Vue, 'FunctionalRenderContext', {
value: FunctionalRenderContext
})

Vue.version = '__VERSION__'

export default Vue

可以看到 Vue.js 使用到相當多較新的語法,因此若不使用工具來編譯的話,許多瀏覽器是無法正常運作的,那麼在上面官方程式碼中,我們也可以看到 Object.defineProperty 的語法存在。

接下來來看一段 Vue2 的程式碼:

1
2
3
4
5
6
7
8
9
10
11
12
const app = new Vue({
el: '#app',
data: {
myName: 'Ray',
},
methods: {
test() {
this.myName = 'Ray 2';
console.log(this.myName);
},
},
})

HTML:

1
2
3
4
<div id="app">
{{ myName }}
<button type="button" @click="test">點我</button>
</div>

上面的程式碼我們都知道當我按下 <button type="button" @click="test">點我</button> 時,原本的 myName 會被替換成 Ray 2,而這一段的運作在 官方文件 有描述到:

当你把一个普通的 JavaScript 对象传入 Vue 实例作为 data 选项,Vue 将遍历此对象所有的 property,并使用 Object.defineProperty 把这些 property 全部转为 getter/setter。Object.defineProperty 是 ES5 中一个无法 shim 的特性,这也就是 Vue 不支持 IE8 以及更低版本浏览器的原因。

所以其實雙向綁定的主要關鍵重點在於 Object.defineProperty 語法,因此本章節可以了解到物件屬性的特徵是多麼重要的觀念。

參考文獻