19秋招面經

8.11 & 8.12筆試

順豐科技二面 8.11(視頻)

  1. 自我介紹 + 實習經歷介紹
  2. 將來職業規劃
  3. 爲何想來順豐
  4. 瞭解過順豐科技的業務嗎?爲何沒關注?
  5. 學習工做中遇到過什麼比較困難的事情?怎麼解決?
  6. 指望薪資?能降嗎?
  7. 提問

猿輔導現場二面 8.10

  1. 自我介紹 + 實習經歷
  2. 算法題1:使用setTimeout實現setInterval功能
function mySetInterval(fn, ms) {
    function interval(){
        setTimeout(interval, ms);
        fn();
    }
    setTimeout(interval, ms);
}

// 更好的實現

function mySetInterval(fn, ms, count) {
    function interval() {
        if(typeof count === 'undefined' || count-- > 0) {
            setTimeout(interval, ms);
            try {
                fn();
            } catch(e) {
                t = 0;
                throw e.toString();
            }
        }
    }
    setTimeout(interval, ms);
}
複製代碼
  1. 算法題2:使用遞歸和非遞歸兩種方法統計一棵二叉樹的深度
  2. 算法題3:在一個無序數組中,尋找連續兩個及兩個以上的相同元素的個數
例如:有數組[10, 22, 32, 4, 4, 5, 6, 9, 8, 8, 2],返回結果爲2

4, 4
8, 8
複製代碼
  1. 算法題3延伸:若是給定的是一個有序數組,如何優化?

猿輔導現場一面 8.10

  1. 自我介紹 + 實習經歷
  2. 爲何會選前端
  3. React:生命週期 + 組件間數據傳遞 + ref
  4. 原生JS:做用域鏈 + 原型鏈 + 閉包
  5. 緩存機制(強緩存 + 協商緩存) + 相關HTTP頭部信息
  6. URL從輸入網址到最終呈現的流程 + 哪些步驟能夠優化
  7. Canvas API
  8. 算法題:判斷一棵二叉樹是對稱的

CVTE終面(視頻) 8.10

太多了,跟面試前補充的簡歷幾乎同樣javascript

順豐科技一面 8.4 (視頻)

  1. 自我介紹 + 項目 + 實習
  2. 研究生以後記憶深入的事
  3. 原型的理解
  4. 閉包的理解
  5. ES5/ES6建立對象的方法
  6. ES5/ES6繼承的方法
  7. 前端語言體系三要素
  8. HTML語義化
根據內容的結構化(內容語義化),選擇合適的標籤(代碼語義化),
便於開發者閱讀和寫出更優雅的代碼的同時讓瀏覽器的爬蟲和機器很好地解析
複製代碼
  1. React的Virtual Dom/Diff算法
  2. Set和Map區別
  3. HTTP與TCP/IP或Socket的區別
TCP鏈接 須要通過「三次握手」

HTTP/1.0 客戶端發送的每次請求都須要服務器回送響應,在請求結束後,會主動釋放鏈接
HTTP/1.1 一次鏈接中處理多個請求,而且多個請求能夠重疊進行,不須要等待一個請求結束後再發送下一個請求


複製代碼
  1. 爲何投順豐科技
  2. 提問

補充:css

  1. 前端兼容性問題
  2. Webpack更新原理
  3. CSS Hack
  4. 箭頭函數爲何不能做爲構造函數
  5. npm發佈版本號
  6. package.json和package-lock.json區別
  7. CSS菊花圖(animation-delay實現)
  8. Object.create實現

大疆二面 8.2(視頻)

  1. 自我介紹
  2. 工做過程當中遇到什麼困難?
  3. 怎麼跟產品經理溝通的?出現問題的緣由在哪裏?如何解決?最終達成一致的立足點是什麼?
  4. 如何學習的?寫過組件庫嗎?看過或本身有開源項目嗎?
  5. 瞭解React Native嗎
  6. 瞭解C/C++嗎?(懂Java)那說說Java內存機制?
  7. 數據結構瞭解?哪些排序算法?實際中有用嗎?
  8. 你但願的工做環境是怎樣的?
  9. 你對996制度怎麼看?
  10. 你有什麼問題?

