導航:首頁 > 數據處理 > 什麼是js數據劫持

什麼是js數據劫持

發布時間:2023-01-15 13:44:12

1. 網站被劫持了怎麼辦

解決如下:

1、刪除域名泛解析,前往域名服務商,關閉域名的泛解析,就是把域名解析那一項刪掉。舉報劫持的頁面,也就是跳轉的錯誤頁面,然後說明舉報理由。

2、提高伺服器安全配置,將伺服器或空間許可權及配置進行升級;設定安全防護系統,或設定只能自己登錄,其他任何人不通過驗證,無法登錄。

3、查看伺服器事件管理器。當網站域名被劫持,網站文件必定會受到侵入者的篡改,查看伺服器本地事件管理器,找到發生修改日誌的文件,將文件恢復到被篡改前,並將許可權設置為可讀,取消可寫的許可權,需要修改時手動設定為可寫許可權,修改完畢及時改為可讀。

簡介:

名劫持是互聯網攻擊的一種方式,通過攻擊域名解析伺服器(DNS),或偽造域名解析伺服器(DNS)的方法,把目標網站域名解析到錯誤的IP地址從而實現用戶無法訪問目標網站的目的或者蓄意或惡意要求用戶訪問指定IP地址(網站)的目的。

2. 2021-11-10.Vue前端面試題及答案

const vm = new Vue({
...
methods: {
handlerEvent(event) {
console.log(event) // 滑鼠點擊時,獲取到事件對象
}
}
})
1、如果只是事件函數的調用,函數名稱後面不要添加括弧
好處:函數執行時,第一個形式參數會被系統自動注入
一個事件對象,提供給函數使用
@click="handlerEvent"
2、如果事件函數調用執行時,需要傳遞參數,函數名稱後面
必須添加括弧,如果要使用事件對象,就必須手工注入(固定語法)
@click="handlerEvent($event)"

事件冒泡是JS語法中的一種事件觸發機制,描述的是目標元素上的事件一旦發生,就會根據DOM節點結構,將事件逐步依次觸發到父節點上的一種事件機制

原生JS中通過兼容性語法阻止事件冒泡
event.stopPropagation?event.stopPropagation():event.cancelBubble=true

Vue中對於事件冒泡的處理進行了封裝,提供了事件修飾符完成阻止冒泡行為
固定語法:標簽對象的事件屬性上,添加 @事件對象.stop="處理函數"

.self事件修飾符的作用,就是讓事件的觸發方式只能由當前標簽上發生的事件觸發!

.lazy作為表單修飾符,經常用在表單元素上,用於將表單數據的同步機制延遲到表單元素失去焦點時再進行同步,節省資源、提高整體效率!

Vue數據雙向綁定的特性,指代的是Vue實例中的數據和網頁視圖中的數據綁定,實例中數據的更新會直接影響視圖的渲染展示,視圖中的數據更新會自動同步到實例中的數據,這樣的操作機制就是數據雙向綁定機制;Vue底層主要是通過Object.defineProperty()數據劫持的操作方式完成的!

數據劫持本質上就是一種變數的高級聲明方式,通過數據劫持的語法聲明的變數,我們可以針對變數數據的查詢、編輯進行監聽,隨時根據變數的使用情況進行功能的添加,如數據的雙向綁定,完成數據的自動同步和自動渲染!

3. 什麼是DNS劫持什麼是HTTP劫持

DNS劫持:

一般而言,用戶上網的DNS伺服器都是運營商分配的,所以,在這個節點上,運營商可以為所欲為。

例如,訪問ht tp://jiankang.qq.com/index.html,正常DNS應該返回騰訊的ip,而DNS劫持後,會返回一個運營商的中間伺服器ip。訪問該伺服器會一致性的返回302,讓用戶瀏覽器跳轉到預處理好的帶廣告的網頁,在該網頁中再通過iframe打開用戶原來訪問的地址。

HTTP劫持:

