撩课-Web大前端每天5道面试题-Day17
程序员文章站
2022-03-24 13:37:12
1.apply, call和bind有什么区别? 2.defineProperty, hasOwnProperty, isEnumerable都是做什么用的? 3. js常用设计模式的实现思路,单例,工厂,代理,装饰,观察者模式等? 4.promise只有2个状态,成功和失败,怎么让一个函数无论成功 ......
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() 返回某个字符串对象的原始值。