CVTE二面 8.1(視頻)

  1. 自我介紹
  2. 前端的學習曲線
  3. 對本身將來的規劃
  4. React的diff算法
  5. React生命週期,setState能用在componentWillUpdate裏嗎?
  6. 算法題:字符串最長不重複子串的長度
  7. 最近看什麼新知識

CVTE一面 7.29

  1. 最近作什麼項目?
  2. 跨域瞭解過哪些?跨域傳cookie可使用哪一種方法?
第一步:
設置響應消息頭Access-Control-Allow-Credentials值爲「true」。
同時,還須要設置響應消息頭Access-Control-Allow-Origin值爲指定單一域名
第二步:
客戶端須要設置Ajax請求屬性withCredentials=true,讓Ajax請求都帶上Cookie
複製代碼
  1. 怎麼處理cookie?刪除cookie?
  2. insertBefore方法
  3. JS異步解決方案
  4. 瀏覽器端的EventLoop和Node的EventLoop
  5. setTimeout和Ajax的優先級
  6. JS實現事件綁定的方法
1. elementObject.addEventListener(eventName,handle,useCapture) 

2. elementObject.attachEvent(eventName,handle);(僅支持IE8及如下)

3. document.getElementById("demo").onclick = function(){};
複製代碼
  1. CSS如何適配瀏覽器大小?
1. <meta name="viewport"
        content="width=device-width, height=device-height, inital-scale=1.0, maximum-scale=1.0, user-scalable=no;" 
    />
2. 網頁內部的元素寬度要使用百分比,在不一樣的屏幕大小下需使用媒體查詢定義不一樣的css代碼

代碼解析:

width:控制 viewport 的大小,能夠是指定的一個值,好比 1920,或者是特殊的值,如 device-width 爲設備的寬度,單位爲縮放爲 100% 時的 CSS 的像素。

height:和 width 相對應,指定高度,能夠是指定的一個值,好比 1080,或者是特殊的值,如 device-height 爲設備的高度。

initial-scale:初始縮放比例,即當頁面第一次載入是時縮放比例。

maximum-scale:容許用戶縮放到的最大比例。

minimum-scale:容許用戶縮放到的最小比例。

user-scalable:用戶是否能夠手動縮放。
複製代碼
  1. 瀏覽器的內核有哪些?哪些CSS屬性須要設置?
1. IE: Trident內核
2. Firefox:Gecko內核
3. Google:Blink內核
4. Safari:Webkit內核

-webkit- ,針對safari,chrome瀏覽器的內核CSS寫法
-moz-,針對firefox瀏覽器的內核CSS寫法
-ms-,針對ie內核的CSS寫法
-o-,針對Opera內核的CSS寫法
複製代碼
  1. 三列布局的實現
  2. 三角形的實現
  3. HTTP/1.1和HTTP/1.0的區別
  4. HTTP的狀態碼
  5. 瀏覽器緩存的分類
  6. cache-control的值有哪些?
  7. 對JS原型鏈的理解
  8. 實現方法?弊端?
  9. 日常怎麼學前端?
  10. 爲何選擇前端?
  11. 有寫博客嗎?有給開源項目貢獻代碼嗎?

阿里飛豬二面 7.25

  1. 自我介紹 + 實習狀況
  2. 如何判斷Array
  3. React-router原理?用到哪些API?
  4. React實現幻燈片組件對外暴露的接口有哪些?
  5. CSS第三方庫的原理
  6. CSS響應式設計的方式
CSS響應式設計適配多種設備:

1. <meta name="viewport" content="width=device-width, initial-scale=1" />

2. 不要使用絕對寬度

3. 字體大小和長寬邊距屬性不要用」px」,應該用相對大小的「rem」