在運營商的路由器節點上,設置協議檢測,一旦發現是HTTP請求,而且是html類型請求,則攔截處理。後續做法往往分為2種,1種是類似DNS劫持返回302讓用戶瀏覽器跳轉到另外的地址,還有1種是在伺服器返回的HTML數據中插入js或dom節點(廣告)。

4. Vue面試題集錦

原理:在創建Vue實例時,Vue會遍歷data選項的屬性,利用Object.defineProperty()為屬性添加getter和setter對數據的讀取進行劫持(getter用來依賴手機,setter用來派發更新),並且在內部追蹤依賴,在屬性被訪問和修改時通知變化。每個組件實例會有相應的watcher實例,會在組件渲染過程中記錄依賴的所有數據屬性,之後依賴項被改動時,setter方法會通知依賴與此data的watcher實例重新計算(派發更新),從而使它關聯的組件重新渲染。

一句話總結:vue.js採用數據劫持結合發布-訂閱模式,通過Object.defineProperty()來劫持各個屬性的setter、getter,在數據變動時發布消息給訂閱者,觸發響應的監聽回調。

我的理解:在new Vue的時候,在Observer中通過Object.defineProperty()達到數據劫持,代理所有數據的getter和setter屬性,在每次觸發setter的時候,都會通過Dep來通知Watcher,Watcher作為Observer數據監聽器與Compile模板解析器之間的橋梁,當Observer監聽到數據發生改變的時候,通過Updater來通知Compile更新視圖。而Compile通過Watcher訂閱對應數據,綁定更新函數,通過Dep來添加訂閱者,達到雙向綁定。

Vue實例從創建到銷毀的全過程,就是生命周期。也就是從開始創建、初始化數據、編譯模板、掛載DOM->渲染、更新->渲染、卸載等一系列過程。

它的生命周期中有多個事件鉤子,讓我們在控制整個Vue實例的過程時更容易形成好的邏輯。

它可以分為8個階段:創建前/後、載入前/後、更新前/後、銷毀前/後。

第一次頁面載入時會觸發beforeCreate、created、beforeMounted、mounted

DOM渲染在mounted中就已經完成。

1、beforeCreate:可以在這加個loading事件,在載入實例時觸發;
2、created:初始化完成時的事件寫在這里,如在這結束loading事件,非同步請求也適宜在這里調用;
3、mounted:掛載元素,獲取DOM節點;
4、updated:如果對數據統一處理,在這里寫上相應函數;
5、beforeDestroy:可以放一個確認停止事件的確認框;
6、nextTick:更新數據後立即操作DOM。

1、對象方法v-bind:class="{'orange': isRipe, 'green': isNotRipe}"
2、數組方法v-bind:class="[class1, class2]"
3、行內v-bind:style="{color: color, fontSize: fontSize+'px'}"

1、router-link標簽會渲染為標簽,咋填template中的跳轉都是這種;
2、另一種是編輯式導航,也就是通過js跳轉比如router.push('/home')

M- model ,model 表示數據模型,也可以在model中定義數據修改和操作的業務邏輯
V- view,view表示視圖,它負責將數據模型轉換為視圖展示出來
VM- viewmodel,viewmodel是一個同步view和model的對象,連接view和model,用於監聽數據模型的改變和控制視圖行為

computed:computed是計算屬性,也就是計算值,更多用於計算值的場景。它具有緩存性,computed的值在getter執行後是會緩存的,只有在它依賴的屬性值改變之後,下一次獲取computed的值時重新調用對應的getter來計算。

watch:watch更多的是觀察作用,類似於某些數據的監聽回調,用於觀察props、$emit或者本組件的值,當數據變化時用來執行回調進行後續操作。它不具有緩存性,頁面重新渲染時值不會變化也不會執行。

在style標簽上添加scoped屬性,以表示它的樣式作用於當下的模塊,很好的實現了樣式私有化的目的,但是也得慎用,樣式不易改變。
解決方法:
① 使用混合型的css樣式,混合使用全局樣式和私有樣式。
② 深度作用選擇器:如果你希望scoped樣式中的一個選擇器能夠作用的更深,可以使用>>>操作符。如:<style scoped>.a>>>.b{/ ... /}</style>

