如下問題解釋非本人原創,是根據面試經驗整理後以爲更容易理解的解釋版本,歡迎補充。javascript
計算機網絡體系結構html
應用層(HTTP、SMTP、FTP、POP3)前端
運輸層(TCP、UDP)vue
網絡層(IP(路由器))java
數據鏈路層(網橋(CSMA/CD、PPP))node
物理層(集線器)react
這一步包括 DNS 具體的查找過程,包括:瀏覽器緩存->系統緩存->路由器緩存...
(1) 瀏覽器搜索本身的 DNS 緩存(維護一張域名與 IP 地址的對應表);
(2) 搜索操做系統中的 DNS 緩存(維護一張域名與 IP 地址的對應表);
(3) 搜索操做系統的 hosts 文件( Windows 環境下,維護一張域名與 IP 地址的對應表);
(4) 操做系統將域名發送至 LDNS(本地區域名服務器),LDNS 查詢 本身的 DNS 緩存(通常查找成功率在 80% 左右),查找成功則返回結果,失敗則發起一個迭代 DNS 解析請求:git
① LDNS 向 Root Name Server (根域名服務器,如 com、net、org等的解析的頂級域名服務器的地址)發起請求,此處,Root Name Server 返回 com 域的頂級域名服務器的地址;es6
② LDNS 向 com 域的頂級域名服務器發起請求,返回 baidu.com 域名服務器地址;
③ LDNS 向 baidu.com 域名服務器發起請求,獲得 www.baidu.com 的 IP 地址;
(5) LDNS 將獲得的 IP 地址返回給操做系統,同時本身也將 IP 地址緩存起來;
(6) 操做系統將 IP 地址返回給瀏覽器,同時本身也將 IP 地址緩存起來;
(1) 主機向服務器發送一個創建鏈接的請求;
(2) 服務器接到請求後發送贊成鏈接的信號;
(3) 主機接到贊成鏈接的信號後,再次向服務器發送了確認信號 ;
注意:這裏的三次握手中主機兩次向服務器發送確認,第二次是爲了防止已失效的鏈接請求報文段傳至服務器致使錯誤。
(1) 瀏覽器根據 URL 內容生成 HTTP 請求,請求中包含請求文件的位置、請求文件的方式等等;
(2) 服務器接到請求後,會根據 HTTP 請求中的內容來決定如何獲取相應的 HTML 文件;
(3) 服務器將獲得的 HTML 文件發送給瀏覽器;
(4) 在瀏覽器尚未徹底接收 HTML 文件時便開始渲染、顯示網頁;
(5) 在執行 HTML 中代碼時,根據須要,瀏覽器會繼續請求圖片、音頻、視頻、CSS、JS等文件,過程同請求 HTML ;
瀏覽器渲染展現網頁過程
HTML代碼轉化爲DOM(DOM Tree)
CSS代碼轉化成CSSOM(CSS Object Model)
結合DOM和CSSOM,生成一棵渲染樹(包含每一個節點的視覺信息)(Render Tree)
生成佈局(layout),即將全部渲染樹的全部節點進行平面合成
將佈局繪製(paint)在屏幕上
(1) 主機向服務器發送一個斷開鏈接的請求;
(2) 服務器接到請求後發送確認收到請求的信號;(此時服務器可能還有數據要發送至主機)
(3) 服務器向主機發送斷開通知;(此時服務器確認沒有要向主機發送的數據)
(4) 主機接到斷開通知後斷開鏈接並反饋一個確認信號,服務器收到確認信號後斷開鏈接;
注意:這裏的四次揮手中服務器兩次向主機發送消息,第一次是回覆主機已收到斷開的請求,第二次是向主機確認是否斷開,確保數據傳輸完畢。
三次握手 && 四次揮手
發現這方面的資料不多啊,都沒有相中的比較好理解的。
前端模塊化
React.js 只是一個視圖庫
(1)聲明式設計
(2)高效:經過對DOM的模擬,最大限度的減小與DOM的交互。
(3)靈活:能夠與已知的框架或庫很好的配合。
(4)JSX:是js語法的擴展,不必定使用,但建議用。
(5)組件:構建組件,使代碼更容易獲得複用,可以很好地應用在大項目的開發中。
(6)單向響應的數據流:React實現了單向響應的數據流,從而減小了重複代碼,這也是解釋了它爲何比傳統數據綁定更簡單。
react 經過prop管理組件通訊,經過state 驅動視圖比較差別進行更新操做
做者:第七頁
連接:https://www.zhihu.com/question/39825457/answer/83544390
來源:知乎
著做權歸做者全部,轉載請聯繫做者得到受權。*angular 是MV 框架, react是用來構建可重複使用的UI組件的, 能夠當作是個提供工具的library。
react 能夠和 angular 的 directive作比較。 這樣比較的話, react是比angular directive 在組建UI上更powerful的。**做者:空空
連接:https://www.zhihu.com/question/23444167/answer/24957302
來源:知乎
著做權歸做者全部,轉載請聯繫做者得到受權。
請問 React 和 Angular 各有什麼優缺點,各自又適合什麼開發場景?
唉,這個真的太難總結了,求評論!!!
Vue擁有相似 Angular 的雙向數據綁定,以及相似 React 的虛擬DOM。
<div class="image-package">
angular && vue && react
Vue.js 很好,但會比 Angular 或 React 更好嗎?
淺析angular,react,vue.js jQuery使用區別
*
每次被問到這個我只能想起less中的定義變量,用過久less都忘了css不能嵌套,醉了醉了。
變量
混合(Mixins)
嵌套規則
運算
函數
命名空間
做用域
註釋
導入(Import)
本質上,less 包含一套自定義的語法及一個解析器,用戶根據這些語法定義本身的樣式規則,這些規則最終會經過解析器,less 把這些樣式規則編譯成瀏覽器能夠識別的 css 樣式。less 並無裁剪 css 原有的特性,更不是用來取代 css 的,而是在現有 css 語法的基礎上,爲 css 加入程序式語言的特性。less 最終須要編譯成 css 文件才能起到樣式的效果,咱們能夠稱 less 爲 css 樣式生成工具。
使用 gulp.js,你的構建腳本是代碼,而不是配置文件;
使用標準庫(node.js standard library)來編寫腳本;
插件都很簡單,只負責完成一件事-基本上都是 20 行左右的函數;
任務都以最大的併發數來執行;
Gulp是一個基於流的構建系統,使用代碼優於配置的策略。輸入/輸出(I/O)是基於「流式」的。
Sass、Less編譯
Css Js 圖片壓縮
Css Js 合併
Css Js 內聯
Html的include功能
Autoprefixer(自動處理瀏覽器css前綴)
自動刷新
去緩存
Handlebars模板文件的預編譯
雪碧圖
ESLint
rem移動端適配方案
gulp | grunt | |
---|---|---|
速度 | 快 | 慢 |
格式 | 和node差很少 | json套json |
操做基於 | 二進制流 | 文件 |
模塊化 && 構建
dist是指distribution——分配,分發——發佈完成的文件夾通常命名dist。
dest則是destination——目的地,終點——用於grunt文件路徑相關的配置項,通常會和src配對出現。好比文件壓縮插件:壓縮源(src)文件,生成壓縮包到(dest)。
做者:峯子
連接:https://www.zhihu.com/question/29199796/answer/82862432
來源:知乎
著做權歸做者全部,轉載請聯繫做者得到受權。
GruntFile.js
<script> module.exports = function(grunt) { // 導入模塊 grunt.loadNpmTasks('grunt-contrib-uglify'); grunt.loadNpmTasks('grunt-contrib-cssmin'); grunt.loadNpmTasks('grunt-contrib-htmlmin'); grunt.loadNpmTasks('grunt-contrib-imagemin'); grunt.loadNpmTasks('grunt-contrib-watch'); // 配置任務 grunt.initConfig({ // js壓縮 默認加密壓縮 uglify: { // 主任務名稱 options: { // [配置選項] mangle: false // 是否加密壓縮 }, a: { // 子任務名稱 expand: true, // 是否分開壓縮 src: 'js/*.js', // 源文件 dest: 'build' // 目標文件 自動建立源文件文件夾 } }, cssmin: { a: { expand: true, src: 'css/*.css', dest: 'build' } }, htmlmin: { options: { removeComments: true, // 是否移除註釋 collapseWhitespace: false // 是否去掉空白 }, a: { src: '*.html', dest: 'build' } }, // imagemin: { // a: { // expand: true, //分開執行 // cwd: 'images', // src: ['**/*.{png,jpg}'], // dest: 'build/images' // } // }, watch: { a: { files: ['*.html', 'css/*.css', 'js/*.js'], tasks: ['cssmin', 'htmlmin', 'uglify'] } } }); // 註冊一個默認任務 grunt.registerTask('default', ['uglify', 'cssmin', 'htmlmin', 'watch']); } </script>
gulpfile.js
<script> // 導入模塊 var gulp = require('gulp'); var cssmin = require('gulp-cssmin'); var uglify = require('gulp-uglify'); var htmlmin = require('gulp-htmlmin'); var concat = require('gulp-concat'); var rename = require('gulp-rename'); // 更名 // 配置任務 gulp.task('uglify:css', function() { gulp.src('css/*.css') .pipe(cssmin()) // 壓縮 .pipe(concat('all.min.css')) // 合併 .pipe(gulp.dest('build/css')) // 輸出 }); gulp.task('uglify:js', function() { gulp.src('js/*.js') .pipe(uglify()) // 壓縮 .pipe(gulp.dest('build/js')) // 輸出 }); gulp.task('uglify:html', function() { gulp.src('*.html') .pipe(htmlmin({ // 壓縮 collapseWhitespace: true, removeComments: true })) .pipe(gulp.dest('build')) // 輸出 }); gulp.watch('*.*', ['uglify:css', 'uglify:js', 'uglify:html']); gulp.task('default', ['uglify:css', 'uglify:js', 'uglify:html']); </script>
<script> var gulp = require('gulp'); var uglify = require('gulp-uglify'); var clean = require('gulp-clean-css'); var sass = require('gulp-sass'); gulp.task('uglify',function(){ return( gulp.src('./src/*.js') .pipe(uglify()) .pipe(gulp.dest('dist')) ) }) gulp.task('minify-css',function(){ return ( gulp.src('./src/*.css') .pipe(clean()) .pipe(gulp.dest('dist')) ) }) gulp.task('compile-sass',function(){ return ( gulp.src('./src/*.scss') .pipe(sass().on('error', sass.logError)) .pipe(gulp.dest('dist')) ) }) gulp.task('default',function(){ gulp.watch('./src/*.js',['uglify']); gulp.watch('./src/*.css',['minify-css']); gulp.watch('./src/*.scss',['compile-sass']); }) </script>
*
在舊的交互方式中,由用戶觸發一個HTTP請求到服務器,服務器對其進行處理後再返回一個新的HTHL頁到客戶端, 每當服務器處理客戶端提交的請求時,客戶都只能空閒等待,而且哪怕只是一次很小的交互、只需從服務器端獲得很簡單的一個數據,都要返回一個完整的HTML頁,而用戶每次都要浪費時間和帶寬去從新讀取整個頁面。而使用Ajax後用戶從感受上幾乎全部的操做都會很快響應沒有頁面重載(白屏)的等待。
Ajax的原理簡單來講是在用戶和服務器之間加了—箇中間層(AJAX引擎),經過XmlHttpRequest對象來向服務器發異步請求,從服務器得到數據,而後用javascript來操做DOM而更新頁面。使用戶操做與服務器響應異步化。這其中最關鍵的一步就是從服務器得到請求數據。
Ajax的過程只涉及JavaScript、XMLHttpRequest和DOM。XMLHttpRequest是ajax的核心機制,它是在IE5中首先引入的,是一種支持異步請求的技術。簡單的說,也就是javascript能夠及時向服務器提出請求和處理響應,而不阻塞用戶。達到無刷新的效果。
得到ajax
打開地址
發送數據
接收數據
<script> // 1.得到ajax if (window.XMLHttpRequest) { //查看當前瀏覽器XMLHttpRequest是不是全局變量 var oAjax = new XMLHttpResquest(); } else { var oAjax = new ActiveXObject('Microsoft.XMLHTTP'); //IE6,傳入微軟參數 } // 2.打開地址 switch (json.type.toLowerCase()) { case 'get': oAjax.open('GET', json.url + '?' + jsonToURL(json.data), true); // 提交方式(大寫),url,是否異步 oAjax.send(); // 3.發送數據 break; case 'post': oAjax.open('POST', json.url, true); oAjax.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); oAjax.send(jsonToURL(json.data)); // 3.發送數據 break; } // 4.接收數據 oAjax.onreadystatechange = function() { //監控狀態 if (oAjax.readyState == 4) { json.complete && json.complete(); if (oAjax.status >= 200 && oAjax.status < 300 || oAjax.status == 304) { json.success && json.success(oAjax.responseText); //執行成功的回調函數, responseText爲響應內容 } else { json.error && json.error(oAjax.status); //執行失敗的回調函數 } } }; </script>
*
哈哈,這個後面會寫一整篇,敬請期待!
我猜這道面試題應該也不讓用 lessc ,哈哈哈!
依舊求評論,我只會lessc和構建轉化誒。
甩上gulp構建轉化
<script> var gulp = require('gulp'), less = require('gulp-less'); gulp.task('testLess', function() { gulp.src(['src/less/index.less', 'src/less/detail.less']) //多個文件以數組形式傳入 .pipe(less()) .pipe(gulp.dest('src/css')); //將會在src/css下生成index.css以及detail.css }); gulp.task('testWatch', function() { gulp.watch('src/**/*.less', ['testLess']); //當全部less文件發生改變時,調用testLess任務 }); </script>
這個後面也有一篇簡單的算法篇,敬請期待!
冒泡排序
每次比較相鄰的兩個數,若是後一個比前一個小,換位置。 時間複雜度:O(n^2)
<script> var arr = [3, 1, 4, 6, 5, 7, 2]; function bubbleSort(arr) { var len = arr.length; for (var i = len; i >= 2; --i) { for (var j = 0; j < i - 1; j++) { if (arr[j + 1] < arr[j]) { var temp; temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } } return arr; } function bubbleSort2(arr) { var len = arr.length; for (var i = 0; i <= len - 1; i++) { for (var j = 0; j <= len - i; j++) { if (arr[j + 1] < arr[j]) { var temp; temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } } return arr; } console.log(bubbleSort(arr)); console.log(bubbleSort2(arr)); </script>
快速排序
採用二分法,取出中間數,數組每次和中間數比較,小的放到左邊,大的放到右邊。 時間複雜度:O(nlog2(n))
<script> var arr = [3, 1, 4, 6, 5, 7, 2]; function quickSort(arr) { if(arr.length == 0) { return []; // 返回空數組 } var cIndex = Math.floor(arr.length / 2); var c = arr.splice(cIndex, 1); var l = []; var r = []; for (var i = 0; i < arr.length; i++) { if(arr[i] < c) { l.push(arr[i]); } else { r.push(arr[i]); } } return quickSort(l).concat(c, quickSort(r)); } console.log(quickSort(arr)); </script>
Promise對象有如下兩個特色。
對象的狀態不受外界影響。Promise對象表明一個異步操做,有三種狀態:Pending
(進行中)、Resolved
(已完成,又稱 Fulfilled)和Rejected
(已失敗)。只有異步操做的結果,能夠決定當前是哪種狀態,任何其餘操做都沒法改變這個狀態。這也是Promise這個名字的由來,它的英語意思就是「承諾」,表示其餘手段沒法改變。
一旦狀態改變,就不會再變,任什麼時候候均可以獲得這個結果。Promise對象的狀態改變,只有兩種可能:從Pending
變爲Resolved
和從Pending
變爲Rejected
。只要這兩種狀況發生,狀態就凝固了,不會再變了,會一直保持這個結果。就算改變已經發生了,你再對Promise對象添加回調函數,也會當即獲得這個結果。這與事件(Event)徹底不一樣,事件的特色是,若是你錯過了它,再去監聽,是得不到結果的。
詳見性能優化篇!
冒泡型事件:事件按照從最特定的事件目標到最不特定的事件目標(document對象)的順序觸發。
捕獲型事件(event capturing):事件從最不精確的對象(document 對象)開始觸發,而後到最精確(也能夠在窗口級別捕獲事件,不過必須由開發人員特別指定)。
DOM事件流:同時支持兩種事件模型:捕獲型事件和冒泡型事件,可是,捕獲型事件先發生。兩種事件流會觸及DOM中的全部對象,從document對象開始,也在document對象結束。
DOM事件模型最獨特的性質是,文本節點也觸發事件(在IE中不會)。
示例
假設一個元素div,它有一個下級元素p。
<div> <p>元素</p> </div>
這兩個元素都綁定了click事件,若是用戶點擊了p:
事件捕獲
當你使用事件捕獲時,**父級元素先觸發**,子級元素後觸發,即div先觸發,p後觸發。
事件冒泡
當你使用事件冒泡時,**子級元素先觸發**,父級元素後觸發,即p先觸發,div後觸發。
addEventListener函數,它有三個參數,第三個參數如果true,則表示採用事件捕獲,如果false,則表示採用事件冒泡。
IE只支持事件冒泡,不支持事件捕獲。
Paste_Image.png
• 在W3c中,使用stopPropagation()
方法
• 在IE下設置oEvent.cancelBubble = true
;
在捕獲的過程當中stopPropagation()後,後面的冒泡過程也不會發生了。
阻止事件的默認行爲,例如click <a>
後的跳轉
• 在W3c中,使用oEvent.preventDefault()
方法;
• 在IE下設置window.event.returnValue = false;
<script> var arr=[1,2,3,4]; var arr2=[]; while(arr.length) { var num=arr.pop(); arr2.push(num); } alert(arr2); </script>
數組更多應用詳見:天天10個前端知識點:數組應用篇
面向對象分爲基於原型的面向對象和基於模板的面向對象。
Java:基於模板的面向對象。
class A { private String name; public void fun(){ } } A a = new A(); a.fun();
JavaScript:基於原型的面向對象,基於事件的網頁腳本語言。
<script> function CreateObject() { } CreateObject.prototype = { constructor: CreateObject, // 可特地聲明constructor指向 CreateObject name: 'xxx', age: '11', children: ['aaa', 'bbb'], getName: function() { return this.name; } } var p = new CreateObject(); console.log(p.name); // 'xxx' </script>
JavaScript中Element與Node的區別,children與childNodes的區別
Element繼承了Node類,也就是說Element是Node多種類型中的一種。
children是Element的屬性,childNodes是Node的屬性
NODE是相對TREE這種數據結構而言的。TREE就是由NODE組成。
node有幾個**子類型**:**Element**,Text,,Attribute,RootElement,Comment,Namespace等。
ELEMENT則是HTML裏的概念,是元素即標籤包含內部屬性及內容的整體,是HTML中的數據的組成部分之一。
*
git是分佈式的,svn不是。
git跟svn同樣有本身的集中式版本庫或服務器。但git更傾向於被使用於分佈式模式,克隆版本庫後即便沒有網絡也可以commit文件,查看歷史版本記錄,建立項目分支等,等網絡再次鏈接上Push到服務器端。
git把內容按元數據方式存儲,而svn是按文件。
全部的資源控制系統都是把文件的元信息隱藏在一個相似.svn,.cvs等的文件夾裏。 git目錄是處於你的機器上的一個克隆版的版本庫,它擁有中心版本庫上全部的東西,例如標籤,分支,版本記錄等。
git沒有一個全局的版本號,svn有。
git的內容完整性優於svn。
由於git的內容存儲使用的是SHA-1哈希算法。
git能夠有無限個版本庫,svn只能有一個指定中央版本庫。
當svn中央版本庫有問題時,全部工做成員都一塊兒癱瘓直到版本庫維修完畢或者新的版本庫設立完成。 每個git都是一個版本庫,區別是它們是否擁有活躍目錄(Git Working Tree)。若是主要版本庫(例如:置於GitHub的版本庫)有問題,工做成員仍然能夠在本身的本地版本庫(local repository)提交,等待主要版本庫恢復便可。工做成員也能夠提交到其餘的版本庫!
這是一道筆試題,小白就是小白啊,還第一次見到定時器的第三個參數,仍是這麼寫的。
↑ 上面這篇文章值得耐心細看,對理解定時器有很大幫助。
首先咱們要了解以前提到的定時器,setTimeout(fn, 0)
輸出時間並不爲0且大於0。
這是由於 JavaScript是單線程執行的。也就是說,在任什麼時候間點,有且只有一個線程在運行JavaScript程序,沒法同一時候運行多段代碼。
瀏覽器的內核是多線程的,它們在內核控制下相互配合以保持同步,一個瀏覽器至少實現三個常駐線程:JavaScript引擎線程,GUI渲染線程,瀏覽器事件觸發線程。
JavaScript引擎是基於事件驅動單線程執行的,JavaScript引擎一直等待着任務隊列中任務的到來,而後加以處理,瀏覽器不管何時都只有一個JavaScript線程在運行JavaScript程序。
GUI渲染線程負責渲染瀏覽器界面,當界面須要重繪(Repaint)或因爲某種操做引起迴流(Reflow)時,該線程就會執行。但須要注意,GUI渲染線程與JavaScript引擎是互斥的,當JavaScript引擎執行時GUI線程會被掛起,GUI更新會被保存在一個隊列中等到JavaScript引擎空閒時當即被執行。
事件觸發線程,當一個事件被觸發時,該線程會把事件添加到待處理隊列的隊尾,等待JavaScript引擎的處理。這些事件可來自JavaScript引擎當前執行的代碼塊如setTimeout、也可來自瀏覽器內核的其餘線程如鼠標點擊、Ajax異步請求等,但因爲JavaScript的單線程關係,全部這些事件都得排隊等待JavaScript引擎處理(當線程中沒有執行任何同步代碼的前提下才會執行異步代碼)。
如下爲此次碰見的題目
廣義上咱們遇到定時器的題目通常是這樣的
<script> for (var i = 1; i < 4; i++) { var t = setTimeout(function() { console.log(i); // 2\. 輸出三次4 }, 10); } console.log(i); // 1\. 4 </script>
此次碰見的是這樣的:
循環只進行兩次
<script> for (var i = 1; i < 4; i++) { var t = setTimeout(function(i) { console.log(i); // 2\. 1 4.2 console.log(t); // 3\. 3 5.3 clearTimeout(t); }, 10, i); } console.log(i); // 1\. 4 </script>
關於定時器.png
幾個讓我印象深入的面試題(一) | Jay Zangwill
請注意:這個t是定義在閉包外面的,也就是說t並無被閉包保存,因此這裏的t指的是最後一個循環留下來的t,因此最後一個3被清除了,沒有輸出。
setTimeout能夠傳入第三個參數、第四個參數...,用來表示第一個參數(回調函數)傳入的參數。
因而我檢測瞭如下變形
循環只進行兩次
<script> for (var i = 1; i < 4; i++) { var t = setTimeout(function(i) { console.log(i); // 2\. 2 4\. 2 console.log(t); // 3\. 3 5\. 3 clearTimeout(t); }, 10, 2); } console.log(i); // 1\. 4 </script>
循環只進行兩次
<script> for (var i = 1; i < 4; i++) { var t = setTimeout(function(i, t) { console.log(i); // 2\. 2 4\. 2 console.log(t); // 3\. 3 5\. 3 clearTimeout(t); }, 10, 2, 3); // 當t傳入 2 / 3 時都是隻進行兩次循環 } console.log(i); // 1\. 4 </script>
t爲非 2 / 3 時,循環輸出3次
<script> for (var i = 1; i < 4; i++) { var t = setTimeout(function(i, t) { console.log(i); // 2\. 2 4\. 2 6\. 2 console.log(t); // 3\. 4 5\. 4 7\. 4 clearTimeout(t); }, 10, 2, 4); } console.log(i); // 1\. 4 </script>
<script> for (var i = 1; i < 4; i++) { var t = setTimeout(function(i, t) { console.log(i); // 2\. 1 4\. 2 6\. 3 console.log(t); // 3\. undefined 5\. 1 7\. 2 clearTimeout(t); }, 10, i, t); } console.log(i); // 1\. 4 </script>
<script> for (var i = 0; i < 4; i++) { var t = setInterval(function() { console.log(i); // 2\. 一直輸出4 }, 10); } console.log(i); // 1\. 4 </script>
此次碰見的長這樣:
<script> for (var i = 0; i < 4; i++) { var t = setInterval(function(i, t) { console.log(i); // 2\. 0,1,2,3,3,3,... clearInterval(t); }, 10, i, t); } console.log(i); // 1\. 4 </script>
幾個讓我印象深入的面試題(一) | Jay Zangwill
第一次觸發回調函數執行的時候 t 的值是undefined,第二次觸發的時候有值了。這和程序的執行順序有關。咱們知道js正常狀況下是從上到下,從右到左執行的。
因此這裏每次循環先設置定時器,而後把定時器的返回值賦值給t。在第一次循環的時候t並無被賦值,因此是undefined,在第二次循環的時候,定時器其實清理的是上一個循環的定時器。因此致使每次循環都是清理上一次的定時器,而最後一次循環的定時器沒被清理,致使一直輸出3。
因而我作了如下測試
<script> for (var i = 1; i < 4; i++) { var t = setInterval(function(i, t) { console.log(i); // 2\. 2 4\. 2 6\. 2... console.log(t); // 3\. 3 5\. 3 7\. 3... clearInterval(t); }, 10, 2, 3); } console.log(i); // 1\. 4 </script>
<script> for (var i = 0; i < 4; i++) { var t = setInterval(function(i, t) { console.log(i); // 2\. 0 4\. 1 6\. 2 8\. 3 10\. 3... console.log(t); // 3\. undefined 5\. 1 7\. 2 9\. 3 11\. 3... clearInterval(t); }, 10, i, t); } console.log(i); // 1\. 4 </script>
轉載:http://www.jianshu.com/p/3944...
我的建了前端學習羣,旨在一塊兒學習前端。純淨、純粹技術討論,非前端人員勿擾!入羣加我微信:iamaixiaoxiao。