4. 使用流動佈局
- 若是寬度過小,放不下兩個元素,後面的元素會自動滾動到前面元素的下方,不會在水平方向overflow(溢出),避免了水平滾動條的出現

5. link標籤的media屬性
- <link rel="stylesheet" type="text/css" media="screen and (min-width: 600px) and (max-device-width: 980px)"  
href="css600-980.css" />  

6. Media Query

7. 圖片的自適應(自動縮放)
- img{max-width: 100%;} 
- 最好仍是根據不一樣大小的屏幕,加載不一樣分辨率的圖片
複製代碼
  1. XSS和CORS原理及解決方案
  2. HTTP和HTTPS的區別
  3. 前端優化的方法
  4. utf-8和unicode區別
1. Unicode是'字符集',utf-8是'編碼規則'
(以8位爲一個編碼單位的可變長編碼,會將一個碼位編碼爲1到4個字節)
2. 字符集:爲每個字符分配一個惟一的ID
   編碼規則:將碼位轉爲字節序序列的規則

例如:'知'的碼位是30693,記做U+7735(16進製爲0x77E5)

'Unicode與utf-8關係':
U+0000 - U+007F:0XXXXXXX
U+0080 - U+07FF:110XXXXX 10XXXXXX
U+0800 - U+FFFF:1110XXXX 10XXXXXX 10XXXXXX
U+10000 - U+1FFFF:11110XXX 10XXXXXX 10XXXXXX 10XXXXXX

3. utf-16使用2或4字節來保存,utf-32使用4字節保存

'GBK與utf-8':

- UTF-8包含全世界全部國家須要用到的字符,是國際編碼,通用性強。
- GBK是國家標準GB2312基礎上擴容後兼容GB2312的標準。
- GBK的文字編碼是用'雙字節'來表示的,爲了區分中文,將其最高位都設定成1,通用性比UTF8差。


複製代碼

大疆一面 7.24

  1. 自我介紹
  2. React-router原理 + SPA
  3. React-router的Link和a標籤的跳轉有什麼區別?
  • Link按需更新,a標籤會重複渲染、形成白屏

補充: React-router中的Link和Route的區別html

  • route是配置,link是使用
  • 靜態跳轉:經過Link組件實現靜態跳轉
    • 必須以寫入組件的方式實現跳轉
    • 沒法跳到歷史記錄中的前一個界面,後一個界面,前N個界面,後N個界面
  • 動態跳轉:經過Route注入component中的route屬性實現動態跳轉
    • 從Route組件中傳入component中的router屬性對象解決了這個問題
  • NavLink是Link的一個特定版本,會在匹配上當前的url的時候給已經渲染的元素添加參數
  1. state和props的區別
  2. virtual DOM和diff算法
  3. Ajax請求應該在哪一個生命週期函數中?爲何不在componentWillMount裏?
  • 在componentDidMount中
  • ajax請求在返回數據後需調用setState方法,進而更新state值,但componentWillMount並不容許(該函數效果與constructor相同,只能設定state初始值),沒法觸發重渲染
  1. key有什麼做用?爲何不該該用數組的index值當key?(不穩定)
  2. 算法題:在局部遞增數組(如:[3, 4, 5, 1, 2])中查詢指定數字是否存在
  3. React學了多久?
  4. 提問

拼多多筆試 7.22

  1. 下面的輸出是什麼?
const promise = new Promise((resolve, reject) => {
    console.log('a');
    resolve();
    console.log('b');
});

promise.then(() => {
    console.log('c');
});

console.log('d');

// a b d c,Promise的異步執行
複製代碼
  1. 下面的輸出是什麼?
(function(x) {
    return (function(y) {
        console.log(x);
    })(2);
})(1);

// 1,閉包問題
複製代碼
  1. 下面的輸出是什麼?
pi = 0;
radius = 1;
function circum(radius) {
    radius = 3;
    pi = 3.14;
    console.log(2 * pi * radius);   // 18.14
    console.log(arguments[0]);      // 3
}
circum(2);                  
console.log(pi);            // 3.14
console.log(radius);        // 1

