14道javascript变态题目 没有最变态 只有更变态

14道javascript变态题目,没有最变态,只有更变态,假如这14道题目全部能做对,那你去任何一加公司面试前端工程师都没有问题!

第一题:
(function(){
return typeof arguments;
})();
答案是“object”
typeof操作符的结果只能是
"undefined"(对一个未声明的标识符使用也不会报错)
"boolean"
"string"
"number"
"object"(对null也返回这个值)
"function"

第二题:
var f = function g(){ return 23; };
typeof g();
答案是Error
此处g是函数名,然而第一行不是一个函数声明,因此函数名g仅能在该函数内部被访问到,外部访问不到,使用()来调用一个不存在的函数自然报错。

第三题:
(function(x){
delete x;
return x;
})(1);
答案是1
首先,非严格模式下无论怎么(符合语法地)使用delete,总是不会报错;然后,delete在函数内部无法删除传入的参数。(不过可以在全局作用域内删除未经function/var语句声明的变量。)

第四题:
var y = 1, x = y = typeof x;
x;
答案是"undefined"(字符串)
根据JavaScript声明提升的特性以及赋值运算的规则,这段代码可以看作
var y, x;
y = 1;
y = typeof x // 此时y的值是"undefined"(字符串)
x = y
x; //x值为"undefined"字符串

第五题:
(function f(f){
return typeof f();
})(function(){ return 1; });
答案是"number"
一个函数名为f的自执行函数,接收一个函数作为参数。函数f内部的f则指向传入的实参而非函数f自身。因此相当于:
(function f(){
return typeof (function(){ return 1; })();
})();

第六题:
var foo = {
bar: function() { return this.baz; },
baz: 1
};
(function(){
return typeof arguments[0]();
})(foo.bar);
答案是"undefined"
这题应该是想考察this的指向。在ES5下面,判断this的指向,可以一步一步按照下面的流程进行(一旦满足某个判断即结束判断流程,不再考虑之后的情况),而跟函数是在哪里定义、声明的无关:
函数是否是new调用?若是,则this指向新对象
函数是否是bind方法返回的?若是,则this指向指定对象。
函数是否通过apply/call调用?若是,则this指向指定对象。
是否作为对象的方法调用?若是,则this指向该对象
this指向全局
这段代码里,函数作为arguments对象的方法被调用,this指向arguments对象并不存在的baz属性,因此返回“undefined”

第七题:
var foo = {
bar: function(){ return this.baz; },
baz: 1
}
typeof (f = foo.bar)();
答案是"undefined"
首先不要忘了赋值运算“=”也是有返回值的,因此(f = foo.bar)的返回值是foo.bar指向的函数。调用该函数,根据前述this的规则判断,应该是属于第五步的“指向全局”而非第四部“作为某对象的方法调用”(这是很多书里都提到的“this丢失”的陷阱),而全局对象内并无baz属性,因此返回undefined

第八题:
var f = (function f(){ return "1"; }, function g(){ return 2; })();
typeof f;
答案是"number"
逗号除了作为分隔符,也是一个操作符,总是返回最后一项。因此
(function f(){ return "1"; }, function g(){ return 2; })
这个表达式的值是函数g,立刻通过()进行调用后返回数字2

第九题:
var x = 1;
if (function f(){}) {
x += typeof f;
}
x;
答案是"1undefined"
if语句的判断部分内是一个函数f,转化为布尔值为真。(只有""(空字符串)、0、NaN、null、undefined的布尔值是false)。这段代码里的function f(){}并不是函数声明。如何判断是否是函数声明:function这个关键词之前有任何东西,那么这都不是一个函数声明,而是函数表达式。因此全局内并无f这个标识符,代码相当于
var x = 1;
if (true) {
x = 1 + 'undefined';
}
x;

第十题:
var x = [typeof x, typeof y][1];
typeof typeof x;
答案是"string"
又是一个声明提升。这段代码可以看作
var x;
x = [typeof x, typeof y][1]; //此时x值为typeof y的结果:"undefined"(字符串)
typeof typeof x;

第十一题:
(function(foo){
return typeof foo.bar;
})({ foo: { bar: 1 } });
答案是"undefined"
这个没啥,仔细看题就可以了。

第十二题:
(function f(){
function f(){ return 1; }
return f();
function f(){ return 2; }
})();
又是声明提升的问题,相当于
(function f(){
function f(){ return 1; }
function f(){ return 2; }
return f();
})();
值得一提的是function声明和var声明不同,var声明对于重复的声明是忽略的,而function声明则是覆盖。

第十三题:
function f(){ return f; }
new f() instanceof f;
简单地说,使用new操作符时,若调用的函数返回的是一个对象,则相当于这个new操作符一点用也没有。函数f返回的是自身,即一个对象,因此代码相当于
function f(){ return f; }
f instanceof f;
instanceof操作符根据原型链判断一个对象是否是一个构造函数的实例。显然一个函数不可能是自己的实例。所以答案是false

第十四题:
with (function(x, undefined){}) length;
对with语句有一点了解的话,就知道这代码相当于
(function(x,undefined) {}).length
而一个函数对象的length属性是该函数的形参个数,故答案是2

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: