JavaScript之typeof

2016/07/29 13:03
阅读数 20

在这里做了套题:贤心 然后错的……不忍直视。 还有一篇很好的介绍函数表达式的文章: (http://www.cnblogs.com/TomXu/archive/2011/12/29/2290308.html)

typeof操作符返回一个字符串,表示未经求值的操作数(unevaluated operand)的类型。 typeof 可能的返回值如下:

输入图片说明

**null ** 注意这个特殊的 typeof null === object.

常见的面试题中涉及到typeof

题目一

(function(){ 
  return typeof arguments; 
})();
返回值为:object 

arguments是对象,不是真正的数组,它是一个伪数组,是可以使用方括号和整数索引的元素。通常利用Array的原型方式将其转换为数组。 Array.prototype.slice.call(arguments);

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。

题目三

(function f(f){ 
  return typeof f(); 
})(function(){ return 1; });
“number”

分解如下: 第一部分

var baz = function(){ return 1; }; 

第二部分

(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(); 

依稀记得高级程序设计里面是这么说的:

  1. 创建空对象。
  2. 将类的prototype中的属性和方法复制到实例中。
  3. 将第一步创建的空对象做为类的参数调用类的构造函数

默认如果没有覆盖这个空对象的话,返回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”

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部