函數內修改了radius 修改的是"形式參數",修改的pi是"全局的"pi
複製代碼

與下述狀況相同前端

var pi = 0;
var radius = 1;
function circum(radius) {
    radius = 3;
    pi = 3.14;
    console.log(2 * pi * radius);   // 18.84
    console.log(arguments[0]);      // 3
}

circum(radius);

console.log(pi);            // 3.14
console.log(radius);        // 1
複製代碼

補充java

function foo(a, b){
   arguments[0] = 9;
   arguments[1] = 99;
   console.log(a, b); //9, 99
}
foo(1, 10); 

function foo(a, b){
   a = 8;
   b = 88;
   console.log(arguments[0], arguments[1]); //8, 88
}
foo(1, 10);

// ES6的默認函數不會改變arguments類數組對象值
function foo(a=1, b=10){
   arguments[0] = 9;
   arguments[1] = 99;
   console.log(a, b); //1, 10
}
foo();

// 實例
function f2(a) {
    console.log(a); 
    var a;
    console.log(a);
    console.log(arguments[0])
}
f2(10)

通過變量提高後:
function f2(a) {
    var a;
    console.log(a); 
    console.log(a);
    console.log(arguments[0])
}
f2(10);

var a會被概括,因爲a已經有值,故不會變爲undefined
複製代碼
  1. 哪些是穩定排序?哪些是不穩定排序?
    定義:
    假定在待排序的記錄序列中,存在多個具備相同的關鍵字的記錄,若通過排序,這些記錄的相對次序保持不變,即在原序列中,r[i]=r[j],且r[i]在r[j]以前,而在排序後的序列中,r[i]仍在r[j]以前,則稱這種排序算法是穩定的;不然稱爲不穩定的。
穩定排序:
插入排序 [1]  ,冒泡排序 [2]  ,歸併排序 [3]  ,基數排序 [4]  ,計數排序 [5] 

不穩定排序:
快速排序 [1],簡單選擇排序 [2],希爾排序 [3],堆排序 [4]
複製代碼
  1. typeof obj === 'object'判斷obj是對象的弊端?如何改進?
var  obj = {};
var  arr = [];
var funcInstance = new (function (){});  
var isNull = null;

console.log(typeof obj === 'object');  //true
console.log(typeof arr === 'object');  //true
console.log(typeof funcInstance == 'object');  //true
console.log(typeof isNull === 'object');    // true

// constructor
({}).constructor === Object;  //true
([]).constructor === Array;  //true

// instanceof
({}) instanceof Object;  //true
([]) instanceof Array;   //true

// toString: 將當前對象以字符串的形式返回
console.log(Object.prototype.toString.call(obj));  //[object Object]
console.log(Object.prototype.toString.call(arr));  //[object Array]
console.log(Object.prototype.toString.call(null));  //[object Null]
複製代碼
  1. 補充題:下面的輸出是什麼?
var a = {};
var b = {name:"ZS"};
var c = {};
c[a] = "demo1";
c[b] = "demo2";

console.log(c[a]);      // demo2
console.log(c);         // Object {[object Object]: "demo2"}

c[a]、c[b]隱式的將對象a,b使用了toString()方法進行了轉換,而後再對屬性賦值。
即:Object.prototype.toString.call(a) ==> [object Object]
所以,c = { [object Object]: 'demo1'} ==> c = {[object Object]: 'demo2' }
複製代碼
  1. 編程:實現log函數
function log() {
    // var arr = [].slice.call(arguments);
    var arr = Array.from(arguments);
    var res = '';
    arr.forEach(elem => {
        res += elem + ' ';
    });
    console.log(`(app)${res}`);
}

// 測試
log('hello', 'world');
log('hello world');
複製代碼
  1. 將具備父子關係的原始數據格式化成樹形結構數據
    第一種思路:
