分享一套经典的前端面试题

分享一套经典的前端面试题

/**
 * 用js实现一个类P 包含成员变量a,成员变量b成员函数sum sum输出a与b的和,a,b默认值都为0.实现一个类M,M继承自P,在P的基础上增加成员变量c成员变量函数sum变成a,b,c的和
 */
function P(a,b){
    this.a = a || 0;
    this.b = b || 0;
}
P.prototype.sum = function(){
    return this.a + this.b;
};

function M(a,b,c){
    P.call(this,a,b);
    this.c = c || 0;
}

M.prototype = new P();
M.prototype.constructor = M;

M.prototype.sum = function(){
    return this.a + this.b + this.c;
};

var p = new P(1,2);
var m = new M(1,2,3);
console.log("p.sum()=",p.sum());
console.log("m.sum()=",m.sum());

/**
 * 写出三个不同的this使用场景
 */

// 0. 构造器函数内的this:
//如果函数创建的目的是使用new来调用,并产生一个对象,那么此函数被称为 构造器函数。
// var Niu = function (string) {
//
//     this.name = string;
// };
// 上述的Niu即为一个构造器函数,其内部的this会自动绑定到new所创建的新对象上面。
//
// 1. 对象成员方法内的this:
// 对象的成员方法中的this是对象本身,此时跟其它语言是一致的,但是也有差异,javascript中this到对象的绑定发生在函数调用的时候。
//
// var myObj = {
//
//     value: 0,
//
//     increment: function (inc) {
//
//         this.value += typeof inc === 'number' ? inc : 1;
//
//     }
//
// };
//
// myObj.increment();    //1
//
// myObj.increment(2);   //3

// 2. 普通函数 与 闭包内的this:
//
//     2.1 以普通方式定义的函数中的this:会被自动绑定到全局对象。
// var value = 232;
//
// function toStr()
//
// {
//
//     console.log("%d", this.value);  //232
//
// }
//
//
// 2.2 对象方法中闭包函数的this:
//
//     由2.1可知,在以普通方式定义的函数中的this会被自动绑定到全局对象上,大家应该可以看出闭包函数定义也与普通方式无异,因此他也会被绑定到全局对象上。
//
// value = 10;
var closureThis = {
// value: 0, // acc: function () // { // var helper = function () // { // this.value += 2; // console.log("this.value : %d", this.value); // } // helper(); // } // }; // // closureThis.acc(); //12 // closureThis.acc(); //14 // // var closureThat = { // value: 0, // acc: function () // { // that = this; // var helper = function () // { // that.value += 2; // console.log("that.value : %d", that.value); // } // helper(); // } // }; // // closureThat.acc(); // 2 // closureThat.acc(); // 4 // 从上述输出值可以看出,上述描述的正确性。 // // 3. Apply函数的参数this: // // appy方法允许我们选择一个this值作为第一个参数传递,第二个参数是一个数组,表明可以传递多个参数。 //【场景1】全局环境中的this指向全局对象 // this.a = 10; // alert(a);//10 // b = 20; // alert(this.b);//20 // var c = 30; // alert(this.c);//30 // 【场景2】对象内部函数的this指向调用函数的当前对象 // var a = 10; // var bar = { // a: 20, // test: function(){ // alert(this.a); // } // } // bar.test();//20 // 【场景3】全局环境函数的this指向全局对象 // var a = 10; // function foo(){ // alert(this.a); // } // foo();//10 // 【场景4】匿名函数中的this指向全局对象 // var a = 10; // var foo = { // a: 20, // fn: (function(){ // alert(this.a); // })() // } // foo.fn//10 // 【场景5】setInterval和setTimeout定时器中的this指向全局对象 // var a = 10; // var oTimer1 = setInterval(function(){ // var a = 20; // alert(this.a);//10 // clearInterval(oTimer1); // },100); // 【场景6】eval中的this指向调用上下文中的this // (function(){ // eval("alert(this)");//[object Window] // })(); // function Foo(){ // this.bar = function(){ // eval("alert(this)");//[object Object] // } // } // var foo = new Foo(); // foo.bar(); // 【场景7】构造函数中的this指向构造出的新对象 // function Person(name,age){ // this.name = name; // this.age = age; // this.sayName = function(){ // alert(this.name); // } // } // var p1 = new Person('lily','20'); // p1.sayName();//'lily' // 【场景8】new Function中的this指向全局对象 // (function(){ // var f = new Function("alert(this)"); // f();//[object Window] // })(); // function Foo(){ // this.bar = function(){ // var f = new Function("alert(this)"); // f();//[object Window] // } // } // var foo = new Foo(); // foo.bar(); // 【场景9】apply和call中的this指向参数中的对象 // var a = 10; // var foo = { // a: 20, // fn: function(){ // alert(this.a); // } // }; // var bar ={ // a: 30 // } // foo.fn.apply();//10(若参数为空,默认指向全局对象) // foo.fn.apply(foo);//20 // foo.fn.apply(bar);//30 // 【复合场景1】 // var someone = { // name: "Bob", // showName: function(){ // alert(this.name); // } // }; // var other = { // name: "Tom", // showName: someone.showName // } // other.showName();  //Tom // // //以上函数相当于 // // var other = { // name: "Tom", // showName: function(){ // alert(this.name); // } // } // other.showName();  //Tom // 【复合场景2】 // var name = 2; // var a = { // name: 3, // fn: (function(){ // alert(this.name); // })(), // fn1:function(){ // alert(this.name); // } // } // a.fn;//2[匿名函数中的this指向全局对象] // a.fn1();//3[对象内部函数的this指向调用函数的当前对象] // // 【复合场景3】 // var name = "Bob"; // var nameObj ={ // name : "Tom", // showName : function(){ // alert(this.name); // }, // waitShowName : function(){ // var that = this; // setTimeout(function(){ // that.showName(); // }, 1000); // } // }; // nameObj.waitShowName();//"Tom"[that=this改变this的指向,使this从指向全局变量变化到指向nameObj] // // var name = "Bob"; // var nameObj ={ // name : "Tom", // showName : function(){ // alert(this.name); // }, // waitShowName : function(){ // var that = this;//that指向nameObj // setTimeout(function(){ // (function(){ // alert(this.name); // })(); // }, 1000); // } // }; // nameObj.waitShowName();// 'Bob'[形成匿名函数,this指向全局变量] /** * 写出下面这段代码的执行结果 */ for(var i = 0 ; i < 3 ; i ++){ setTimeout(function(){ console.log(i); },0); } /** * 执行结果: * 3 * 3 * 3 * 原因:js是单程的,会先执行for然后有空闲的时候再执行setTimeout,虽然setTimeout的时间延时为0,还是会缓存等待for循环执行结束之后等有空闲的时候再执行 */ /** * 说出以下函数的作用,并填写空格内容 */ //define (function(window){ function fn(str){ this.str = str; } fn.prototype.format = function(){ var arg = ____; return this.str.replace(____,function(a,b){ return arg[b] || ""; }); }; window.fn = fn; })(window); //use (function(){ var t = new fn('

{1}{2}

'
); console.log(t.format('http://www.baidu.com','BaiDuSecurites','Welcome')); })(); /** * 将字符串中的特定字符用函数的参数来替换 */ //define 这里是一个私有作用域,为了让外面的函数可以访问到fn函数,传入了window对象,并且最终将定义的函数赋值到了window中的fn上了,所以外面可以访问到 (function(window){ function fn(str){ this.str=str; } fn.prototype.format=function(){ var arg=arguments; return this.str.replace(/\{(\d+)\}/ig,function(a,b){ // console.log(a); // console.log(arg); // console.log(b); console.log(arg[b]); return arg[b]||''; }); } window.fn=fn; })(window); //use (function(){ var t=new fn('

