1. 程式人生 > >Web大前端每天5道面試題

Web大前端每天5道面試題

1.apply, call和bind有什麼區別?
複製程式碼
三者都可以把一個函式應用到其他物件上,注意不是自身物件.
apply,call是直接執行函式呼叫,bind是繫結,執行需要再次呼叫.
apply和call的區別是apply接受陣列作為引數,而call是接受逗號分隔的無限多個引數列表.

程式碼如下:
    function Person() {
    }
    Person.prototype.sayName() { alert(this.name); }

    var obj = {name: 'michaelqin'}; // 注意這是一個普通物件,它不是Person的例項
1) apply Person.prototype.sayName.apply(obj, [param1, param2, param3]); 2) call Person.prototype.sayName.call(obj, param1, param2, param3); 3) bind var liaoke = Person.prototype.sayName.bind(obj); liaoke ([param1, param2, param3]); // bind需要先繫結,再執行 liaoke (param1, param2, param3); //
bind需要先繫結,再執行 複製程式碼 2.defineProperty, hasOwnProperty, isEnumerable都是做什麼用的? Object.defineProperty(obj, prop, descriptor)用來給物件定義屬性, 有value,writable,configurable,enumerable,set/get等.hasOwnProerty用於檢查某一屬性是不是存在於物件本身,繼承來的父親的屬性不算. isEnumerable用來檢測某一屬性是否可遍歷,也就是能不能用for..in迴圈來取到. 3. js常用設計模式的實現思路,單例,工廠,代理,裝飾,觀察者模式等? 複製程式碼
1) 單例: 任意物件都是單例,無須特別處理 var obj = {name: 'michaelqin', age: 30}; 2) 工廠: 就是同樣形式引數返回不同的例項 function Person() { this.name = 'Person1'; } function Animal() { this.name = 'Animal1'; } function Factory() {} Factory.prototype.getInstance = function(className) { return eval('new ' + className + '()'); } var factory = new Factory(); var obj1 = factory.getInstance('Person'); var obj2 = factory.getInstance('Animal'); console.log(obj1.name); // Person1 console.log(obj2.name); // Animal1 3) 代理: 就是新建個類呼叫老類的介面,包一下 function Person() { } Person.prototype.sayName = function() { console.log('michaelqin'); } Person.prototype.sayAge = function() { console.log(30); } function PersonProxy() { this.person = new Person(); var that = this; this.callMethod = function(functionName) { console.log('before proxy:', functionName); that.person[functionName](); // 代理 console.log('after proxy:', functionName); } } var pp = new PersonProxy(); pp.callMethod('sayName'); // 代理呼叫Person的方法sayName() pp.callMethod('sayAge'); // 代理呼叫Person的方法sayAge() 4) 觀察者: 就是事件模式,比如按鈕的onclick這樣的應用. function Publisher() { this.listeners = []; } Publisher.prototype = { 'addListener': function(listener) { this.listeners.push(listener); }, 'removeListener': function(listener) { delete this.listeners[listener]; }, 'notify': function(obj) { for(var i = 0; i < this.listeners.length; i++) { var listener = this.listeners[i]; if (typeof listener !== 'undefined') { listener.process(obj); } } } }; // 釋出者 function Subscriber() { } Subscriber.prototype = { 'process': function(obj) { console.log(obj); } }; // 訂閱者 var publisher = new Publisher(); publisher.addListener(new Subscriber()); publisher.addListener(new Subscriber()); publisher.notify({name: 'michaelqin', ageo: 30}); // 釋出一個物件到所有訂閱者 publisher.notify('2 subscribers will both perform process'); // 釋出一個字串到所有訂閱者 複製程式碼 4.promise只有2個狀態,成功和失敗,怎麼讓一個函式無論成功還是失敗都能被呼叫? 複製程式碼 使用promise.all() Promise.all方法用於將多個Promise例項,包裝成一個新的Promise例項。 Promise.all方法接受一個數組作為引數,數組裡的元素都是Promise物件的例項, 如果不是,就會先呼叫下面講到的Promise.resolve方法,將引數轉為Promise例項,再進一步處理。 (Promise.all方法的引數可以不是陣列,但必須具有Iterator介面,且返回的每個成員都是Promise例項。) 示例: var p =Promise.all([p1,p2,p3]); p的狀態由p1、p2、p3決定,分為兩種情況。 當該數組裡的所有Promise例項都進入Fulfilled狀態:Promise.all**返回的例項才會變成Fulfilled狀態。 並將Promise例項陣列的所有返回值組成一個數組,傳遞給Promise.all返回例項的回撥函式**。 當該數組裡的某個Promise例項都進入Rejected狀態: Promise.all返回的例項會立即變成Rejected狀態。 並將第一個rejected的例項返回值傳遞給Promise.all返回例項的回撥函式。 複製程式碼 5.說說字串常用的十個函式? 複製程式碼 charAt() 返回在指定位置的字元。 concat() 連線字串。 fromCharCode() 從字元編碼建立一個字串。 indexOf() 檢索字串。 match() 找到一個或多個正則表示式的匹配。 replace() 替換與正則表示式匹配的子串。 search() 檢索與正則表示式相匹配的值。 slice() 提取字串的片斷,並在新的字串中返回被提取的部分。 split() 把字串分割為字串陣列。 substr() 從起始索引號提取字串中指定數目的字元。 substring() 提取字串中兩個指定的索引號之間的字元。 toLocaleLowerCase() 把字串轉換為小寫。 toLocaleUpperCase() 把字串轉換為大寫。 toLowerCase() 把字串轉換為小寫。 toUpperCase() 把字串轉換為大寫。 toString() 返回字串。 valueOf() 返回某個字串物件的原始值。