一個元素綁定多個事件的寫法有兩種:
1、修飾符的使用

2、在method方法里分別寫兩個事件

Vue組件中的data值不能為對象,因為對象是引用類型,組件可能會被多個實例同時引用,如果data值為對象,將導致多個實例共享一個對象,其中一個組件改變data屬性值,其它實例也會受到影響。

原理:JS執行是單線程的,它是基於事件循環的。所有同步任務都在主線程上執行,形成一個執行棧。主線程之外,還存在一個任務隊列,只要非同步任務有了運行結果,就在任務隊列中放置一個事件。一旦執行棧中的所有同步任務執行完畢,系統就會讀取任務隊列,看看那些對應的非同步任務,等結束等待狀態,進入執行棧,開始執行。主線程不斷重復上面的步驟。主執行的執行過程就是tick,所有的非同步結果都是通過任務隊列來調度的。任務分為兩大類:宏任務和微任務,宏任務包括:setTimeOut等,微任務包括promise.then。

Vue用非同步隊列的方式來控制DOM更新和nextTick回調先後執行。在下次DOM更新循環結束之後執行延遲回調,nextTick主要使用了宏任務和微任務,nextTick把要執行的任務推入一個隊列中,在下一個tick同步執行隊列的所有任務,它是非同步任務中的微任務。如果我們在更新了一個響應式數據後,需要同步拿到這個渲染後的DOM結果,就使用nextTick方法,非同步拿這個結果。
使用方式:
① this. nextTick.then(cb); 非同步

父組件調用子組件的方法
父組件: this.$refs.yeluosen.childMethod()
子組件向父組件傳值並調用方法: $emit
組件之間: bus==$emit+$on

1、第一種方法是直接在子組件中通過this. emit向父組件觸發一個事件,父組件監聽這個事件就行了。
3、第三種都可以實現子組件調用父組件的方法。

keep-alive是Vue內置的一個組件,可以使被包含的組件保留狀態,或避免重新渲染。

原來的組件實例會被復用。這也意味著組件的生命周期鉤子不會再被調用,你可以簡單的監控watch $route對象:

is用來動態切換組件,DOM模板解析

全局的:前置守衛、後置鉤子(beforeEach、afterEach)beforeResolve
單個路由獨享的:beforeEnter
組件級的:beforeRouteEnter(不能獲取組件實例this)、beforeRouteUpdate、beforeRouteLeave
這是因為在執行路有鉤子函數beforeRouteEnter的時候,組件還沒有被創建出來,先執行beforeRouteEnter,再執行周期鉤子函數beforeCreate,可以通過next獲取組件的實例對象,如:next((vm) => {}),參數vm就是組件的實例化對象。

缺點:

優點:

計算屬性是需要復雜的邏輯,可以用方法method代替。

vue-cli提供的腳手架模板有browserify和webpack。

① 是什麼?
Vue框架中的狀態管理,分別是State、Getter、Mutation、Action、Mole。
② 怎麼使用?
新建一個目錄store。
③ 功能場景?
單頁應用中,組件之間的狀態。音樂播放、登錄狀態、加入購物車等。
④ vuex的狀態:
a. State特性:vuex就是一個倉庫,倉庫裡面放了很多對象,其中state就是數據源存放地,對應於一般Vue對象裡面的data。state裡面存放的數據是響應式的,Vue組件從store中讀取數據,若是store中的數據發生改變,依賴這個數據的組件也會發生更新。它通過mapState把全局的state和getters映射到當前組件的computed計算屬性中。
b. Getter特性:getters可以對State進行計算操作,它就是store的計算屬性。雖然在組件內可以做計算屬性,但是getters可以在多組件之間復用。如果一個狀態只在一個組件內使用,可以不用getters。
c. Mutation特性:改變store中state狀態的唯一方法就是提交mutation,每個mutation都有一個字元串類型的事件類型和一個回調函數,我們需要改變state的值就要在回調函數中改變。我們要執行這個回調函數,那我們需要執行一個相應的調用方法:store.commit。
d. Action特性:類似於mutation,不同點在於:Action提交的是mutation,而不是直接變更狀態。Action可以包含任意非同步操作,Action函數接受一個與store實例具有相同方法和屬性的context對象,因此你可以調用context.commit提交一個mutation。或者通過context.state和context.getters來獲取state和getters。Action通過store.dispatch方法觸發:store.dispatch('increment')。
e. Mole特性:Mole其實只是解決了當state中很復雜臃腫的時候,mole可以將store分解為模塊,每個模塊中擁有自己的state、mutation、action和getter。

