1. 程式人生 > >2018-07-25拼多多提前批前端筆試題

2018-07-25拼多多提前批前端筆試題

2018-08-05拼多多前端筆試題

1.如何改變this的指向?

This物件是在執行時基於函式的執行環境繫結的:
1) 在全域性函式中,this等於window(匿名函式的執行環境具有全域性性,因此this物件指向window)
2) 當函式被作為某個物件的方法呼叫時,this等於那個物件
解析思路:如果是全域性環境,就是window,如果是物件呼叫,就是obj,如果不知道上下文環境,還是window吧
詳細解析
改變this的指向:通過bind(),call(),apply()改變函式執行環境的情況下,this就會指向其它物件。

2.設計函式輸出數組裡面的重複元素

先進行第一輪排序,排完之後的結果,就是1,1,2,3,3,3,4,4,5。如果是這樣的陣列中找重複的就好辦了,直接就是 arr[0]與arr[1]比較,依此類推,相等就是重複的.

var arr = [1,2,4,4,3,3,1,5,3];
function duplicates(arr) {
    var newArr=[];
    arr.sort();
    for(var i =0;i<arr.length;i++){
        if(arr[i]==arr[i+1]&&(newArr.indexOf(arr[i])==-1) ){
            newArr.push(arr[i]);
            i++;
 
        }
    }
 
return newArr;}

3.undefined和null的區別?

Null型別,代表“空值”,代表一個空物件指標,使用typeof運算得到 “object”,所以你可以認為它是一個特殊的物件值。undefined: Undefined型別,當一個聲明瞭一個變數未初始化時,得到的就是undefined。null是javascript的關鍵字,可以認為是物件型別,它是一個空物件指標,和其它語言一樣都是代表“空值”,不過 undefined 卻是javascript才有的。它是一個預定義的全域性變數。沒有返回值的函式返回為undefined,沒有實參的形參也是undefined。

4.foreach和map的區別

forEach()方法:對陣列的每一個元素都執行一次提供的函式

返回值: undefined

該方法不會改變原來的陣列,只是將陣列中的每一項作為callback的引數執行一次。

map()方法:map()方法建立一個新的陣列,其結果是該陣列中的每個元素都呼叫一次callback後返回的結果,同樣,該方法不改變原有的陣列

返回值: 新陣列,每個元素都是回撥函式的結果。

5.什麼是偽陣列,把偽陣列轉換為陣列

無法直接呼叫陣列方法或期望length屬性有什麼特殊的行為,不具有陣列的push,pop等方法,但仍可以對真正陣列遍歷方法來遍歷它們。典型的是函式的argument引數,還有像呼叫getElementsByTagName,document.childNodes之類的,它們都返回NodeList物件都屬於偽陣列。可以使用Array.prototype.slice.call(fakeArray)將陣列轉化為真正的Array物件。

6.跨域產生的原因及解決辦法?

跨域問題來源於JavaScript的同源策略,即只有 協議+域名+埠號 (如存在)相同,則允許相互訪問。也就是說JavaScript只能訪問和操作自己域下的資源,不能訪問和操作其他域下的資源。
解決辦法:
1) Jsonp 需要目標伺服器配合一個callback函式
2) 通過修改document.domain來跨子域
3) 使用window.name+iframe來進行跨域
4) 跨文件訊息傳輸window.postMessage
5) 通過CORS解決AJAX跨域
6) 通過設定Access-Control-Allow-Origin
7) 通過Nginx反向代理

7.CSS實現左邊固定右邊200px自適應

實現一個div,左邊固定div寬度200px,右邊div自適應

<div class= "container">
    <div class="left"></div>
    <div class="rigth"></div>
</div>
 
<style>
/*方法一: BFC(塊級格式化上下文)*/
    .container{
        width:1000px;height:400px;border: 1px solid red;
    }
    .left{
        width:200px;height:100%;background: gray;
        float: left;
    }
    .rigth{
        overflow:hidden;  /* 觸發bfc */
        background: green;
    }
 
/*方法二: flex佈局 */
    .container{
        width:1000px;height:400px;border:1px solid red;
        display:flex;         /*flex佈局*/
    }
    .left{
        width:200px; height:100%;background:gray;
        flex:none;
    }
    .right{
        height:100%;background:green;
        flex:1;        /*flex佈局*/
    }
 
/* 方法三: table佈局 */
    .container{
        width:1000px;height:400px;border:1px solid red;
        display:table;         /*table佈局*/
    }
    .left{
        width:200px; height:100%;background:gray;
        display:table-cell;
    }
    .right{
        height:100%;background:green;
        display: table-cell;
    }
 
/*方法四: css計算寬度calc*/
    .container{
        width:1000px;height:400px;border:1px solid red;
    }
    .left{
        width:200px;height:100%;background:gray;
        float:left;
    }
    .right{
        height:100%;background:green;
        float:right;
        width:calc(100% - 200px);
    }
/*方法五:負外邊距,雙飛翼佈局的雙欄佈局*/
</style>

8. JavaScript裡面0.1+0.2!=0.3的原因

在JavaScript中的二進位制的浮點數0.1和0.2並不是十分精確,在他們相加的結果並非正好等於0.3,而是一個比較接近的數字 0.30000000000000004 ,所以條件判斷結果為 false

2018-07-25拼多多前端筆試題