function toTreeData(data){
	var pos={};
	var tree=[];
	var i=0;
	while(data.length!=0){
		if(data[i].pid==0){
			tree.push({
				id:data[i].id,
				text:data[i].text,
				children:[]
			});
			pos[data[i].id]=[tree.length-1];	
			data.splice(i,1);
			i--;
		}else{
			var posArr=pos[data[i].pid];
			if(posArr!=undefined){
				
				var obj=tree[posArr[0]];
				for(var j=1;j<posArr.length;j++){
					obj=obj.children[posArr[j]];
                }
                
				obj.children.push({
					id:data[i].id,
					text:data[i].text,
					children:[]
				});
				pos[data[i].id]=posArr.concat([obj.children.length-1]);
				data.splice(i,1);
				i--;
			}
		}
		i++;
		if(i>data.length-1){
			i=0;
		}
	}
	return tree;
}


var data=[
    {id:1,pid:0,text:'A'},
    {id:2,pid:4,text:"E[父C]"},
    {id:3,pid:7,text:"G[父F]"},
    {id:4,pid:1,text:"C[父A]"},
    {id:5,pid:6,text:"D[父B]"},
    {id:6,pid:0,text:'B'},
    {id:7,pid:4,text:"F[父C]"}
];

var result = toTreeData(data);

console.log(result);
複製代碼

第二種思路:web

function treeObj(originObj) {
    // 深拷貝
    let obj = {};
    for(key in originObj) {
        var val = originObj[key];
        // arguments的callee屬性指向擁有這個 arguments 對象的函數
        obj[key] = typeof val === 'object'? arguments.callee(val):val;
    }
    obj['children'] = [];
    return obj;
}

function toTreeData(data, attributes) {
    let resData = data;
    let tree = [];
    
    // 找根節點
    for(let i = 0; i < resData.length; i++) {
        if(resData[i][attributes.parentId] === ''
            ||
            resData[i][attributes.parentId] === null) {
                tree.push(treeObj(resData[i]));
                // 刪除掉已經放入tree中的根節點
                resData.splice(i, 1);
                i--;
            }
    }
    // 找尋子樹
    return run(tree);

    function run(childArr) {
        if(resData.length !== 0) {
            for(let i = 0; i < childArr.length; i++) {
                for(let j = 0; j < resData.length; j++) {
                    if(childArr[i][attributes.id] === resData[j][attributes.parentId]) {
                        let obj = treeObj(resData[j]);
                        childArr[i].children.push(obj);
                        // 刪除加入樹中的節點
                        resData.splice(j, 1);
                        j--;
                    }
                }
                run(childArr[i].children);
            }
        }
        return tree;
    }
}


let allRes = [
    {
        id: 4,
        resName: "刪除角色",
        parentId: 2
    },
    {
        id: 3,
        resName: "編輯角色",
        parentId: ''
    },
    {
        id: 2,
        resName: "設置權限",
        parentId: ''
    },
    {
        id: 5,
        resName: "添加用戶",
        parentId: 4
    },
    {
        id: 6,
        resName: "更新用戶",
        parentId: 4
    },
    {
        id: 7,
        resName: "刪除用戶",
        parentId: 6
    },
    {
        id: 8,
        resName: "重置密碼",
        parentId: 3
    },
    {
        id: 9,
        resName: "添加地區",
        parentId: 5
    },
    {
        id: 10,
        resName: "編輯地區",
        parentId: 6
    }
];

let data = allRes;
// 屬性配置信息
let attributes = {
    id: 'id',
    parentId: 'parentId',
};
let treeData = toTreeData(data, attributes);

console.log(treeData);

複製代碼
  1. 深拷貝與淺拷貝的區別?如何實現?
  • 淺拷貝(shallow copy):只複製指向某個對象的指針,而不復制對象自己,新舊對象共享一塊內存
  • 深拷貝(deep copy):複製並建立一個一摸同樣的對象,不共享內存,修改新對象,舊對象保持不變
// 1. Object.assign

