簡答題
1.css3特性中的transform:translateZ(0)有什麼作用
答案: GPU加速,優化前端效能
2.列舉三種禁止瀏覽器快取的頭欄位,並寫出響應的設定值
Expires:告訴瀏覽器把回送的資源快取多長時間 -1或0則是不快取 簡要:新增Expires頭能有效的利用瀏覽器的快取能力來改善頁面的效能,能在後續的頁面中有效避免很多不必要的Http請求,WEB伺服器使用Expires頭來告訴Web客戶端它可以使用一個元件的當前副本,直到指定的時間為止。 例如:Expires:Thu,15 Apr 2010 20:00:00 GMT; 他告訴瀏覽器快取有效性持續到2010年4月15日為止,在這個時間之內相同的請求使用快取,這個時間之外使用http請求。
Cache-Control:no-cache Cathe-Control:max-age=315360000
Expires有一個非常大的缺陷,它使用一個固定的時間,要求伺服器與客戶端的時鐘保持嚴格的同步,並且這一天到來後,伺服器還得重新設定新的時間。 HTTP1.1引入了Cathe-Control,它使用max-age指定元件被快取多久,從請求開始在max-age時間內瀏覽器使用快取,之外的使用請求,這樣就可以消除Expires的限制, 如果對瀏覽器相容性要求很高的話,可以兩個都使用。
Pragma:no-cache
3.精確獲取頁面元素位置的方式有哪些
那就是使用getBoundingClientRect()方法。它返回一個物件,其中包含了left、right、top、bottom四個屬性,分別對應了該元素的左上角和右下角相對於瀏覽器視窗(viewport)左上角的距離。
var X= this.getBoundingClientRect().left;
var Y =this.getBoundingClientRect().top;
//再加上滾動距離,就可以得到絕對位置
var X= this.getBoundingClientRect().left+document.documentElement.scrollLeft;
var Y =this.getBoundingClientRect().top+document.documentElement.scrollTop;
複製程式碼
4.正則從2018-10-07T11:48:47 Asia/zh-cn 提取出來結果[2018,10,07,11,48,47]
"2018-10-07T11:48:47 Asia/zh-cn".match( /\d{1,}/g )
5.如何判斷object是陣列型別?
alert(typeof 1); // 返回字串"number"
alert(typeof "1"); // 返回字串"string"
alert(typeof true); // 返回字串"boolean"
alert(typeof {}); // 返回字串"object"
alert(typeof []); // 返回字串"object "
alert(typeof function(){}); // 返回字串"function"
alert(typeof null); // 返回字串"object"
alert(typeof undefined); // 返回字串"undefined"
複製程式碼
其中,typeof {}和typeof []的結果都是object,那麼問題來了,我怎麼通過typeof去判斷一個物件是不是陣列型別呢?
物件是物件,陣列也是物件,js中萬物皆物件,很顯然,通過簡單的typeof運算子是不能夠達到目的,我們得換個方法。
1、從原型入手,Array.prototype.isPrototypeOf(obj);
利用isPrototypeOf()方法,判定Array是不是在obj的原型鏈中,如果是,則返回true,否則false。
2.Array.isArray()方法。Array.isArray([1, 2, 3]); // true
Array.isArray({foo: 123}); // false
Array.isArray('foobar'); // false
Array.isArray(undefined); // false 
複製程式碼
程式設計題
1.已知資料結構users,請實現語法支援user.unique能夠按照name欄位去重,並輸出結構為:["a","b"]
var users=[{
id:1,name:"a"
},{
id:2,name:"a"
},{
id:3,name:"b"
},{
id:4,name:"v"
}]
複製程式碼
Array.prototype.unique = function () {
var res;
this.map(item => {
this[item.id - 1] = item.name
})
// ES6裡新新增了兩個很好用的東西,set和Array.from
// set是一種新的資料結構,它可以接收一個陣列或者是類陣列物件,自動去重其中的重複專案。
res=new Set(this);
console.log("new Set物件",res)
// 但是這裡大家可以看到,set返回的是一個物件,但是我們想要的是陣列啊。
// 這回,就該輪到Array.from出場了,它的作用,就是可以把類陣列物件、可迭代物件轉化為陣列。
res=Array.from(new Set(this));
return res//es6 陣列去重
}
console.log(users.unique());
複製程式碼
2.已知如下物件,請基於es6的proxy方法設計一個屬性攔截讀取操作的例子,要求實現去訪問目標物件example中不存在的屬性時,丟擲錯誤:Property "$(property)" does not exist
const man={
name:'jscoder',
age:22
}
//補全程式碼
const proxy = new Proxy(...)
proxy.name //"jscoder"
proxy.age //22
proxy.location //Property "$(property)" does not exist
複製程式碼
考點
es6 javascript的Proxy 例項的方法 ,get()
get方法用於攔截某個屬性的讀取操作。
var man = {
name:'jscoder',
age:22
};
var proxy = new Proxy(man, {
get: function(target, property) {
if(property in target) {
return target[property];
} else {
throw new ReferenceError(`Property ${property} does not exist.`);
}
}
});
console.log(proxy.name)
console.log(proxy.age)
console.log(proxy.location)
複製程式碼
Proxy 例項的方法的其他方法參考這個連結,很詳細 blog.csdn.net/qq_30100043…
3.給出如下虛擬dom的資料結構,如何實現簡單的虛擬dom,渲染到目標dom樹
//樣例資料
let demoNode = ({
tagName: 'ul',
props: {'class': 'list'},
children: [
({tagName: 'li', children: ['douyin']}),
({tagName: 'li', children: ['toutiao']})
]
});
複製程式碼
//構建一個render函式,將demoNode物件渲染為以下dom
<ul class="list">
<li>douyin</li>
<li>toutiao</li>
</ul>
複製程式碼
看到虛擬DOM,是不是感覺很玄乎,但是剝開它華麗的外衣,也就那樣:
- 通過JavaScript來構建虛擬的DOM樹結構,並將其呈現到頁面中;
- 當資料改變,引起DOM樹結構發生改變,從而生成一顆新的虛擬DOM樹,將其與之前的DOM對比,將變化部分應用到真實的DOM樹中,即頁面中。 通過上面的介紹,下面,我們就來實現一個簡單的虛擬DOM,並將其與真實的DOM關聯。
構建虛擬DOM
虛擬DOM,其實就是用JavaScript物件來構建DOM樹,如上ul元件模版,其樹形結構如下:
通過JavaScript,我們可以很容易構建它,如下:var elem = Element({
tagName: 'ul',
props: {'class': 'list'},
children: [
Element({tagName: 'li', children: ['item1']}),
Element({tagName: 'li', children: ['item2']})
]
});
複製程式碼
note:Element為一個建構函式,返回一個Element物件。為了更清晰的呈現虛擬DOM結構,我們省略了new,而在Element中實現。
/*
* @Params:
* tagName(string)(requered)
* props(object)(optional)
* children(array)(optional)
* */
function Element({tagName, props, children}){
if(!(this instanceof Element)){
return new Element({tagName, props, children})
}
this.tagName = tagName;
this.props = props || {};
this.children = children || [];
}
複製程式碼
好了,通過Element我們可以任意地構建虛擬DOM樹了。但是有個問題,虛擬的終歸是虛擬的,我們得將其呈現到頁面中,不然,沒鳥用。。
怎麼呈現呢?
從上面得知,這是一顆樹嘛,那我們就通過遍歷,逐個節點地建立真實DOM節點:
1. createElement;
2. createTextNode.
怎麼遍歷呢?
因為這是一顆樹嘛,對於樹形結構無外乎兩種遍歷:
1. 深度優先遍歷(DFS)
2. 廣度優先遍歷(BFS)
針對實際情況,我們得采用DFS,為什麼呢?
因為我們得將子節點append到父節點中
好了,那我們採用DFS,就來實現一個render函式吧,如下:
Element.prototype.render = function(){
var el = document.createElement(this.tagName),
props = this.props,
propName,
propValue;
for(propName in props){
propValue = props[propName];
el.setAttribute(propName, propValue);
}
this.children.forEach(function(child){
var childEl = null;
if(child instanceof Element){
childEl = child.render();
}else{
childEl = document.createTextNode(child);
}
el.appendChild(childEl);
});
return el;
};
複製程式碼
此時,我們就可以輕鬆地將虛擬DOM呈現到指定真實DOM中啦。假設,我們將上訴ul虛擬DOM呈現到頁面body中,如下:
var elem = Element({
tagName: 'ul',
props: {'class': 'list'},
children: [
Element({tagName: 'li', children: ['item1']}),
Element({tagName: 'li', children: ['item2']})
]
});
document.querySelector('body').appendChild(elem.render());
複製程式碼
歡迎關注前端公眾號,每日訂閱前端知識