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() 返回某个字符串对象的原始值。
复制代码