今日頭條面試題與解析

簡答題

1.css3特性中的transform:translateZ(0)有什麼做用

答案: GPU加速,優化前端性能javascript


2.列舉三種禁止瀏覽器緩存的頭字段,並寫出響應的設置值

Expires:告訴瀏覽器把回送的資源緩存多長時間 -1或0則是不緩存 簡要:添加Expires頭能有效的利用瀏覽器的緩存能力來改善頁面的性能,能在後續的頁面中有效避免不少沒必要要的Http請求,WEB服務器使用Expires頭來告訴Web客戶端它能夠使用一個組件的當前副本,直到指定的時間爲止。 例如:Expires:Thu,15 Apr 2010 20:00:00 GMT; 他告訴瀏覽器緩存有效性持續到2010年4月15日爲止,在這個時間以內相同的請求使用緩存,這個時間以外使用http請求。css

Cache-Control:no-cache Cathe-Control:max-age=315360000html

Expires有一個很是大的缺陷,它使用一個固定的時間,要求服務器與客戶端的時鐘保持嚴格的同步,而且這一天到來後,服務器還得從新設定新的時間。 HTTP1.1引入了Cathe-Control,它使用max-age指定組件被緩存多久,從請求開始在max-age時間內瀏覽器使用緩存,以外的使用請求,這樣就能夠消除Expires的限制, 若是對瀏覽器兼容性要求很高的話,能夠兩個都使用。前端

Pragma:no-cachejava


3.精確獲取頁面元素位置的方式有哪些

那就是使用getBoundingClientRect()方法。它返回一個對象,其中包含了left、right、top、bottom四個屬性,分別對應了該元素的左上角和右下角相對於瀏覽器窗口(viewport)左上角的距離。css3

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 )es6


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運算符是不可以達到目的,咱們得換個方法。數組

一、從原型入手,Array.prototype.isPrototypeOf(obj);瀏覽器

利用isPrototypeOf()方法,斷定Array是否是在obj的原型鏈中,若是是,則返回true,不然false。

判斷object是數組類型
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,是否是感受很玄乎,可是剝開它華麗的外衣,也就那樣:

  1. 經過JavaScript來構建虛擬的DOM樹結構,並將其呈現到頁面中;
  2. 當數據改變,引發DOM樹結構發生改變,從而生成一顆新的虛擬DOM樹,將其與以前的DOM對比,將變化部分應用到真實的DOM樹中,即頁面中。 經過上面的介紹,下面,咱們就來實現一個簡單的虛擬DOM,並將其與真實的DOM關聯。

構建虛擬DOM

虛擬DOM,其實就是用JavaScript對象來構建DOM樹,如上ul組件模版,其樹形結構以下:

DOM樹
經過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());
複製代碼

公衆號
相關文章
相關標籤/搜索