[筆記] Javascript 面試題

日本嵐山

看過許多大大寫得的稍微做整理

題目:
幫 array 加一個 any 的 function,可以輸入任一 function,如果任何一個元素丟進那 function 裡面的值是 true,就輸出 true,否則就 false。
例如:
[1, 2, 3, 4, 5].any(isGreaterThanZero); //=> true
[-1, 0].any(isGreaterThanZero); //=> false

Array.prototype.any = function (func) {
    var objLen = this.length;
    for (i=0;i< objLen;i++){
        if(func (this[i])) return true;
    }
    return false;
};
題目:
對於這一行程式碼:var MyObject = new MyClass();可以試著講講看背後做了什麼事嗎?有沒有可能不用 new 但是卻達成一樣的效果?

在這邊稍微整理一下函式建構式(constructor)
new constructor[([arguments])]
  • new 為一個運算子(operators),用來建立新的物件
  • 指定函數構造(constructor)來創建一個實例(instance)
  • 當 new MyClass() 執行時,繼承 MyClass() 的 prototype

當我們建立一個 Constructor
function person(nickname, years, gender) {
    this.nickname = nickname;
    this.years = years;
    this.gender = gender;
}
再建立一個新物件
var mySis = new person('Cindy',12, 'M');
此時,新的物件(mySis)被建立,且繼承 person() 的屬性、屬性值,如果帶入引數,則會覆蓋原本的 person() 屬性值。
可以 return,也可以不 return,就建立一個空的物件。當然也可以寫成帶引數 person(),或不帶引數 person。

如果沒有添加 new 呢?
var myDad = person('Harry', 51, 'M');
var myMom = person('Amy', 50, 'F');

console.log(myDad); //undefined
console.log(myMom); //undefined
因為 JavaScript 不知道你是要執行這個程式還是要根據這個function去建立object,因次最後回傳 undefined 的結果。

替代法:如果不使用 new ?關於Object.create()

在其他語言,我們會用 class 來設定物件的樣貌,再用 new 建立需要的物件,那麼JavaScript實際上使用的是原形繼承(prototypal inheritance),而不是類別繼承(classic inheritance),那麼我們讓 JavaScript 回歸到 prototypal inheritance 所以使用 Object.create(),目前大多的瀏覽器也都有支援。

好處:
可以傳入第二個引數(非必要)
當同一函式需要被繼承多次時,確保內容不被更動(此在簡單的需求,較難體會)

寫法:
var myFriend = Object.create(person);
// 修改內容
myFriend.nickname = 'Jhon';
myFriend.years = 40;
myFriend.gender = 'M';

// 結果
// Function {}
//     gender:"M"
//     nickname:"Jhon"
//     years:40

若不支援 Object.create()呢?那就寫一個 Polyfill吧
function inherit(o) {
    if(!Object.create){
        if(arguments.length>1) {
            //此時無法使用第二引數
            throw new Error('Object.create implementation only accepts the first parameter');
        }
        //宣告一個新的物件
        function F() {}
        //把原本的建構式塞進 F
        F.prototype = o;
        //回傳
        return new F();
    } else {
        return Object.create(o);
    }
}

//建立一個物件
var dorasMom = inherit(person);

其實,本質上就用new()代替,我想之後可以探討一下關於inherit。

題目:字串反轉
function revers(str) {
    var output = "";
    const len = str.length;
    for (i=len-1; i>=0; i--) {
        output += str[i];
    }
    return output;
}

var revers_test = revers('123456');

console.log(revers_test); //654321

題目:
寫一個function removeSubArray()
var main = [1,2,3,4,5,6];
var sub = [3,5];
removeSubArray(main, sub) //[1,2,4,6]
要從原本的陣列中移除,而不是另外建立陣列。

function removeSubArray(main, sub) {
    for (i=0; i<=main.length; i++){
        var temp = sub.indexOf(main[i]);

        // remove
        if (temp>=0) {
            main.splice(i, 1);
            i--;
        }
    }
    return main;
}

var remove_test = removeSubArray([1,2,3,4,6,3,3,2], [2,3]);
console.log(remove_test);//[1, 4, 6]

題目:寫一個 Copy function

另外簡單整理一篇《深拷貝 vs 淺拷貝》

var copyThis = {a:10, b:21, c:33};
function copy(o) {
    var copyObj = JSON.parse(JSON.stringify(o));

    copyObj.a = 14;

    console.log(o); // {a: 10, b: 21, c: 33}
    console.log(copyObj); // {a: 14, b: 21, c: 33}

}
copy(copyThis);
先用JSON.stringify()轉成JSON,再JSON.parse()解開,但如果遇到 function 使用JSON.stringify()會發生undefined的殘念。

題目:寫一個 closure
var makeColor = function (color) {
    return function() {
        document.body.style.backgroundColor = color;
    };
};

var paintWindow = makeColor('pink');
paintWindow();

題目:
臉書按讚機制
  • 只有一個人按讚:A likes this
  • 有兩個人按讚:A and B like this
  • 有三個人按讚:A, B and C like this
  • 有四個人以上按讚:A, B and 2 others like this

function displayLike(friends) {
    var msg = ' likes this';
    var output = '';
    const total = friends.length;

    if (total === 1){
        output = friends[1]+msg;
    }

    msg = ' like this';

    if (total === 2){
        output = friends[0]+' and '+friends[1]+msg;
    }
    if (total === 3){
        output = friends[0]+', '+friends[1]+' and '+friends[2]+msg;
    }
    if (total >= 4) {
        output = friends[0] + ', ' + friends[1] + ' and ' + (total - 2) + ' others' + msg;
    }

    console.log(output);
    return output;
}
var friends = ['amy','cindy','Ian','Gina'];
displayLike(friends);

參考資料:
http://blog.techbridge.cc/2017/01/27/interview-review/
http://larry850806.github.io/2016/09/20/shallow-vs-deep-copy/
https://pjchender.blogspot.tw/2016/06/javascriptfunction-constructornew.html
https://pjchender.blogspot.tw/2016/06/javascriptprototypal-inheritance.html