文章寫於 2016 年,舊的博客不維護了,一些文章直接遷移到這邊來。如今看當時本身仍是很青澀的哈哈,無論是文筆仍是前端。文章的第二篇,記得應該是阿里的二面javascript
嗯…面試三次,每一個面試官都會問我這個問題,這裏仍是貼一下參考的文章吧:
Angular沉思錄(一) 數據的雙向綁定
AngularJS 數據雙向綁定揭祕
簡易實現版本:html
var Scope = function () {
this.$$watchers = [];
}
Scope.prototype.$watch = function( watchExp, listener ) {
this.$$watchers.push( {
watchExp: watchExp,
listener: listener || function () {}
});
};
Scope.prototype.$digest = function() {
var dirty;
do {
dirty = false;
for (var i = this.$$watchers.length - 1; i >= 0; i--) {
var newValue = this.$$watchers[i].watchExp(),
oldValue = this.$$watchers[i].last;
if( oldValue !== newValue) {
this.$$watchers[i].listener(newValue, oldValue);
dirty = true;
this.$$watchers[i].last = newValue;
}
};
} while(dirty);
};
var $scope = new Scope();
$scope.name = 'Ryan';
$scope.$watch(function () {
return $scope.name;
}, function ( newValue, oldValue ) {
console.log('Input Value has update:' + newValue + ' and Old Value is: ' + oldValue);
element[0].value = newValue;
tips.innerHTML = newValue
});
/** 視圖到模型 **/
var element = document.querySelectorAll('input'),
tips = document.querySelectorAll('#tips')[0];
element[0].addEventListener('keyup', function () {
$scope.name = element[0].value;
$scope.$digest();
})
/** 模型到視圖 **/
var updateScopeValue = function () {
$scope.name = 'Bob';
$scope.$digest();
}
var btn = document.getElementsByTagName('button')[0];
btn.addEventListener('click', function () {
updateScopeValue();
})
複製代碼
jQuery: 歷史悠久,對PC端友好,體積相對於Zepto過大,但有豐富的插件支持和社區支持
Zepto: 專門爲移動端定製,好比tap事件,體積小,一些功能沒有jQuery那麼完善,不支持鏈式調用,不支持高級選擇器(能夠用原生選擇器再包裝),插件比較少,和jQuery不兼容前端
貼一篇文章: zepto和jquery的區別,zepto的不一樣使用8條小結 啊,屬性選擇器是支持的=.= 以前一直覺得不支持:java
Zepto 的選擇器表達式: [name=value] 中value 必須用 雙引號 「 or 單引號 ‘ 括起來 例如執行:(‘[data-userid=」123123123]」‘) or $(「[data-userid=’123123123’]」)jquery
以爲其餘比較明顯的不一樣是:web
感受本身運氣真好..面試前有比較仔細的看了這部分.看的是紅色的那本JavaScript高級程序設計,講的很明白很透徹:面試
從頁面中接受事件的順序 IE:事件冒泡 Netscape:事件捕獲 DOM事件流: 捕獲階段,處於目標階段,事件冒泡階段(高版本瀏覽器會在捕獲階段觸發事件)數組
面試的時候想到了函數綁定bind.面試官讓我寫出來=.=啊當時就比較慌了.想了一下,以爲仍是說本身會的就好,就說了用apply或者call來實現.後面翻了一下書也確實是這麼寫的:瀏覽器
function bind(fn, context) {
return function () {
return fn.apply(context, arguments);
};
}
複製代碼
函數綁定要建立一個函數,能夠在特定的this環境中以指定參數調用另外一個函數.該技巧經常和回調函數與事件處理程序一塊兒使用,以便在將函數做爲變量傳遞的同事保留代碼執行環境安全
var handler = {
message: "Event handled",
handleClick: function (event) {
alert(this.message);
}
};
var btn = document.getElementById('my-btn');
EventUtil.addHandler(btn, "click", bind(handler.handleClick, handler));
//Event handled
//ES5:
EventUtil.addHandler(btn, "click", handler.handleClick.bind(handler));
複製代碼
只要是將某個函數指針以值的形式進行傳遞,同時該函數必須在特定環境中執行,就須要這個綁定函數.
這個以前沒想過,可是有看到一篇文章說這個. 感受是會維護一個數組,數組保存着全部用戶本身定義的事件,而後克隆的時候直接遍歷這個數組綁定事件/移除事件.讓事件執行順序相同就根據瀏覽器(IE),逆序綁定事件達到全部事件執行順序都相同. 說是這麼說,也不知道是否是真的這麼幹,明天查查資料.斷網啦睡覺啦.~~
這個真不瞭解=.= 下面摘抄自<<深刻淺出Nodejs>>
在Node中,除了JavaScript是單線程外,Node自身實際上是多線程的,只是I/O線程使用的CPU較少.另外一個須要重視的觀點是,除了用戶代碼沒法並行執行外,全部的I/O(磁盤I/0和網絡I/O)則是能夠並行起來的.
Node的執行模型包括:事件循環,觀察者,請求對象,I/O線程池
JavaScript的代碼經過調用C++核心模塊進行下層的操做.
從JavaScript調用Node的核心模塊,核心模塊調用C++內建模塊,內建模塊經過libuv進行系統調用;libuv有兩個平臺的實現,實際上調用uv_fs_open()方法;
在uv_fs_open()調用過程當中,建立了一個FSReqWrap請求對象,JS層傳入的參數和方法都封裝在這個請求對象中,回調函數是oncomplete_sym: req_wrap->object_->Set(oncomplete_sym, callback); 包裝完畢後,Windows下調用QueueUserWorkItem()將這個FSReqWrap對象推入線程池中等待執行.
至此,由JavaScript層面發起的異步調用第一階段就此結束.JavaScript線程能夠繼續執行當前任務的後續操做,I/O操做就在線程池中等待執行.達到異步的目的.
執行回調:線程池中的IO操做調用完畢後,經過PostQueuedCompletionStatus()通知IOCP(IO完成端口),提交執行狀態,並將線程歸還線程池.
這個過程當中,事件循環的IO觀察者都會檢查線程池中是否有執行完的請求,若是存在,將請求對象加入隊列,做爲事件處理.
IO觀察者的回調函數就是取出請求對象的result屬性做爲參數,oncomplete_sym做爲方法,調用執行.達到調用JavaScript中傳入的回調函數的目的.
有張圖好想貼上來!!就在書上~~ 看多幾遍大概瞭解這個工做流程了.