[筆記] Javascript 面試題

日本嵐山

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

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

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

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

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

如果沒有添加 new 呢?
  1. var myDad = person('Harry', 51, 'M');
  2. var myMom = person('Amy', 50, 'F');
  3.  
  4. console.log(myDad); //undefined
  5. console.log(myMom); //undefined
因為 JavaScript 不知道你是要執行這個程式還是要根據這個function去建立object,因次最後回傳 undefined 的結果。

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

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

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

寫法:
  1. var myFriend = Object.create(person);
  2. // 修改內容
  3. myFriend.nickname = 'Jhon';
  4. myFriend.years = 40;
  5. myFriend.gender = 'M';
  6.  
  7. // 結果
  8. // Function {}
  9. // gender:"M"
  10. // nickname:"Jhon"
  11. // years:40

若不支援 Object.create()呢?那就寫一個 Polyfill吧
  1. function inherit(o) {
  2. if(!Object.create){
  3. if(arguments.length>1) {
  4. //此時無法使用第二引數
  5. throw new Error('Object.create implementation only accepts the first parameter');
  6. }
  7. //宣告一個新的物件
  8. function F() {}
  9. //把原本的建構式塞進 F
  10. F.prototype = o;
  11. //回傳
  12. return new F();
  13. } else {
  14. return Object.create(o);
  15. }
  16. }
  17.  
  18. //建立一個物件
  19. var dorasMom = inherit(person);
  20.  
其實,本質上就用new()代替,我想之後可以探討一下關於inherit。

題目:字串反轉
  1. function revers(str) {
  2. var output = "";
  3. const len = str.length;
  4. for (i=len-1; i>=0; i--) {
  5. output += str[i];
  6. }
  7. return output;
  8. }
  9.  
  10. var revers_test = revers('123456');
  11.  
  12. console.log(revers_test); //654321

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

  1. function removeSubArray(main, sub) {
  2. for (i=0; i<=main.length; i++){
  3. var temp = sub.indexOf(main[i]);
  4.  
  5. // remove
  6. if (temp>=0) {
  7. main.splice(i, 1);
  8. i--;
  9. }
  10. }
  11. return main;
  12. }
  13.  
  14. var remove_test = removeSubArray([1,2,3,4,6,3,3,2], [2,3]);
  15. console.log(remove_test);//[1, 4, 6]

題目:寫一個 Copy function

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

  1. var copyThis = {a:10, b:21, c:33};
  2. function copy(o) {
  3. var copyObj = JSON.parse(JSON.stringify(o));
  4.  
  5. copyObj.a = 14;
  6.  
  7. console.log(o); // {a: 10, b: 21, c: 33}
  8. console.log(copyObj); // {a: 14, b: 21, c: 33}
  9.  
  10. }
  11. copy(copyThis);
先用JSON.stringify()轉成JSON,再JSON.parse()解開,但如果遇到 function 使用JSON.stringify()會發生undefined的殘念。

題目:寫一個 closure
  1. var makeColor = function (color) {
  2. return function() {
  3. document.body.style.backgroundColor = color;
  4. };
  5. };
  6.  
  7. var paintWindow = makeColor('pink');
  8. paintWindow();

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

  1. function displayLike(friends) {
  2. var msg = ' likes this';
  3. var output = '';
  4. const total = friends.length;
  5.  
  6. if (total === 1){
  7. output = friends[1]+msg;
  8. }
  9.  
  10. msg = ' like this';
  11.  
  12. if (total === 2){
  13. output = friends[0]+' and '+friends[1]+msg;
  14. }
  15. if (total === 3){
  16. output = friends[0]+', '+friends[1]+' and '+friends[2]+msg;
  17. }
  18. if (total >= 4) {
  19. output = friends[0] + ', ' + friends[1] + ' and ' + (total - 2) + ' others' + msg;
  20. }
  21.  
  22. console.log(output);
  23. return output;
  24. }
  25. var friends = ['amy','cindy','Ian','Gina'];
  26. 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