① 創建組件頁面eg Toast.vue
② 用Vue.extend() 擴展一個組件構造器,再通過實例化組件構造器,就可以創造出可復用的組件。
③ 將toast組件掛載到新創建的div上;
④ 將toast組件的dom添加到body里;
⑤ 修改優化達到動態控制頁面顯示文字跟顯示時間;

修飾符分為:一般修飾符、事件修飾符、按鍵、系統
① 一般修飾符:

② 事件修飾符

③ 按鍵修飾符

④ 系統修飾符(可以用如下修飾符來實現僅在按下相應按鍵時才觸發滑鼠或鍵盤事件的監聽器。)

Vue的核心的功能,是一個視圖模板引擎,但這不是說Vue就不能成為一個框架。在聲明式渲染(視圖模板引擎)的基礎上,我們可以通過添加組件系統、客戶端路由、大規模狀態管理來構建一個完整的框架。更重要的是,這些功能相互獨立,你可以在核心功能的基礎上任意選用其他的部件,不一定要全部整合在一起。可以看到,所說的「漸進式」,其實就是Vue的使用方式,同時也體現了Vue的設計的理念
在我看來,漸進式代表的含義是:主張最少。視圖模板引擎每個框架都不可避免會有自己的一些特點,從而會對使用者有一定的要求,這些要求就是主張,主張有強有弱,它的強勢程度會影響在業務開發中的使用方式。
比如說,Angular,它兩個版本都是強主張的,如果你用它,必須接受以下東西:
必須使用它的模塊機制- 必須使用它的依賴注入- 必須使用它的特殊形式定義組件(這一點每個視圖框架都有,難以避免)所以Angular是帶有比較強的排它性的,如果你的應用不是從頭開始,而是要不斷考慮是否跟其他東西集成,這些主張會帶來一些困擾。
Vue可能有些方面是不如React,不如Angular,但它是漸進的,沒有強主張,你可以在原有大系統的上面,把一兩個組件改用它實現,當jQuery用;也可以整個用它全家桶開發,當Angular用;還可以用它的視圖,搭配你自己設計的整個下層用。也可以函數式,都可以,它只是個輕量視圖而已,只做了自己該做的事,沒有做不該做的事,僅此而已。
漸進式的含義,我的理解是:主張最少,沒有多做職責之外的事。

5. Proxy(vue響應式原理:數據偵測--數據劫持和數據代理)

Object.defineProperty : 通過設定對象屬性getter/setter方法來監聽數據的變化,同時getter也用於依賴收集,而setter在數據變更時通知訂閱者更新視圖。

1.無法檢測到對象屬性的新增或刪除
由於js的動態性,可以為對象追加新的屬性或者刪除其中某個屬性,這點對經過Object.defineProperty方法建立的響應式對象來說,只能追蹤對象已有數據是否被修改,無法追蹤新增屬性和刪除屬性,這就需要另外處理。

2.不能監聽數組的變化
vue在實現數組的響應式時,它使用了一些hack,把無法監聽數組的情況通過重寫數組的部分方法來實現響應式,這也只限制在數組的push/pop/shift/unshift/splice/sort/reverse七個方法,其他數組方法及數組的使用則無法檢測到。

