17-撩課大前端-面試寶典-第十七篇
阿新 • • 發佈:2018-12-19
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() 返回某個字串物件的原始值。