1. CSS實現動畫有哪些方式:

  1. css的transition(過渡屬性)
  2. 過渡屬性是一個複合屬性,主要包括以下幾個屬性
  3. transition-property:指定過渡或動態模擬的css屬性
  4. transition-duration:指定完成過渡所需的時間
  5. transition-timing-function:指定過渡函式
  6. transition-delay:指定開始出現的延遲時間
  7. css3的animation屬性
  8. Jquery的animate函式
  9. 原生js動畫
  10. a) 原生js動畫利用js程式碼,將動畫一步以函式的方式寫出來,可以實現多種動畫樣式,而且可以自己做相容性處理,自己設立每一步的動畫效果,並且能夠完成比較複雜的效果,但是程式碼量很大。如下面的例子:需要自己定義所有的動態函式,並進行計算、判斷和處理
  11. 外掛(waves,textillate.js等等)
  12. 使用canvas製作動畫(可以使用canvas在瀏覽器上畫圖,並且利用其api,製作動畫。)
  13. 使用gif圖片

2. 題目描述:

let arr1=[1,2,3];
let arr2=[4,5,6];
如何合併這兩個陣列:

let arr1=[1,2,3];
let arr2=[4,5,6];
// 第一種:
console.log(arr1.concat(arr2))
// 第二種:
Array.prototype.push.apply(arr1,arr2)
console.log(arr1)

3.編寫一個輸出日誌的函式log,在輸出內容前面加上字首(app),如: 

log(“Hello world”)返回“(app)Hello world”
log(“Hello”,”world”)返回”(app)Hello world”

function log(){
    //Array.prototype.slice.call(arguments)能將具有length屬性的物件轉成陣列
    var args = Array.prototype.slice.call(arguments).map(stringify);
    // console.log.apply(console,args);
    var t=args.toString().replace(',',' ')
    console.log('(app)'+t)
}
 
function stringify(arg) {
    return arg;
}
log( 'hello','world');

4.當代碼var a=new A(‘testa’)執行時,會發生什麼?

  1. var o = new Object();  //建立一個新物件
  2. 將建構函式的作用域賦值給新物件
  3. 執行建構函式中的程式碼,為新物件新增屬性
  4. 返回新物件

5.使用typeof bar===”object”判斷bar是不是一個物件有什麼弊端?如何避免這種弊端?

用typeof來判斷型別,只有‘boolean’、‘number’、’string’、‘function’四種類型是靠譜的

儘管 typeof bar === "object" 是檢查 bar 是否物件的可靠方法,令人驚訝的是在JavaScript中 null 也被認為是物件,即console.log(typeof null === 'object'); //true!
typeof bar === "object" 並不能準確判斷 bar 就是一個 Object。

可以通過 Object.prototype.toString.call(bar) === "[object Object]" 來避免這種弊端

6. 簡述一下什麼是淺拷貝,什麼是深拷貝,如何實現?

  1. 首先深複製和淺複製只針對像 Object, Array 這樣的複雜物件的。簡單來說,淺複製只複製一層物件的屬性,而深複製則遞迴複製了所有層級。
  2. 對於字串型別,淺拷貝是對值的複製,對於物件來說,淺拷貝是對物件地址的複製,並沒有開闢新的棧,也就是複製的結果是兩個物件指向同一個地址,修改其中一個物件的屬性,則另一個物件的屬性也會改變,而深複製則是開闢新的棧,深複製會在堆區開闢新的一塊,兩個物件對應兩個不同的地址,修改一個物件的屬性,不會改變另一個物件的屬性。
    淺拷貝:簡單複製(Object,Array),Object.assign()方法用於將所有可列舉的屬性的值從一個或多個源物件複製到目標物件。它將返回目標物件
    深拷貝:jQuery.extend( [deep ], target, object1 [, objectN ] ),其中deep為Boolean型別,如果是true,則進行深拷貝。JSON.parse()和JSON.stringify()

7. 快速排序

function quickSort(arr) {
    if(arr.length<=1){
        return arr;
    }
    var pivotIndex=Math.floor(arr.length/2);
    var pivot=arr.splice(pivotIndex,1)[0]
    var left=[];
    var right=[];
    for(var i=0;i<arr.length;i++){
        if(arr[i]<pivot){
            left.push(arr[i])
        }else {
            right.push(arr[i]);
 
        }
    }
    return quickSort(left).concat([pivot], quickSort(right));
}

8. json轉換

將陣列obj格式:
var obj = [
    {id:1, parent: null},
    {id:2, parent: 1},
    {id:3, parent: 2},
];
轉換為obj2格式:
var obj2 = {
    obj: {
        id: 1,
        parent: null,
        child: {
            id: 2,
            parent: 1,
            child: {
                id: 3,
                parent: 2
            }
        }
    }
}

答案如下:

var obj2 = {};
function createObj2(obj, child){
    if(child.parent){
        if(obj.obj){
            createObj2(obj.obj, child);
        }else{
            if(obj.id === child.parent){
                obj.child = {
                    id: child.id,
                    parent: child.parent,
                }
            }else{
                if(obj.child){
                    createObj2(obj.child, child);
                }else{
                    console.log('obj2未匹配到對應的parent對應關係')
                }
            }
        }
    }else{
        obj.obj = {
            id: child.id,
            parent: child.parent,
            child: {}
        }
    }
}
obj.forEach((item, item_i) => {
    createObj2(obj2, item)
})
console.log('obj2:', obj2)

other

function arr2obj(obj, parent) 
{  
let targetObj;  
obj.forEach(function(obj) {   
    if (obj.parent === parent) 
    {    targetObj = obj;   }  
});  
if (targetObj) {   
     targetObj.child = arr2obj(obj, targetObj.id);   
    if (!targetObj.child) {    delete targetObj.child;   }   
    if (!targetObj.parent) {    targetObj = {     obj: targetObj    }   }  
}  
    return targetObj; 
}