Proxy,字面意思是代理,是ES6提供的一個新的API,用於修改某些操作的默認行為,可以理解為在目標對象之前做一層攔截,外部所有的訪問都必須通過這層攔截,通過這層攔截可以做很多事情,比如對數據進行過濾、修改或者收集信息之類。借用 proxy的巧用 的一幅圖,它很形象的表達了Proxy的作用。

ES6原生提供的Proxy構造函數,用法如下:

其中obj為Proxy要攔截的對象,handler用來定製攔截的操作,返回一個新的代理對象proxy;Proxy代理特點:
1.Proxy的代理針對的是整個對象,而不是像Object.defineProperty針對某個屬性。只需做一層代理就可以監聽同級結構下的所有屬性變化,包括新增屬性和刪除屬性

2.Proxy也可以監聽數組的變化

參考: https://juejin.cn/post/6850418111985352711

6. vue是怎麼將數據綁定到組件的原理

vue將數據綁定到組件的原理如下:

1、當實例化一個Vue構造函數,會執行 Vue 的 init 方法,在 init 方法中主要執行三部分內容,一是初始化環境變數,而是處理 Vue 組件數據,三是解析掛載組件。以上三部分內容構成了 Vue 的整個執行過程。

2、Vue 實現了一個觀察者-消費者(訂閱者)模式來實現數據驅動視圖。通過設定對象屬性的 setter/getter 方法來監聽數據的變化,而每個屬性的 setter 方法就是一個觀察者, 當屬性變化將會向訂閱者發送消息,從而驅動視圖更新。

3、Vue 的訂閱者 watcher 實現在/src/watchr.js。構建一個 watcher 最重要的是 expOrFn 和 cb 兩個參數,cb 是訂閱者收到消息後需要執行的回調,一般來說這個回調都是視圖指令的更新方法,從而達到視圖的更新,但是這也不是必須的,訂閱回調也可以是一個和任何無關的純函數。一個訂閱者最重要的是要知道自己訂閱了什麼,watcher 分析 expOrFn 的 getter 方法,從而間接獲得訂閱的對象屬性。

4、Vue 雙向數據綁定實現

數據與視圖的綁定與同步,最終體現在對數據的讀寫處理過程中,也就是 Object.defineProperty() 定義的數據 set、get 函數中。Vue 中對於的函數為 defineReactive,在精簡版實現中,我只保留了一些基本特性:

function defineReactive(obj, key, value) {
var dep = new Dep()
Object.defineProperty(obj, key, {
enumerable: true,
configurable: true,
get: function reactiveGetter() {
if (Dep.target) {
dep.depend()
}
return value
},
set: function reactiveSetter(newVal) {
if (value === newVal) {
return
} else {
value = newVal
dep.notify()
}
}
})
}

在對數據進行讀取時,如果當前有 Watcher(對數據的觀察者吧,watcher 會負責將獲取的新數據發送給視圖),那將該 Watcher 綁定到當前的數據上(dep.depend(),dep 關聯當前數據和所有的 watcher 的依賴關系),是一個檢查並記錄依賴的過程。而在對數據進行賦值時,如果數據發生改變,則通知所有的 watcher(藉助 dep.notify())。這樣,即便是我們手動改變了數據,框架也能夠自動將數據同步到視圖。

7. 網吧管理軟體載入劫持代碼

建議安裝殺毒軟體。
網吧魚龍混雜,電腦上很有可能會有各種垃圾軟體,最簡單的方式就是安裝殺毒軟體,軟體自帶的防火牆會阻攔大多數病毒。
劫持代碼就是黑客拿到了你的ftp,趁你不注意、蜘蛛正抓取你網站的時候把數據換掉。
等蜘蛛抓取完你的快照後再把數據換回來,這樣你的網站快照就被劫持了,而且你檢查代碼也發現不了問題,由於修改主站標題、關鍵詞、描述導致快照停留時間長。
所有被掛了跳轉鏈接的網頁中絕大多數都是建立在網站被getshell的基礎上的,所以當你在維護網站的時候不能僅僅只刪除js代碼,還要系統性的對網站內的文件進行對比找出後門。

8. vue數據雙向綁定原理

