前端工程师面试题JavaScript部分(第三季)
请定义这样一个函数function repeat (func, times, wait) {} 这个函数能返回一个新函数,比如这样用 var repeatedFun = repeat(alert, 10, 5000),调用这个 repeatedFun ("hellworld") 会alert十次 helloworld, 每次间隔5秒
function repeatFun(fn,times,wait){ var i=0; var handle = setInterval(function(){ fun.apply(null,arguments); if(i==9){ clearInterval(handle); }; i++; },wait) } function fun(){ console.log('hello world') } repeatFun(fun,10,100)
console代替了alert,而且没有返回函数,闭包一下即可
function repeat (func, times, wait) { //不用匿名函数是为了方便调试 function repeatImpl(){ var handle, _arguments = arguments, i = 0; handle = setInterval(function(){ i = i + 1; //到达指定次数取消定时器 if(i === times){ clearInterval(handle); return; } func.apply(null, _arguments); },wait); } return repeatImpl; } //测试用例 var repeatFun = repeat(alert, 4, 3000); repeatFun("hellworld");
第二题
写一个函数stringconcat, 要求能var result1 = stringconcat("a", "b") result1 = "a+b",var stringconcatWithPrefix = stringconcat.prefix("hellworld");var result2 = stringconcatWithPrefix("a", "b") result2 = "hellworld+a+b",此题需要静态方法的思路才能解;
第三题
function Foo() { getName = function () { alert (1); }; return this; } Foo.getName = function () { alert (2);}; Foo.prototype.getName = function () { alert (3);}; var getName = function () { alert (4);}; function getName() { alert (5);} //答案: Foo.getName();//2首先访问静态属性 getName();//4访问变量声明提前 Foo().getName();//1
getName();//1
new Foo.getName();//2 new Foo().getName();//3 new new Foo().getName();//3
其中知识点
console.log('x' in window);//true不管是不是字符串,就是当变量用 var x; x = 0; 衍生的if("a" in window){ var a = 10; } console.log(a);
关于变量声明提前的
var x; function x(){} console.log(x); x=1; //上题中执行顺序应该是这样,被覆盖了x的属性
最终执行的顺序是
function Foo() { getName = function () { alert (1); }; return this; } var getName;//只提升变量声明 function getName() { alert (5);}//提升函数声明,覆盖var的声明 Foo.getName = function () { alert (2);}; Foo.prototype.getName = function () { alert (3);}; getName = function () { alert (4);};//最终的赋值再次覆盖function getName声明
getName();//最终输出4
挨个解答:
第一问:
Foo.getName();静态属性,返回2
第二问
getName();变量声明提前,函数声明提前,函数覆盖变量声明4
第三问
Foo().getName();//执行第一个函数返回的this
Foo函数中赋值一个全局变量 getName=function(){alert(1)}
当前作用域没有getName,那么向上寻找也就是window,覆盖外面的getName的定义
这就是污染了全局变量了,this也指向了window,相当于window.getName
第四问
直接调用getName(),全局变量已经被污染了
下面三问涉及运算符优先级
圆括号()>成员访问>new带参数列表>函数调用>new不带参数列表>递增递减>逻辑运算符>一元加法减法>typeof>算数>位移>比较>in,instance>条件,赋值,逗号
第五问
new Foo.getName(); //相当于 new(Foo.getName)(),这里注意运算符优先级,new一个(Foo.getName)2
第六问
(new Foo()).getName();
//关于返回值的问题
构造函数返回值可以没有返回值也可以没有,undifined,有返回值的时候检查是不是引用类型,
是基本类型等于undefined,实例里返回实例化对象
是引用类型的时候返回undefined,实例返回这个引用类型
此处返回了this是实例化对象,没有getName属相,通过原型链找到构造函数的原型对象,3
第七问
new((new Foo().getName)();//3