let foo = {
    a: 1,
    b: 2,
    c: {
        d: 1,
    }
}
let bar = {};
Object.assign(bar, foo);
foo.a++;
foo.a === 2 //true
bar.a === 1 //true
foo.c.d++;
foo.c.d === 2 //true
bar.c.d === 1 //false
bar.c.d === 2 //true

Object.assign()是一種能夠對非嵌套對象進行深拷貝的方法;
若是對象中出現嵌套狀況,那麼其對被嵌套對象的行爲就成了普通的淺拷貝。


// 2. JSON.parse和JSON.stringify

var obj1 = { body: { a: 10 } };
var obj2 = JSON.parse(JSON.stringify(obj1));
obj2.body.a = 20;
console.log(obj1);   // { body: { a: 10 } } 
console.log(obj2);   // { body: { a: 20 } }
console.log(obj1 === obj2);   // false
console.log(obj1.body === obj2.body);   // false

用JSON.stringify把對象轉成字符串,再用JSON.parse把字符串轉成新的對象。
可是,會破壞原型鏈,而且沒法拷貝屬性值爲function的屬性


// 3. 遞歸

var json1={
    "name":"shauna",
    "age":18,
    "arr1":[1,2,3,4,5],
    "string":'got7',
    "arr2":[1,2,3,4,5],
    "arr3":[{"name1":"shauna"},{"job":"web"}]
};
var json2={};

function copy(obj1,obj2){
  var obj2 = obj2 || {};
  for(var name in obj1){
    if(typeof obj1[name] === "object"){ 
      obj2[name]= (obj1[name].constructor===Array)?[]:{}; 
      copy(obj1[name],obj2[name]); 
    }else{
      obj2[name]=obj1[name];  
    }
  }
  return obj2;
}

json2=copy(json1,json2)
json1.arr1.push(6);
alert(json1.arr1);  //123456
alert(json2.arr1);  //12345
複製代碼
  1. 補充題: 數組扁平化
// 遞歸
function flatten(arr){
    var res = [];
    for(var i=0;i<arr.length;i++){
        if(Array.isArray(arr[i])){
            res = res.concat(flatten(arr[i]));
        }else{
            res.push(arr[i]);
        }
    }
    return res;
}
複製代碼

CVTE筆試 7.20

  1. 回溯算法面試

  2. 下面的輸出是什麼?ajax

var array1 = Array(3);
array1[0] = 2;
var result = array1.map(elem => '1');

// ['1', empty * 2]
複製代碼
  1. 下面的輸出是什麼?
var setPerson = function(person) {
    person.name = 'kevin';
    person = {name: 'Nick'};
    console.log(person.name);       // Nick
    person.name = 'Jay';
    console.log(person.name);       // Jay
}
var person = {name: 'Alan'};
setPerson(person);
console.log(person.name);           // Kevin
複製代碼
  1. 下面的輸出是什麼?
var execFunc = () => console.log('a');
setTimeout(execFunc, 0);
console.log('000');
execFunc = () => console.log('b');

// '000', 'a'
複製代碼

補充:setTimeout沒法使用含參函數參數算法

window.setTimeout(hello(userName),3000);
這將使hello函數當即執行,並將'返回值'做爲調用句柄傳遞給setTimeout函數

// 方法1:
使用'字符串形式'能夠達到想要的結果:
window.setTimeout("hello(userName)",3000);
可是,此處的username變量必須處於全局環境下

// 方法2:
function hello(_name){
       alert("hello,"+_name);
}
// 建立一個函數,用於返回一個無參數函數
function _hello(_name){
       return function(){
             hello(_name);
       }
}
window.setTimeout(_hello(userName),3000);
使用_hello(userName)來返回一個不帶參數的函數句柄,從而實現了參數傳遞的功能
複製代碼
  1. 下面的輸出是什麼?
for(var i = {j: 0}; i.j < 5; i.j++) {
    (function(i){
        setTimeout(function() {
            console.log(i.j);
        }, 0);
    })(JSON.parse(JSON.stringify(i)));
}

