一套有趣的 javascript题.

原题地址: http://www.cnblogs.com/ziyunfei/archive/2012/10/04/2711370.html

有兴趣的同学可以去做一做.


 

本帖为,本人给出的答案贴.并非原作者给出答案. 仅供参考. 欢迎讨论.

 

1. TypeError
原因: Function.prototype.toString不是一个通用方法,这意味着,该方法被调用时,其this,如果不是一个函数对象,则要抛出TypeError异常.

2. TypeError.
原因:
new String(expression);
是需要对expression 解释执行,并对其结果进行 内部ToString运算. 其调用栈为 ToString(value) -> ToPrimitive(value, hint string)
ToPrimitive(value) 这里,因参数为非原始类型(是个对象),又因hint string,所以会优先调用目标对象的toString方法,如果结果仍然不是一个原始类型,则再次去调用其valueOf方法,如果返回结果仍然不是一个原始类型则抛出TypeError异常.因为题中.参数是个对象,且valueOf,和toString都被重写,且都不返回一个原始类型.so ...异常是必然的.


3. string
因为"+"加发,对于对于两个运算元,是直接调用ToPrimitive的,而Date类型进行ToPrimitive运算的过程.没有明确指明hint .那么就视为 hint string. 所以优先调用其toString方法.自然是字符串结果.至于toString的输出内容则是依赖实现的.但总是要返回一个string就对了. 啥时候会有hint Number? new Date - new Date 就会了. 区别在于 "-" 减法会对两个运算元,调用内部抽象运算 ToNumber. 则会导致调用ToPrimitive时,显式提供 hint Number 作为参数.

4. undefined
似乎没啥好说的, void 运算符,的运算过程很明确. 对运算元解释执行的结果求值后. 直接返回undefined . 这也是为啥我反对使用 void function(){}(); 作为IIFE的用法.因为void并不像很多人认为的那样, 比其他一些IIFE的写法,少一次运算.真正少一次运算的是分组运算符.也就是最古老的(function(){}()) .

 

5. [object Object]
似乎没啥好说的. new F 肯定 object ...

6. RangeError
简单来说js的数组要求length 的范围在0 - 2的32次方-1 之间.

那么对于 [].length = xxx 这本质是以'length'为参数,调用数组对象自身的 [PUT]方法, 并把xxx作为value. 这是个过程中会调用
ToUint32(xxx) 然后再去与 ToNumber(xxx) 的结果做对比.如果不相等.则抛出RangeError. 内部运算 ToUint32 是不会返回负数的.所以与ToNumber的结果一定不同. so ...


7. false.
这道题,我甚至觉得根本无需解释的样子..
位运算只对 2的32次方以内的数字有效. 所以D已经越界了. 越界后 D | D 的结果, 就不可能与其自身会相等了.


8. _string__string_
String.prototype.replace 是一个异常复杂的方法.
这里唯一要提醒的就是那组替换字符:
$’ 替换为匹配位之后的子串

有兴趣可以看下这个表:

$$ $

$& The matched substring.

$‘ The portion of string that precedes the matched substring.

$’ The portion of string that follows the matched substring.

$n The nth capture, where n is a single digit 1-9 and $n is not followed by a decimal
digit. If n≤m and the nth capture is undefined, use the empty string instead. If n>m,
the result is implementation-defined.

$nn The nnth capture, where nn is a two-digit decimal number 01-99. If nn≤m and the
nnth capture is undefined, use the empty string instead. If nn>m, the result is
implementation-defined

 


9. function
只要记住一点
eval code 在ES3 里的定义十分简单. 内部依然有函数声明的概念. 所以这个结果大家应该不会选错的样子.


10. 说实话,如果严格考虑标准,而不是我们熟知的那些ES3引擎实现的话.选项中没有正确答案.

原因如下 :
debugger; ES3是作为关键字中的预保留字定义的. 所以在ES3的引擎中直接使用,本来应该抛出异常的.只不过即使IE6时代的jscript引擎,(ES3)引擎也都实现了这玩意. ES5,把他正式定义了.
所以, 仅从标准角度来看.答案应该是,确认抛异常,而不是可能抛异常.只是ES3的浏览器的实现几乎都与ES5的规范一致.所以其实ES5的规范,在这里是从善如流.即当你有一个调试器存在时,则进入断点.否则,无视这玩意..

 

 

posted @ 2012-10-04 15:17 Franky 阅读(...) 评论(...) 编辑 收藏