{1}{2}

'
); console.log(t.format('http://www.alibaba.com','Alibaba','Welcome')); })(); /** * 用js实现一个Promise,要求支持resolve,reject,done,fail,then,always. */ // state: 当前执行状态,有pending、resolved、rejected3种取值 // // done: 向doneList中添加一个成功回调函数 // // fail: 向failList中添加一个失败回调函数 // // then: 分别向doneList和failList中添加回调函数 // // always: 添加一个无论成功还是失败都会调用的回调函数 // // resolve: 将状态更改为resolved,并触发绑定的所有成功的回调函数 // // reject: 将状态更改为rejected,并触发绑定的所有失败的回调函数 // // when: 参数是多个异步或者延迟函数,返回值是一个Promise兑现,当所有函数都执行成功的时候执行该对象的resolve方法,反之执行该对象的reject方法 // 下面是我的具体实现过程: var Promise = function() { this.doneList = []; this.failList = []; this.state = 'pending'; }; Promise.prototype = { constructor: 'Promise', resolve: function() { this.state = 'resolved'; var list = this.doneList; for(var i = 0, len = list.length; i < len; i++) { list[0].call(this); list.shift(); } }, reject: function() { this.state = 'rejected'; var list = this.failList; for(var i = 0, len = list.length; i < len; i++){ list[0].call(this); list.shift(); } }, done: function(func) { if(typeof func === 'function') { this.doneList.push(func); } return this; }, fail: function(func) { if(typeof func === 'function') { this.failList.push(func); } return this; }, then: function(doneFn, failFn) { this.done(doneFn).fail(failFn); return this; }, always: function(fn) { this.done(fn).fail(fn); return this; } }; function when() { var p = new Promise(); var success = true; var len = arguments.length; for(var i = 0; i < len; i++) { if(!(arguments[i] instanceof Promise)) { return false; } else { arguments[i].always(function() { if(this.state != 'resolved'){ success = false; } len--; if(len == 0) { success ? p.resolve() : p.reject(); } }); } } return p; } // Improve // 目前只是实现了Promise的基础功能,但仍然还有无法处理的情况,例如要实现3个或3个以上的异步请求的串行,目前我的Promise没有办法支持new Promise(A).then(B).then(C)这样的形式,jQuery在1.7的版本中为Deferred(Promise)对象实现了pipe函数,可以通过这个函数实现上述功能,代码为$.Deferred(A).pipe(B).then(C),我尝试去读了jQuery这部分的代码,但是没能读懂,希望有大神能够给一些实现思路 /** * 两个顺序排列的数组A和B,求B数组是否为A数组的子集。(数组内可能有重复数字) */ var A = [1,2,2,2,2,3,5,5,5,6,8,9,9,9]; var B = [1,2,3]; /** * A,B,分别是两个顺序排列的数组,判断B是否为A的子集 * @param _A * @param _B * @returns {boolean} */ function isASon(_A,_B){ var flag = false; if(_A instanceof Array && _B instanceof Array){ var i = 0,j = 0 ; while(i < _B.length){ flag = false; for( ; j < _A.length ; j ++){ if(_B[i] === _A[j] ){ flag = true; break; } } if(flag){ i ++; }else{ return false; } } if(flag){ return true ; }else{ return false; } } } isASon(A,B);

你可能感兴趣的:(前端面试题)