vue.js 採用數據劫持結合發布者-訂閱者模式的方式,通過 Object.defineProperty() 來劫持各個屬性的setter,getter,在數據變動時發布消息給訂閱者,觸發相應的監聽回調。

首先我們為每個vue屬性用Object.defineProperty()實現數據劫持,在監聽數據的過程中,為每個屬性分配一個訂閱者集合的管理數組dep;然後在編譯的時候在該屬性的數組dep中添加訂閱者 watcher,v-model會添加一個訂閱者,{{}}也會,v-bind也會,只要用到該屬性的指令理論上都會,接著為input會添加監聽事件,修改值就會為該屬性賦值,觸發該屬性的set方法,在set方法內通知訂閱者數組dep,訂閱者數組循環調用各訂閱者的update方法更新視圖。

實現步驟:修改輸入框內容 => 在事件回調函數中修改屬性值 => 觸發屬性的 set 方法=>發出通知 dep.notify() => 觸發訂閱者的 update 方法 => 更新視圖。

流程圖

在實例化一個Vue對象的時候,會傳進去一個data對象,之後分成兩個進程,一個進程是對掛載目標元素模板里的v-model和{{ }};兩個指令進行編譯。另一個進程是對傳進去的data對象裡面的數據進行監聽。

上圖中,observe是利用Object.defineProperty()對傳入的data對象進行數據監聽,在數據改變的時候觸發該屬性的set方法,更新該屬性的值,並發布消息,我(該屬性)的值變了。

compile是編譯器,找到vue的指令v-model所在的元素,將data中該屬性的值賦給元素的value,並給這個元素添加二級監聽器,在元素的值改變的時候,將新值賦給data裡面同名屬性,這個時候就完成了單向數據綁定,視圖 >> 模型。

那麼最終的由模型到視圖的更新,依賴於dep和watcher,dep會收集訂閱者,就是綁定了data裡面屬性的元素,在數據更新的時候,會觸發該屬性的set方法,在set里觸發該屬性的消息發布通知函數。而Watcher根據收到的數據變化通知,更新相應的數據。

dep這個東東給大家解釋一下,就是data里的每個屬性都有一個dep對象,dep對象里可以有很多訂閱者(watcher),但是只有一個添加訂閱者的方法和一個發布變化通知的方法,就是模板上可以有多處元素綁定data里的同一個屬性值,所以dep是依賴於data裡面的屬性的。

而Watcher是每個{{ }}有一個,初次編譯的時候,會在new的時候自動更新一下模板的數據,等到下次數據改變的時候,由dep通知數據更新,直接調用watcher的update方法,更新模板的綁定數據。

observer 模塊共分為這幾個部分:

示意圖如下:

Observer的構造函數

value是需要被觀察的數據對象,在構造函數中,會給value增加 ob 屬性,作為數據已經被Observer觀察的標志。如果value是數組,就使用observeArray遍歷value,對value中每一個元素調用observe分別進行觀察。如果value是對象,則使用walk遍歷value上每個key,對每個key調用defineReactive來獲得該key的set/get控制權。

Dep是Observer與Watcher之間的紐帶,也可以認為Dep是服務於Observer的訂閱系統。Watcher訂閱某個Observer的Dep,當Observer觀察的數據發生變化時,通過Dep通知各個已經訂閱的Watcher。

Watcher是用來訂閱數據的變化的並執行相應操作(例如更新視圖)的。Watcher的構造器函數定義如下:

參數中,vm表示組件實例,expOrFn表示要訂閱的數據欄位(字元串表示,例如a.b.c)或是一個要執行的函數,cb表示watcher運行後的回調函數,options是選項對象,包含deep、user、lazy等配置。

Object.defineProperty(obj, prop, descriptor) ,這個語法內有三個參數,分別為 obj (要定義屬性的對象) prop (要定義或修改的屬性的名稱或 Symbol ) descriptor (要定義或修改的屬性描述符=>具體的改變方法)

簡單地說,就是用這個方法來定義一個值。當調用時我們使用了它裡面的get方法,當我們給這個屬性賦值時,又用到了它裡面的set方法;

