23. 監聽輸入:javascript
1. oninput > onchange: onchange在離焦事件是觸發。不如input靈敏 ( IE9+ )css
2. 中文輸入時(即非直接輸入),input獲取的值不正確,需加判斷。( IE9+ )html
compositionstart:當瀏覽器有非直接的文字輸入時, compositionstart事件會以同步模式觸發.vue
compositionEnd: 當瀏覽器是直接的文字輸入時, compositionend會以同步模式觸發.html5
var cpLock = false; input.addEventListener('compositionstart', function(){ cpLock = true; }) input.addEventListener('compositionend', function(){ cpLock = false; }) input.addEventListener('input', function(){ if(!cpLock)console.log(this.value); });
3. 須要兼容IE9一下的,只能使用keyPress,keyDown等事件,判斷keyCodejava
(參考作法:http://jyren-rachel.iteye.com/blog/1886275)react
24. 遞歸中的性能:es6
遞歸是處遍歷外最經常使用的循環方法。鑑於其性能問題,通常能用while,for等循環的儘可能不用遞歸。 若必須用遞歸方法,通常把遞歸中的執行代碼放入setTimeout方法中,以免棧溢出(setTimeout老是在下一次的tick中執行)。web
setInterval的不靠譜:當每次執行的時間小於循環時間時,不會出現異常;而當代碼執行時間較長,超出循環時間時,下一次的循環將被延後,這樣每次的循環間隔將不統一,且任務會堆積在隊列中。gulp
更詳細的介紹https://www.cnblogs.com/simonbaker/p/5707270.html
25. es6屬性:
1. let , const
let : a. 不存在變量提高, 必須先聲明 後使用。(會報錯 is not defined ;var 中則不報錯,返回值爲 undefined)
b. 存在塊做用域內,同域內不可重複聲明
c. 暫時性死區:一旦在做用域內聲明瞭次變量,若提早訪問會報錯,(即便外域也聲明瞭同名變量)
const : 與 let 特色相同,聲明時必須賦值,且不能更改賦值,如果對象保存的是對象的地址。
2. 結構賦值 : 等號右邊的值會賦予左邊的變量。
3. 模板字符串: ‘字符串’,按照字符串處理拼接。
a. 反引號爲特殊字符,使用的話需加 \ 轉義。
b. 花括號內能夠進行 js 運算
c. 空格、縮進都會被保留
`${1}+${2}` // '1+2'
4. rest參數 , 擴展運算符
rest : (. . .a) 做爲參數或者等號左邊變量 必須爲最後一個參數
擴展運算符: 至關於rest的逆運算, 展開一個數組或者對象
5.class 類,super方法:(阮一峯:https://m.imooc.com/article/20618)
注:react中通常寫法: super ( props );這樣寫的緣由是 在constructor 中可使用 this.props, props是實例化時傳入的參數。
(子類纔會有super方法,父類是沒有的);在子類的構造函數中,只有調用super以後,才能使用this關鍵字,不然會報錯,這是由於子類沒有本身的this對象,而是繼承父類的this對象,而後對其進行加工,若是不調用super方法,子類就得不到this對象;
若是子類沒有定義constructor方法,這個方法會默認添加,也就是說,無論有沒有顯式定義,任何一個子類都有constructor方法。
通過super調用父類的方法時,super會綁定子類的this。
super看成函數調用時,表明父類的構造函數;super做爲對象時,在普通方法中,指向父類的原型對象,在靜態方法中,指向父類
26. http1.0 和 http2.0:
http2增長了:
27. use strict 嚴格模式:(參考文章:https://blog.csdn.net/weixin_40387601/article/details/80514358)
js 以更嚴謹的方式運行。
28. 小程序實現vue類型的數據監聽:Object.defineProperty方法
/** * 設置監聽器 */ setWatcher(page) { let data = page.data; let watch = page.watch; Object.keys(watch).forEach(v => { let key = v.split('.'); // 將watch中的屬性以'.'切分紅數組 let nowData = data; // 將data賦值給nowData for (let i = 0; i < key.length - 1; i++) { // 遍歷key數組的元素,除了最後一個! nowData = nowData[key[i]]; // 將nowData指向它的key屬性對象 } let lastKey = key[key.length - 1]; // 假設key==='my.name',此時nowData===data['my']===data.my,lastKey==='name' let watchFun = watch[v].handler || watch[v]; // 兼容帶handler和不帶handler的兩種寫法 let deep = watch[v].deep; // 若未設置deep,則爲undefine this.observe(nowData, lastKey, watchFun, deep, page); // 監聽nowData對象的lastKey }) }, /** * 監聽屬性 並執行監聽函數 */ observe(obj, key, watchFun, deep, page) { var val = obj[key]; // 判斷deep是true 且 val不能爲空 且 typeof val==='object'(數組內數值變化也須要深度監聽) if (deep && val != null && typeof val === 'object') { Object.keys(val).forEach(childKey=>{ // 遍歷val對象下的每個key this.observe(val,childKey,watchFun,deep,page); // 遞歸調用監聽函數 }) } var that = this; Object.defineProperty(obj, key, { configurable: true, enumerable: true, set: function(value) { // 用page對象調用,改變函數內this指向,以便this.data訪問data內的屬性值 watchFun.call(page,value,val); // value是新值,val是舊值 val = value; if(deep){ // 如果深度監聽,從新監聽該對象,以便監聽其屬性。 that.observe(obj, key, watchFun, deep, page); } }, get: function() { return val; } }) } page中使用: //index.js Page({ data: { my: { name: 'xuyang', age: 21, hobby: ['girls', 'games'] }, nameInfo:{} }, onLoad() { getApp().setWatcher(this); this.data.my.hobby[0] = 'study'; this.setData({ nameInfo:{name:'haha',sex:'boy'} }) console.log(this.data) }, watch: { my:{ handler(newValue) { console.log(newValue); }, deep:true } } })
(轉載連接:https://blog.csdn.net/xuyangxinlei/article/details/81408200)
29. CSS 3 + HTML 5 (postcss-loader只是給 css 添加前綴,通gulp中的autoprefixer, 謹慎使用新屬性)
1.選擇器:
屬性:[att=val] 指定特定名字的元素
[att*=val] 匹配val*的元素,
[att^=val] 匹配val開頭的元素,好比id爲val一、val432432均可以。
[att$=val] 匹配val結尾的元素,好比id爲1213val、fdajlval等等。
順序:first-child:選擇第一個子元素
last-child:選擇最後一個子元素
nth-child:選擇第n個子元素,這個還能夠根據奇偶來制定,
nth-last-child:選擇倒數第n個子元素
only-child:單個子元素時,指定樣式
狀態: hover , active ,checked , selection, focus , enabled , disabled , read-only
2. 效果: border-radius , box-shadow , box-sizing , background屬性 , linear-gradient , radial-gradient
3.動畫:
1.關鍵幀動畫:animation: name duration timing-function delay count; @keyframes
2.2D效果屬性: tranform : translate 、rotate、scale ; transition
4. html5 :
1.語義化標籤: nav ,head ,footer , aside,article,section;
2. 拖拽: drag , drop
3. vedio 、audio、canvas
4.input 新類型: time , date , email , url , search ,calendar , datetime, week , month , color , tel ,number ,
5. websocket , localstorage
28.閉包:定義 , 效果:能夠獲去操做一個函數中的局部變量。缺點:消耗內存,一直保持父函數的引用。 優勢: 對局部變量保護做用,利於函數的 封裝。
29. CMD,AMD比較:
AMD(異步模塊定義):requirejs : 提早下載,提早執行
CMD(通用模塊定義):seajs :提早下載,延遲執行
RequireJS 和 SeaJS 都是很不錯的模塊加載器,二者區別以下:
1. 二者定位有差別。RequireJS 想成爲瀏覽器端的模塊加載器,同時也想成爲 Rhino / Node 等環境的模塊加載器。SeaJS 則專一於 Web 瀏覽器端,同時經過 Node 擴展的方式能夠很方便跑在 Node 服務器端
2. 二者遵循的標準有差別。RequireJS 遵循的是 AMD(異步模塊定義)規範,SeaJS 遵循的是 CMD (通用模塊定義)規範。規範的不一樣,致使了二者 API 的不一樣。SeaJS 更簡潔優雅,更貼近 CommonJS Modules/1.1 和 Node Modules 規範。
3. 二者社區理念有差別。RequireJS 在嘗試讓第三方類庫修改自身來支持 RequireJS,目前只有少數社區採納。SeaJS 不強推,而採用自主封裝的方式來「海納百川」,目前已有較成熟的封裝策略。
4. 二者代碼質量有差別。RequireJS 是沒有明顯的 bug,SeaJS 是明顯沒有 bug。
5. 二者對調試等的支持有差別。SeaJS 經過插件,能夠實現 Fiddler 中自動映射的功能,還能夠實現自動 combo 等功能,很是方便便捷。RequireJS 無這方面的支持。
6. 二者的插件機制有差別。RequireJS 採起的是在源碼中預留接口的形式,源碼中留有爲插件而寫的代碼。SeaJS 採起的插件機制則與 Node 的方式一致:開放自身,讓插件開發者可直接訪問或修改,從而很是靈活,能夠實現各類類型的插件。.
(來源文章:http://www.cnblogs.com/dojo-lzz/p/4707725.html)
30. arguments對象:函數的參數對象
特色:1. 不是數組,可是有數組的一些屬性,length,索引,變成數組的方法:[].slice.call(arguments)或Array.prototype.slice.call(arguments);
typeof arguments // obeject ; {}.tostring.call(arguments) // [object Arguments]
2. 實參中的值和arguments中的值保持一致。
3. length的值不會自動改變,必須主動設置,但能夠訪問
4. 屬性callee:arguments.callee指向函數自己,能夠用於遞歸中,優勢是即便函數名稱改變,也不會報錯 ; arguments.callee.caller指向調用此函數的函數,若無爲null,
5. 嚴格模式下,對arguments操做,只對arguments有效,對參數無效。
function test(a,b,c){ console.log(c); arguments[2]=10; console.log(c); arguments[3]=10; console.log(arguments[3]); console.log(arguments.length); arguments.length=4; console.log(arguments.length); } test(1,2,3) // 結果: // 3 // 10 特色2 // 10 特色3 // 3 // 4 test(1,2) // 結果: // undefined 特色2 // 10 特色3 // 10 // 2 // 4
31. 隊列,宏任務,微任務:參考:http://www.javashuo.com/article/p-cmtsxzha-h.html
1. 宏任務:script, setTimeout, setInterval :setTimeout 的含義爲:xx毫秒後加入event loop 中,setInterval 也是如此。
微任務:promise.then, process.nextTick(): nextTick將執行函數添加至這次執行棧的尾部。
2. 執行順序:script(宏) --> 微任務list(任務中有新的微任務時,直接添加在list中,依然在宏任務前執行) --> 宏任務list --> . . .
(宏任務必然是在微任務以後才執行的(由於微任務其實是宏任務的其中一個步驟))
32. SEO及優化:
1. TDK:title , description , keywords
2. 標題標籤,img的alt屬性,語義化標籤,
SPA的優化:單頁面應用對國內瀏覽器seo很不友好,國外瀏覽器不受影響。
a. 預渲染 b. ssr 服務端渲染,首屏採用服務端渲染。nuxt.js
vue : prerender-plugin + vue-meta-info
33. sort方法:瀏覽器的實現方式不一樣:V8:<=22使用InsertionSort ,>22使用QuickSort排序。ff:歸併排序
//自定義sort方法: Array.prototype.mySort = function (fn) { for (var i = this.length; i >0; i--) { for (var j =0; j < i; j++) { if (fn && typeof fn == 'function') { if(fn(this[j] ,this[j+1])>0){ [this[j], this[j+1]] = [this[j+1], this[j]]; } } else { var a = String(this[j]),b=String(this[j+1]); if(charcode(a,b)>0){ var temp=this[j]; this[j] = this[j+1]; this[j+1] = temp; // [this[j+1], this[j]] = [this[j], this[j+1]]; } } } } function charcode(a,b){ if(a.charCodeAt(0)<b.charCodeAt(0)){ return -1 }else if(a.charCodeAt(0)>b.charCodeAt(0)){ return 1 }else{ if(a.slice(1)===''){ return -1 }else if(b.slice(1)===''){ return 1 }else{ return charcode(a.slice(1),b.slice(1)) } } } return this; }
34. 構造函數:
//js中沒有類的概念(es6中也只是中語法糖),因此經過原型鏈實現繼承這種機制。 //構造函數實際上就是普通函數,返回一個實例對象 function Test(name,age){ this.name=name; this.age=age; }; //每一個函數都有prototype屬性,一個對象,是因此實例對象共有的屬性方法,由於都引用這個對象,new 的過程當中會自動添加constructor屬性,構造函數自己。 Test.prototype.constructor = Test; Test.prototype.fn=function(){}; //一個實例的屬性分爲兩部分:自有屬性 + 公共屬性 var test = new Test(1,2); // name , age , fn //經過 hasOwnProperty 判斷屬性是不是自有屬性 test.hasOwnProperty('fn') // false //經過 isPrototypeOf 判斷 實例 是不是構造函數的實例 Test.prototype.isPrototypeOf(test) // true;
35原型鏈:
數據類型:undefined,null,Number,String,Boolean + Object 六大類型。 Number,String,Boolean, Object,Function等都是構造函數,typeof 值:‘function’ 生成相應類型的數據能夠直接定義,也能夠經過構造函數生成(這種方式生成的返回值都是一個 object,function例外,返回的是function), // 1.prototype:只有函數有此屬性, // 2.__proto__:對象的此屬性指向構造函數的prototype, 函數的此屬性指向Function的prototype(因此的函數都是Function的實例), Obeject.__proto__ === Function.prototype // true typeof 爲function,此function較特殊,沒有prototype屬性, Object.__proto__.__proto__ ===Object.prototype // true 擁有object的屬性 //constructor:指向構造函數自己,在34中,是在prototype中的默認一個屬性。所以因此的實例中也會有此方法,
sd
36.運算符優先級及轉換
var a = (!(~+[])+{})[--[~+""][+[]]*[~+[]] + ~~!+[]] + ({}+[])[[~!+[]]*~+[]]; // sb (--的優先級大於*;~改變正負值再減一;[]是空=>0;{}是[object Object])
sd