// 0, 1, 2, 3, 4

for(var i = {j: 0}; i.j < 5; i.j++) {
    (function(i){
        setTimeout(function() {
            console.log(i.j);
        }, 0);
    })(i);
}

// 5, 5, 5, 5, 5
複製代碼
  1. Generator
  2. line-height
  3. FileReader
  4. 如何判斷x爲數組
  5. npm依賴包的版本號
  6. attachEvent, detachEvent, dispathEvent

阿里飛豬1面 7.20

  1. 自我介紹 + 項目介紹(難點)
  2. React相關知識
  • 生命週期
  • diff算法及時間複雜度
  • refs
  • React-router原理
  1. Redux和Relay的瞭解
  2. Node的瞭解
  3. Webpack的瞭解(如何使用)
  4. typeof操做符的返回值(undefined, number, string, boolean, object, function, symbol)
  5. ES6的瞭解程度
  • var,let,const區別
  • const a = []; a.push(1); 容許嗎?
  • Symbol的用處(避免屬性名衝突)
  1. 除get和post以外,HTTP的請求方法還有哪些
  2. HTTP的狀態碼有哪些
  3. 從輸入網址到頁面呈現的過程
  4. DOMContentLoad和Load的區別
  5. Flex佈局
  6. 客戶端的存儲方法?localStroage和sessionStorage的區別
  7. HTML5點擊延遲事件
  8. 移動端前端開發的瞭解
  9. 前端性能優化的方法
  10. 前端性能工具
  11. 日常怎麼學習前端?
  12. 提問

做業幫7.9

  1. Webpack的瞭解
  2. React的diff算法
  3. 單向數據流
  4. MVC和MVVM的區別
  5. ES6瞭解程度(let,const,Generator,Promise)
  6. JS異步方法及回調地獄
  7. Node、MongoDB瞭解多少
  8. 關係型和菲關係型數據庫的區別
  9. CSS的position屬性有哪些
  10. 左右定寬,中間自適應的多種CSS佈局方法
  11. 前端的性能優化
  12. HTTP狀態碼

做業幫 2018

1.如何進行輸入去重?chrome

// 方法1:
function nonDup(arr){
    var res = [];
    for(var i = 0; i < arr.length; i++) {
        if(res.indexOf(arr[i]) === -1) {
            res.push(arr[i]);
        }
    }
    return res;
}

// 方法2:
function nonDup(arr){
    var res = new Set(arr);
    return [...res];
}

// 方法3:
function nonDup(arr){
    return arr.filter((elem, index) => {
        return index === arr.indexOf(elem);
    });
}

// 方法4:

Array.prototype.uniq = function () {
    var hasNaN = false;
    for(var i = 0; i < this.length; i++){
        if(this[i] !== this[i]) hasNaN = true;
        for(var j = i+1; j < this.length;){
            if(this[i] === this[j] ||(hasNaN && this[j] !== this[j])){
                this.splice(j,1);
            }else{
                j++;
            }
        }
    }
    return this;
}
複製代碼

2.實現鼠標滑過頭像顯示簡介

<!DOCTYPE html>
<html>
<head>
<style>
    .div1{
        width:100px;
        height:100px;
        background-color:red;
        border-radius: 50px;
    }
    .div2{
        width:100px;
        height:200px;
        margin-top: 10px;
        background-color:black;
        display: none;
    }
</style>
</head>
<body>
    <div class='div1'></div>
    <div class='div2'></div>
    
    <script type="text/javascript">
        var d1 = document.getElementsByClassName('div1')[0];
        var d2 = document.getElementsByClassName('div2')[0];
        var timer;
        d1.addEventListener('mouseenter',function(){
            timer = window.setTimeout(function(){d2.style.display="block"},300);
        })
        d1.addEventListener('mouseout',function(){
            window.clearTimeout(timer);
            d2.style.display="none";
        })
    </script>
</body>
</html>
複製代碼
相關文章
相關標籤/搜索