主要解釋第三個參數 {
value: 設置屬性的值
writable: 值是否可以重寫。true | false
enumerable: 目標屬性是否可以被枚舉。true | false (就是能不能被遍歷出來)
configurable: 目標屬性是否可以被刪除或是否可以再次修改特性 true | false
set: 目標屬性設置值的方法
get:目標屬性獲取值的方法
}

set 是一個函數,接收一個新值,會在值被重寫或修改的時候觸發這個函數
get 是一個函數,返回一個值,會在屬性被調用的時候觸發。


Object.defineProperty()詳解
Object.defineProperty()官方文檔

已經了解到vue是通過數據劫持的方式來做數據綁定的,其中最核心的方法便是通過Object.defineProperty()來實現對屬性的劫持,那麼在設置或者獲取的時候我們就可以在get或者set方法里假如其他的觸發函數,達到監聽數據變動的目的。

我們知道通過Object.defineProperty()可以實現數據劫持,它的屬性在賦值的時候觸發set方法,

當然要是這么粗暴,肯定不行,性能會出很多的問題。

observer用來實現對每個vue中的data中定義的屬性循環用Object.defineProperty()實現數據劫持,以便利用其中的setter和getter,然後通知訂閱者,訂閱者會觸發它的update方法,對視圖進行更新。

為什麼要訂閱者 :在vue中v-model,v-name,{{}}等都可以對數據進行顯示,也就是說假如一個屬性都通過這三個指令了,那麼每當這個屬性改變的時候,相應的這個三個指令的html視圖也必須改變,於是vue中就是每當有這樣的可能用到雙向綁定的指令,就在一個Dep中增加一個訂閱者,其訂閱者只是更新自己的指令對應的數據,也就是v-model='name'和{{name}}有兩個對應的訂閱者,各自管理自己的地方。每當屬性的set方法觸發,就循環更新Dep中的訂閱者。

訂閱發布模式(又稱觀察者模式)定義了一種一對多的關系,讓多個觀察者同時監聽某一個主題對象,這個主題對象的狀態發生改變時就會通知所有觀察者對象。

發布者發出通知 => 主題對象收到通知並推送給訂閱者 => 訂閱者執行相應操作
舉個例子:

2.實現compile: compile的目的就是解析各種指令稱真正的html。

這樣一來就實現了vue的數據雙向綁定。

參考鏈接:
理解VUE雙向數據綁定原理和實現---趙佳樂
Vue的雙向數據綁定原理
vue雙向綁定原理分析
Vue原理解析之observer模塊
深入響應式原理

9. Vue學習系列一 —— MVVM響應式系統的基本實現原理

MVVM是Model-View-ViewModel的簡寫。它模式是MVC—>MVP—>MVVM的進化版。
Model負責用JavaScript對象表示,View負責UI界面顯示,兩者做到了最大限度的分離。
而把Model和View關聯起來的就是ViewModel。ViewModel負責把Model的數據同步到View顯示出來,還負責把View的界面修改同步回Model更新數據。

臟值檢查 : angular.js 是通過臟值檢測的方式來比對數據是否有變更而決定是否更新視圖。
原理是,拷貝一份 _viewModel 在內存中,用戶操作導致 viewModel 發生改變的行為時,框架都會把 _viewModel 和最新的 viewModel 進行深度比較,一旦發現有屬性發生變化,則重新渲染與之綁定的DOM節點。
最簡單的方式就是通過 setInterval() 定時輪詢檢測數據變動,angular觸發時進入臟值檢測。但只限 指定的事件 (如:用戶點擊,輸入操作,ajax請求,setInterval,setTimeout等...),否則需手動調用 apply 函數去強制執行一次臟檢查。

數據劫持 : vue.js 則是採用數據劫持結合發布者-訂閱者模式的方式,通過 Object.defineProperty() 來劫持各個屬性的 setter , getter 在數據變動時發布消息給訂閱者,觸發相應的監聽回調,而產生更新數據和視圖。

