在这里作了套题:贤心 而后错的……不忍直视。 还有一篇很好的介绍函数表达式的文章: (http://www.cnblogs.com/TomXu/archive/2011/12/29/2290308.html)javascript
typeof操做符返回一个字符串,表示未经求值的操做数(unevaluated operand)的类型。 typeof 可能的返回值以下:html
**null ** 注意这个特殊的 typeof null === object.java
常见的面试题中涉及到typeof面试
(function(){ return typeof arguments; })();
返回值为:object
arguments是对象,不是真正的数组,它是一个伪数组,是可使用方括号和整数索引的元素。一般利用Array的原型方式将其转换为数组。 Array.prototype.slice.call(arguments);express
var f = function g(){ return 23; }; typeof g();
Uncaught ReferenceError: g is not defined(…)
由于function g(){ return 23; }是函数表达式,事实上g只是一个名字,不是函数声明。函数其实是绑定到变量f,而不是g。 指定的函数标识符:g通常的用途是:使堆栈跟踪更加清晰,可使用匿名函数递归调用其自身,而不须要使用argument.callee.(注意 ES5 严格模式中禁用)数组
var y = 1, x = y = typeof x; x;
undefined
重写上述代码以下:函数
var y = 1; y = typeof x; var x = y; x;
当执行y = typeof x时,x 尚未被定义,因此y成为字符串”undefined”,而后被分配到x。this
(function f(f){ return typeof f(); })(function(){ return 1; });
“number”
分解以下: 第一部分lua
var baz = function(){ return 1; };
第二部分prototype
(function f(f){ return typeof f(); })(baz);
在这里,函数f接受一个参数是另外一个函数,f函数内部执行这个实参函数而且返回类型 不管是从调用该函数返回,即便参数名称f与函数名冲突,函数接受自己做为本身的参数,而后调用,此时就看谁更具备更高的优先级了,显然,参数的优先级更高,因此实际执行的是
return typeof 1。
var foo = { bar: function(){ return this.baz; }, baz: 1 } typeof (f = foo.bar)(); “undefined”
继续改写一下:
var foo = { bar: function(){ return this.baz; }, baz: 1 } f = foo.bar; typeof f();
把foo.bar存储给f而后调用,因此this在foo.bar引用的是全局对象,因此就没有baz属性了 换句话说foo.bar执行的时候上下文是 foo,可是当 把 foo.bar 赋值给 f 的时候,f 的上下文环境是 window ,是没有 baz 的,因此是 ”undefined” 题目五
var f = (function f(){ return "1"; }, function g(){ return 2; })(); typeof f; “number”
逗号操做符的使用能够很混淆,但这段说明它的行为:
var x = (1, 2, 3); x;
x的值是3,这代表,当你有一系列的组合在一块儿,并由逗号分隔的表达式,它们从左到右进行计算,但只有最后一个表达式的结果保存。因为一样的缘由,这个问题能够改写为减小混乱:
var f = (function g(){ return 2; })(); typeof f;
关于逗号表达式: 原文: http://www.2ality.com/2012/09/expressions-vs-statements.html 译文: http://www.cnblogs.com/ziyunfei/archive/2012/09/16/2687589.html
var x = 1; if (function f(){}) { x += typeof f; } x; “1undefined”
这里有个难点 if 中的 function f(){} 要如何处理? 函数声明的实际规则以下: 函数声明只能出如今程序或函数体内。从句法上讲,它们 不能出如今Block(块)({ … })中,例如不能出如今 if、while 或 for 语句中。由于 Block(块) 中只能包含Statement语句, 而不能包含函数声明这样的源元素。另外一方面,仔细看一看规则也会发现,惟一可能让表达式出如今Block(块)中情形,就是让它做为表达式语句的一部分。可是,规范明确规定了表达式语句不能以关键字function开头。而这实际上就是说,函数表达式一样也不能出如今Statement语句或Block(块)中(由于Block(块)就是由Statement语句构成的)。 假设代码咱们不妨变一下:
var x = 1; if (function(){}) { x += typeof f; } x; var x = 1; x += typeof f; x;
f在这了没有被定义,因此typeof f 是字符串”undefined” ,字符与数字相加结果也是一个字符串, 因此最后的x就是”1undefined”了
(function f(){ function f(){ return 1; } return f(); function f(){ return 2; } })(); 2
若是是一直看下来的话,这个题目应该是比较简单 简单的来讲在执行return以前,函数声明会在任何表达式被解析和求值以前先被解析和求值。 即便你的声明在代码的最后一行,它也会在同做用域内第一个表达式以前被解析/求值, 参考以下例子,函数fn是在alert以后声明的,可是在alert执行的时候,fn已经有定义了
alert(fn()); function fn() { return 'Hello world!'; }
因此题目中函数提高了两次,第二次把第一次覆盖了, 因此 return 后面的 f 是 return 语句的下一条语句声明的函数 f 。 注意自执行函数 (function f (){})(); 中的 f 并无函数提高效果,它是表达式
function f(){ return f; } new f() instanceof f; false
怎样去理解?
new f()
首先这个操做会建立一个新对象并调用构造函数函数这一新的对象做为它的当前上下文对象 简单的说
new f();
依稀记得高级程序设计里面是这么说的:
默认若是没有覆盖这个空对象的话,返回this var a = new Object; a instanceof Object 为 true 咱们在看 f() 返回了 return f; 那么也就是说这个新的对象是是自身,构造函数自己在 new 的过程当中会返回一个表示该对象的实例。 可是函数的返回值覆盖了这个实例,这个new 就形同虚设 果f的形式为 function f(){return this}或function f(){}就不同
var a = new f(); a instanceof f // false
值得注意的是 instanceof 检测的是原型
var x = [typeof x, typeof y][1]; typeof typeof x;
这题目比较简单,注意下返回类型便可 x = [,][1]; 即 x = typeof y = ‘undefind’. typeof 返回的是string类型就能够了 typeof typeof必然就是’string’了.
function(foo){ return typeof foo.bar; })({ foo: { bar: 1 } });
“undefined” 又是一个恶心的题目,纯文字游戏,你们看仔细看 先分解一下
var baz = { foo: { bar: 1 } }; (function(foo){ return typeof foo.bar; })(baz);
去掉函数关联
var baz = { foo: { bar: 1 } }; var foo = baz; typeof foo.bar;
最后,经过替代咱们除去中间变量foo
var baz = { foo: { bar: 1 } }; typeof baz.bar;
因此如今就很清晰了,属性中没有定义baz;它被定义为baz.foo上了,因此结果是:”undefined”