前端工程師應該注意的一些細節,面試容易問到
個人最近整理的一些資料:每個問題都值得思考,有問題的地方還望廣大碼友批評指正,請勿用於其他用途!!!
所有示例務必親自試一試!!!
javascript
- ajax 原理
Ajax的工作原理相當於在使用者和伺服器之間加了—箇中間層(AJAX引擎),使使用者操作與伺服器響應非同步化。並不是所有的使用者請求都提交給伺服器,像—些資料驗證和資料處理等都交給Ajax引擎自己來做, 只有確定需要從伺服器讀取新資料時再由Ajax引擎代為向伺服器提交請求。
- 如何解決跨域問題,jsonp(json padding) 利用 script 標籤沒有跨域限制的機制(如果你用nodejs 那可以使用代理解決)
window['callbackFunc'] = function (response) { // 對返回的資料做後續處理 } var script = document.createElement('script'); script.src = 'http://back/service.jsonp?callback=callbackFunc'; document.body.appendChild(script);
- 談一談promises
Promise 是非同步程式設計的一種解決方案,比傳統的解決方案——回撥函式和事件——更合理和更強大。
將非同步操作以同步操作的流程表達出來,避免了層層巢狀的回撥函式。
Promise 的三種狀態
Pending(進行中)
Resolved(已完成,又稱 Fulfilled)
Rejected(已失敗)
// 能被 2 整除就返回成功, 否則返回失敗 var promise = new Promise(function(resolve, reject) { var number, value, error = "Not even"; setTimeout(() => { number = Math.round(Math.random() * 1000) if(number%2 === 0) { resolve(value); } else { reject(error); } }, 1000) }); promise.then( (value) => { console.log("success", value) }, (error) => { console.log("failure", error) })
- 陣列去重,不考慮物件陣列
Array.prototype.unique = function(){
var result = [];
var json = {};
for(var i = 0, len = this.length; i < len; i++){
if(!json[this[i]]){
result.push(this[i]);
json[this[i]] = true;
}
}
return result;
}
當陣列中存在物件時,則使用雙重迴圈
- js面向物件和繼承的理解(包括 call、apply實現繼承)
call、apply 有擴充套件作用域的功效
閉包: 原理是函式可以訪問函式呼叫時外部的作用域,本質是函式作用域的擴充套件。
注意:在退出函式時刪除不使用的變數,清理記憶體。
閉包優缺點:jQuery使用閉包原理,封裝保護變數,訪問區域性變數;佔記憶體
閉包的應用:當你點選頁面任何一個連結時彈出連結在頁面的序號,如第二個連結 alert(2)
function addClickEvt() {
var aList = document.getElementsByTagName('a');
var clickEvt = function(i) {
return function(e){
alert(i+1);
}
}
for (var i = aList.length - 1; i >= 0; i--) {
aList[i].onclick = clickEvt(i);
}
}
- 用js寫一個方法來檢測瀏覽器是否有某個css屬性,引數為屬性名
function testCss(propertyName) {
var element = document.createElement('div');
if(propertyName in element.style) return true;
return false;
}
- 如何獲取樣式表中的某個css屬性,如position,不同於嵌入HTML中的樣式 dom.style.position
var btn = document.getElementById('btn');//btn.backgroundColor 值為空;
var cStyle = document.defaultView.getComputedStyle(btn,null);
cStyle.backgroundColor;
- 根據 offsetPparent offsetLeft offsetRight 計算dom的邊距,方法引數為dom
function getPosition(dom) {
var left = 0,
top = 0;
while(dom.offsetParent){
left += dom.offsetLeft;
top += dom.offsetTop;
dom = dom.offsetParent;
}
return {left:left,top:top};
}
- 變數作用域和閉包的考察
function test(){
var a = 1;
setTimeout(function() {
alert(a);
a=3;
},1000);
a = 2;
setTimeout(function() {
alert(a);
a=4;
},4000)
}
test();
alert(0);//依次彈出:0;2;3
var a = 1;
function test() {
a=b=2;//b=2;a=b;
}
test()
alert(a);
alert(b);
//依次彈出:2;2
- this 、作用域以及arguments的考察
var length = 10;
function logLength() {
console.log(this.length);
}
var obj = {
length:5,
method:function(func) {
this.func = func
func();
arguments[0]();
this.func()
}
}
obj.method(logLength);
//依次列印:10,1,5
- 合併陣列並排序
var a = [1,-2,3,-5,2];
var b = [-1,4,-3,5,-4];
// 要求得到 [-5,-4,-3,-2,-1,1,2,3,4,5],即生序排列
// 實現
var arr = a.concat(b);
function sortArr(item1,item2) {
return item1 - item2;
}
arr.sort(sortArr);
- 自己寫個氣泡排序
function sortArr(array) {
for(var i = 0, len = arr.length; i < len; i++){
for(var j = i+1; j<len; j++){
var temp = array[i];
if(array[i] > array[j]) {
array[i] = array[j];
array[j] = temp;
}
}
}
}
result = sortArr(arr);
- 陣列、遞迴考察
// 已有物件obj
var obj = {
node_1:{
node_1_1:{
node_1_1_1:null
},
node_1_2:null
},
node_2:{
node_2_1:{
node_2_1_1:{
node_2_1_1_1:null
}
}
}
}
// 希望根據該物件獲得
// ["node_1", "node_1_1", "node_1_1_1", "node_1_2", "node_2", "node_2_1", "node_2_1_1", "node_2_1_1_1"]
// 請你寫一個js方法實現
function getArray (obj) {
var arr = [];
for(var prop in obj){
arr.push(prop);
if (obj[prop]!=null) {
arr = arr.concat(getArray(obj[prop]));
}
}
return arr;
}
var result = getArray (obj);
- 獲取字串中所有匹配項,並將所有項存入一個數組返回,使用 indexOf(str,offset)
var source = 'asdf aa asdfv ass aaa asdff,dsfsd',
result = getAllIndexOf(source,'aa');
function getAllIndexOf(sourceStr,filterStr) {
var arr = [];
var index = -1;
while(sourceStr.indexOf(filterStr,index+1)>=0){
index = sourceStr.indexOf(filterStr,index+1);
arr.push(index);
}
return arr;
}
- 呼叫方法A() 1000次,隨機入B、C,300次執行B(),700次執行C()
function A() {
if(!A.innit){
C.times = C.times?C.times:0;
B.times = B.times?B.times:0;
A.innit = true;
}
if(Math.round(1000*Math.random())%2==0 && C.times < 700){
C.times++;
C();
}else if(B.times < 300) {
B.times++;
B();
}else{
console.log('超出極限!');
}
}
function B() {
console.log('呼叫B的次數為:' + B.times);
}
function C() {
console.log('呼叫C的次數為:' + C.times);
}
- 阻止事件冒泡
event.stopPropagation();event.preventDefault();
事件傳播和預設操作是相互獨立的兩套機制,在二者任何一方發生時,都可以終止另一方。如果想要同時停止事件傳播和預設操作,可以在事件處理程式中返回false,這是對在事件物件上同時呼叫.stopPropagation()和.preventDefault()的一種簡寫方式。
Jquery
- 事件
jquery 事件委託 live delegate on (給現在不存在的DOM 元素繫結事件,委託給其父節點)
.bind()是直接繫結在元素上
.live()則是通過冒泡的方式來繫結到元素上的。更適合列表型別的,繫結到document DOM節點上。和.bind()的優勢是支援動態資料。
.delegate()則是更精確的小範圍使用事件代理,效能優於.live()
.on()則是最新的1.9版本整合了之前的三種方式的新事件繫結機制
- each() 與 map()
jquery each 和 map 不同 map返回一個新陣列(不需要時會影響記憶體,產生垃圾)
- get() 與 eq()
jquery eq(0) 和 get(0) 不同 eq 返回 jquery 物件,get 返回 javascript 物件
- document.ready
window.onload 事件和 jQuery ready 函式有何不同(前者等待媒體、圖片等,後者只要DOM樹載入完即可,而且可以多次使用)
- 移除元素
detach() 會保持對過去被解除元素的跟蹤, 因此它可以被取消解除, 而 remove() 方法則會保持過去被移除物件的引用
- get() 與 ajax()
ajax() 方法更強大,更具可配置性, 讓你可以指定等待多久,以及如何處理錯誤。get() 方法是一個只獲取一些資料的專門化方法。
css
- 談一談實踐中用 css 解決相容問題的例子
- reset 為了讓更多的瀏覽器能顯示同樣的效果
- hack 使你的CSS程式碼相容不同的瀏覽器”-moz-、-webkit-、*”
- sprite 把網頁中一些背景圖片整合到一張圖片檔案中,再利用CSS的“background-image”,“background- repeat”,“background-position”的組合進行背景定位
- 兩個浮動div,同屬一個父級,相對位置的確定(根據margin)
- 盒子模型
內容(content)、填充(padding)、邊框(border)、邊界(margin)
ie 盒子模型的 content 部分包含了 border 和 padding。(計算高度或寬度時會有所不同)
- 用css3實現效果,左側寬度固定,右側兩個寬度自適應,且寬度相等
.cantianer1 {
width: 100%;
border: green solid 4px;
}
.column1 {
float:left;
width:200px;
border-right: green solid 4px;
margin: 0;
}
.column {
width:auto;
margin-left:200px;
-moz-column-count: 2;
-webkit-column-count: 2;
column-count: 2;
-moz-column-rule: 4px outset green;
-webkit-column-rule: 4px outset green;
column-rule: 4px outset green;
}
- 實現效果,sidebar 寬度固定,content和header 寬度自適應; 當window 寬度小於 600px 時,變成三行佈局
.cantianer2 {
width: 100%;
border: #639A63 solid 6px;
margin: 0px;
}
.header {
background-color: red;
width: auto;
margin: 2px;
}
.sidebar {
float:left;
width:200px;
background-color: green;
margin: 0px 2px 2px 2px;
}
.content {
width:auto;
margin: 2px 2px 2px 206px;
background-color: blue;
}
@media (max-width: 600px) {
.header, .sidebar, .content {
width: 100%;
clear: both;
margin: 1px;
}
.cantianer {
border: 1px;
}
}
HTML
- 請寫出所瞭解的HTML5新增特性api,並指出應用場景。
標籤 | 語義 | 場景 |
---|---|---|
vidio | 視訊播放 | 網頁上播放視訊 |
canvas | 畫布 | 使用 JavaScript 在網頁上繪製圖像 |
svg | 可伸縮向量圖形 | 用於定義用於網路的基於向量的圖形 |
audio | 音訊 | 網頁上播放音訊 |
article | 定義文章 | 語義化,定義文章時使用 |
多媒體:video、audio、
遊戲:canvas、webgl、
儲存:localstorage、sessonstorage、websql、indexedDB
網路:websocket
應用程式快取:CACHE MANIFEST
- HTTP狀態碼
200成功類、300重定向類、400客戶端類、500伺服器端類
HTML有哪些塊與行內元素
doctype 的作用,標準模式和混雜模式如何區分,有什麼區別
HTML語義化的好處
去掉或樣式丟失的時候能讓頁面呈現清晰的結構
螢幕閱讀器(如果訪客有視障)會完全根據你的標記來“讀”你的網頁
PDA、手機等裝置可能無法像普通電腦的瀏覽器一樣來渲染網頁
搜尋引擎的爬蟲也依賴於標記來確定上下文和各個關鍵字的權重
你的頁面是否對爬蟲容易理解非常重要,因為爬蟲很大程度上會忽略用於表現的標記,而只注重語義標記
便於團隊開發和維護
前端程式碼以及效能優化
- CSS:
CSS程式碼簡寫;
同屬性提出;
結構清晰優化;
- HTML:
語義化;
id、class命名規範;
SEO關鍵詞;
- javascript:
減少全域性變數;
程式碼自注視;
統一縮排;
命名規範;
- 效能優化:
儘量減少HTTP請求;
使用內容釋出網路(CDN的使用);
分離樣式、指令碼到單獨檔案;
將CSS樣式引用放在頂部;
將javascript指令碼引用放在底部(可非同步的非同步);
減少DNS查詢;
精簡javascript;
避免重定向;
刪除重複指令碼;
配置ETag;
使Ajax可快取;
圖片整合;
樣式能用程式碼儘量用程式碼,而不用圖片;
減少DOM訪問;
減小Cookie體積
- SEO
Search Engine Optimization 搜尋引擎優化
- CND
Content Delivery Network,即內容分發網路。其基本思路是儘可能避開網際網路上有可能影響資料傳輸速度和穩定性的瓶頸和環節,使內容傳輸的更快、更穩定
關鍵技術主要有內容儲存和分發技術。
其他(MVC)框架使用經驗
ReactJS(只有View)
React之所以快,是因為它不直接操作DOM。React將DOM結構儲存在記憶體中,然後同render()的返回內容進行比較,計算出需要改動的地方,最後才反映到DOM中。
此外,React實現了一套完整的事件合成機制,能夠保持事件冒泡的一致性,跨瀏覽器執行。甚至可以在IE8中使用HTML5的事件。AngularJS
Backbone
Vue 檢視
。
。
。同源策略:不能訪問不同協議、域名、埠、。。。確保安全防止使用者資料被惡意網站利用。
- 跨域方式 .document.domain,jsonp,cors
談一談cookie和session以及h5的localstorage sessionstorage 等快取機制
嚴格模式好壞處:
Ajax返回的資料如何快取的
- http請求原生,後臺返回物件,各種狀態碼
- get post不同
登入密碼快取機制用 get 還是 post 為什麼
物件複製,改變副本原物件不受影響
圖片懶載入
前端效能優化。。快取機制優化效能的案例
css3實現畫進度圓、css3盒模型屬性以及各新屬性的使用和場景
移動端如何自適應螢幕大小
H5實際應用有哪些
document.ready 實現機制