原理圖告訴我們,data屬性定義了getter、setter對屬性進行劫持,當屬性值改變是就會notify通知watch對象,而watch對象則會重新觸發組件呈現功能,繼而更新view上的DOM節點樹。
反之,view上輸入數據時,也會觸發data變更,也會觸發訂閱者watch更新,這樣子model數據就可以實時更新view上的數據變化。這樣一個過程就是vue的數據雙向綁定了。

vue是通過數據劫持的方式來做數據綁定的,其中最核心的方法便是通過 Object.defineProperty() 來實現對屬性的劫持,達到監聽數據變動的目的。

Object.defineProperty 是ES5一個方法,可以直接在一個對象上定義一個新屬性,或者修改一個已經存在的屬性,並返回這個對象,對象里目前存在的屬性描述符有兩種主要形式: 數據描述符 存取描述符
數據描述符 是一個擁有可寫或不可寫值的屬性。
存取描述符 是由一對getter-setter函數功能來描述的屬性。
描述符必須是兩種形式之一;不能同時是兩者。即:有值和可寫,或者可get和set
屬性描述符包括:

我們已經知道怎麼實現數據的雙向綁定,首先要對數據進行劫持監聽,所以我們需要設置一個監聽器 Observer ,用來監聽所有屬性。如果屬性發上變化了,就需要告訴訂閱者 Watcher 看是否需要更新。因為訂閱者是有很多個,所以我們需要有一個消息訂閱器 Dep 來專門收集這些訂閱者,然後在監聽器 Observer 和訂閱者 Watcher 之間進行統一管理的。接著,我們還需要有一個指令解析器 Compile ,對每個節點元素進行掃描和解析,將相關指令對應初始化成一個訂閱者 Watcher ,並替換模板數據或者綁定相應的函數,此時當訂閱者 Watcher 接收到相應屬性的變化,就會執行對應的更新函數,從而更新視圖。
因此接下去我們執行以下4個步驟,實現數據的雙向綁定:

深入響應式原理
剖析Vue原理&實現雙向綁定MVVM
《響應式系統的基本原理》.js
JavaScript實現MVVM之我就是想監測一個普通對象的變化

10. js數據劫持的兩個api

方法一:Object.defineProperty(target, key, desc)(vue2使用)
target: 目標對象
key: 將要操作的對象中的屬性或名稱
desc: 對象的描述
Object.defineProperty()用來訪問一個對象的設置,允許精確地添加或修改對象的屬性
劫持即是通過Object.defineProperty()對對象屬性的set和get操作與檢測
例子:

方法二:Proxy(target, handler)(vue3使用)
target: 目標對象
handler: 對象處理器
相比Object.defineProperty(),速度更快,更重要的是,vue3因為它可以響應數組變化了

閱讀全文

與什麼是js數據劫持相關的資料

熱點內容
宏基筆記本怎麼樣關閉程序 瀏覽:522
邯鄲有哪些鐵板市場 瀏覽:850
問道如何查詢賬號信息 瀏覽:323
工商銀行交易4204是什麼意思 瀏覽:454
食品產品標准號怎麼解讀 瀏覽:536
我愛我家鏈家為什麼退出北京市場 瀏覽:648
男生如何縮小臉部毛孔產品 瀏覽:199
數據線方頭卡扣怎麼卸 瀏覽:668
宮頸代理怎麼做 瀏覽:815
想做食品代理商怎麼樣 瀏覽:366
農資加盟店需多少錢代理商 瀏覽:492
信息驗證碼如何設置 瀏覽:296
設計時必要准備的數據有哪些 瀏覽:886
採取的程序是有什麼優勢 瀏覽:115
偽中幣交易網站有哪些 瀏覽:870
代理記賬專家多少錢 瀏覽:529
怎麼在淘寶上產品鏈接 瀏覽:967
電工技術為什麼要講參考方向 瀏覽:842
如何清理網路有害信息 瀏覽:267
微信全國用戶一天有多少數據量 瀏覽:334