来源地址:

http://dmitrysoshnikov.com/ecmascript/the-quiz/#q1

另一篇帖子 看看国外的javascript题目,你能全部做对吗?

http://www.cnblogs.com/aaronjs/p/3172112.html

答案都是自己总结的,毕竟是人肉解释器,解释不一定完全正确,如有不对欢迎大家指出!

题目1. 结果是什么?

typeof typeof(null)
  • “undefined”
  • SyntaxError
  • “string”
  • “object”
  • TypeError

答案"string"

这个是10个中最简单的问题了
typeof typeof 的结果总是"string" 测试结果
typeof({})
"object" typeof([])
"object" typeof(1)
"number" typeof(null)
"object" 在本例中,typeof(null) 返回“object”

题目2. 下面的检测是否等价?

typeof foo == 'undefined'
typeof foo === 'undefined'
  • Yes
  • No

答案Yes 

这里就是全等与==的区别了
==, 两边值类型不同的时候,要先进行类型转换,再比较。
===,不做类型转换,类型不同的一定不等 一个决定性的因素,因为最终在每个比较来比较去的是两个字符串
当比较两个字符串,== 操作符不做任何类型的转化
,因此这两个比较将始终返回相同的结果。

题目3. 结果是什么?

100['toString']['length']
  • 100
  • 3
  • 1
  • 8
  • 0
  • SyntaxError

这个估计好多人想不通了

JavaScript 中所有变量都是对象,除了两个例外 null 和 undefined

false.toString(); // 'false'
[1, 2, 3].toString(); // '1,2,3'
function Foo(){}
Foo.bar = 1;
Foo.bar; //

一个常见的误解是数字的字面值(literal)不是对象。这是因为 JavaScript 解析器的一个错误, 它试图将点操作符解析为浮点数字面值的一部分。

2.toString(); // 出错:SyntaxError

例如以下这种就OK

true.toString()
"true" false.toString()
"false" 01.toString()
"1" 0x20.toString()
"32"

true.toString()、false.toString()、02.toString()、 0x20.toString()都是可以的

我仔细查了下,网上大多给的解释

2.toString()出错是因为解释器读到“2. ”不知道这个“点”究竟该作为小数点还是“.”操作符, 或者也就是说在这里产生了一个“shift-shift conflit”

有很多变通方法可以让数字的字面值看起来像对象

2..toString(); // 第二个点号可以正常解析
2 .toString(); // 注意点号前面的空格
(2).toString(); // 2先被计算

访问100['toString']的length返回toString方法形参个数;

换个

(function(a,b){
//输出2
})['length']
fn = {
f : function(a,b,c){
//
}
}; fn.f['length']

有长度属性的函数,这个长度就是用来计算多个参数的,

可以分解为

100['toString'].length

由于toString是个方法,所以它length属性返回的是toString的形参个数,而toString方法可以接收一个radix(基数)作为形参(比如:toString(2),返回该数值的二进制,16则代表16进制),所以最终返回结果是1。

function toString( [radix : Number] ) : String

radix 可选项。为将数字值转换为字符串指定一个基数。此值仅用于数字。

所以当数字调用toString的时候,会有一个参数radix,其它的比如:Function、Array、String这些调用的话,结果会是 0

刚才上面的100['toString']['length']为什么不分解成100.toString.length?

这是是由于100后面的.是小数点之后是小数部分,从而导致语法错误

解决的方法也说了

100..toString.length
1

参考资料

http://www.dengpeng.org/archives/615

题目4:结果是什么?

var a = (1,5 - 1) * 2
  • 0.999999999
  • 1
  • 0.5
  • 8
  • -0.5
  • 4

这里主要是理解这个 逗号操作符了

在for循环中,增量表达式

j = 10;
for (i = 0; i <5; i++, j++) {
k = i + j;
}
i j k
0 10 10
1 11 12
2 12 14
3 13 16
4 14 18

允许多个表达式被当作单个表达式,所以这两个变量可以递增。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comma_Operator

当有一个包含一个或多个逗号表达式,表达式的值等于最后一个值

var a = (1,2,3,4)   //

* 逗号操作符的最佳用途是定义多个变量和示例使用这里是绝对不推荐的

答案呼之欲出了就是8,

题目5 结果是什么?

var x = 10;
var foo = {
x: 20,
bar: function () {
var x = 30;
return this.x;
}
}; console.log(
foo.bar(), // 1.
(foo.bar)(), // 2.
(foo.bar = foo.bar)(), // 3.
(foo.bar, foo.bar)() // 4.
);
  • 20, 20, 20, 20
  • 20, 20, 10, 10
  • 20, 20, 20, 10
  • 20, 20, 10, 30
  • 20, 10, 10, 10
  • 20, 10, 30, SyntaxError

我们一句一句的分解

foo.bar()

这个很简单,直接调用bar 方法,此时的上下文就是foo对象,所以this.x = 20  return 的结果也就是20了

(foo.bar)()

我们看看括号的定义 ECMA语言规范

11.1.6 The Grouping Operator

The production PrimaryExpression : ( Expression ) is evaluated as follows:

    1. Evaluate Expression. This may be of type Reference.
2. Return Result(1). NOTE This algorithm does not apply GetValue to Result(1). The principal
motivation for this is so that operators such as delete and typeof
may be applied to parenthesised expressions.

引用类型的值与函数上下文中的this值如何相关?——从最重要的意义上来说。 一个函数上下文中确定this值的通用规则如下:

在一个函数上下文中,this由调用者提供,由调用函数的方式来决定。如果调用括号()的左边是引用类型的值,this将设为引用类型值的base对象(base object),在其他情况下(与引用类型不同的任何其它属性),这个值为null。不过,实际不存在this的值为null的情况,因为当this的值为null的时候,其值会被隐式转换为全局对象。注:第5版的ECMAScript中,已经不强迫转换成全局变量了,而是赋值为undefined。

这是对组操作符的描述,说明得到的结果是一个 Reference 引用类型

alert( foo.bar === (foo.bar) )   //true

关于引用类型的解释,参考

http://dmitrysoshnikov.com/

(foo.bar = foo.bar)(),

这一题我也做错了,呵呵

查了查资料,我们先看看

var foo = {
bar: function () {
alert(this);
alert(this === foo);
}
};
 

foo.bar(); // foo, true

var exampleFunc = foo.bar;

alert(exampleFunc === foo.bar); // true

// 再一次,同一个function的不同的调用表达式,this是不同的
exampleFunc(); // global, false

可见将foo.bar的引用赋给一个变量,在执行的时候,这个this的指向就被改变了

重点(=)赋值是如何处理的?

不懂就翻规范呗,又去找找ECMA语言规范

11.13.1 Simple Assignment (= )
The production AssignmentExpression : LeftHandSideExpression = AssignmentExpression is evaluated as follows: 1. Evaluate LeftHandSideExpression. 2. Evaluate AssignmentExpression. 3.Call GetValue(Result(2)). 4.Call PutValue(Result(1), Result(3)). 5.Return Result(3).
8.7.2 PutValue(V, W)

1. If Type(V) is not Reference, throw a
ReferenceError exception.
2. Call GetBase(V).
3. If Result(2) is null, go to step 6.
4. Call the [[Put]] method of Result(2), passing GetPropertyName(V)
for the property name and W for the value.
5. Return.
6. Call the [[Put]] method for the global object, passing
GetPropertyName(V) for the property name and W for the value.
7. Return.

我也没有看太明白, 还要慢慢消化,但是大体的定义

赋值运算符调用了GetValue方法。返回的结果是函数对象(但不是引用类型),这意味着this设为null,结果是global对象

语句返回的是 foo.bar 的函数值

因此,赋值操作符返回的是「值(Value)」而不是「引用(Reference)」。

因为函数体需要 this 值获取 x 属性的值,那么接下来我们考虑改函数时调用时的上下文作用域以及背后的具体流程。 尤其注意第七条规则

...
6. If Type(Result(1)) is Reference, Result(6) is GetBase( Result(1)).
Otherwise, Result(6) is null.
7. If Result(6) is an activation object, Result(7) is null. Otherwise,
Result(7) is the same as Result(6).
8. Call the [[Call]] method on Result(3), providing Result(7) as
the this value and providing the list Result(2) as the
argument values.

那么在这种情况下,GetBase 操作实际上返回的是 null,因此此条语句函数执行的作用域为 global ,在浏览器中也就是 window 。

(foo.bar = foo.bar)()

那么,上面的语句中我们可以得知

  1. Grouping Operator 中的赋值语句返回的是 foot.bar 的函数值(「Value」)
  2. 该函数执行的上下文作用域为 window

找了几篇相关文章具体参考:

http://www.w3.org/html/ig/zh/wiki/ES5/%E8%A1%A8%E8%BE%BE%E5%BC%8F

http://www.cnblogs.com/TomXu/archive/2012/01/17/2310479.html

(foo.bar, foo.bar)()

逗号运算符和逻辑运算符(OR)调用了GetValue 方法,相应地,我们失去了引用而得到了函数。并再次设为global。


我们似乎可以总结一下:

JavaScript 是弱类型语言,这就意味着,等于操作符会为了比较两个值而进行强制类型转换

两个等号组成:==

""           ==   "0"           // false
0 == "" // true
0 == "0" // true
false == "false" // false
false == "0" // true
false == undefined // false
false == null // false
null == undefined // true
" \t\r\n" == 0 // true

严格等于操作符由个等号组成:===

""           ===   "0"           // false
0 === "" // false
0 === "0" // false
false === "false" // false
false === "0" // false
false === undefined // false
false === null // false
null === undefined // false
" \t\r\n" === 0 // false

== 被广泛认为是不好编程习惯的主要原因, 由于它的复杂转换规则,会导致难以跟踪的问题。

此外,强制类型转换也会带来性能消耗,比如一个字符串为了和一个数字进行比较,必须事先被强制转换为数字。

关于Object.prototype.toString方法的原理参考

https://developer.mozilla.org/zh-CN/docs/JavaScript/Reference/Global_Objects/Object/toString

http://www.cnblogs.com/ziyunfei/archive/2012/11/05/2754156.html

后面还有5道题,楼主要深思熟虑才行…

JS越学越谦卑….

后面还有5道题,楼主要深思熟虑才行…

JS越学越谦卑….

后面还有5道题,楼主要深思熟虑才行…

JS越学越谦卑….

还有5道题,需要深思熟虑了...

PS:JS越学越谦卑........

试试看 ? 离奇古怪的javascript题目的更多相关文章

  1. 看看国外的javascript题目,你能全部做对吗?(分享)

    本文转自@Aaron的博客,拿过来分享一下.原文:看看国外的javascript题目,你能全部做对吗? 题目一: (function(){ return typeof arguments; })(); ...

  2. 容易出错的JavaScript题目集锦

    容易出错的JavaScript题目集锦 1.typeof(null) 会得到什么?object,在JavaScript中null被认为是一个对象. 2.下列代码将输出控制台的是什么?为什么? 1234 ...

  3. 汤姆大叔 javascript 系列 第20课 最后的5到javascript题目

    博客链接:http://www.cnblogs.com/TomXu/archive/2012/02/10/2342098.html 原题: 大叔注:这些题目也是来自出这5个题目的人,当然如果你能答对4 ...

  4. 看看国外的javascript题目,你能全部做对吗?

    叶小钗 的博客最近都在讨论面试题目 正好以前也看过一篇,就借花献佛拿出来分享一下 http://perfectionkills.com/javascript-quiz/ 附带了自己的理解,答案有争议的 ...

  5. 我觉得有意思的JavaScript题目(01-05更新中)

    对于以下js题目均来至于网络中.有的来至于文章之中,有的也许来至于问答题型中.如果您有更好的问题解释,请留言交流! 1.相关问题描述:到底该怎么去理解闭包? 代码片段A !function(){ va ...

  6. JavaScript 题目破解过程与解析

    题目来源 https://www.hackthissite.org/missions/javascript/ HackThisSite JavaScript mission 1-7 1 我先尝试输入  ...

  7. 看看这些JavaScript题目你会做吗?

    题目1 咋一看这题目,还以为答案选择B呢,其实正确答案为D,知道原因吗?接着往下看 map对数组的每个元素调用定义的回调函数并返回包含结果的数组,咋一看还以为它会像如下这样执行: function t ...

  8. TOM大叔的几道Javascript题目与解答

    几道JS题目 之前没有深入研究js语言,最近几年前端越来越工程化,需要扎实的js基础,看到博客园上有很多大牛分享JS学习文章,幸运看到tom大叔的blog,抽时间潜心学习了其文章,遇到到其出的几道题目 ...

  9. 分享一道我认为非常有思考价值JavaScript题目

    这是一道综合性的题目,如果你能快速清晰的分析整理出来,那我相信你对JavaScript是有一定的理解的了.我会先将题目的图片截取出来,供大家思考,在结尾在给出我的分析过程和答案,作个总结. 好,废话不 ...

随机推荐

  1. windows系统时间(SYSTEMTIME)

    GetSystemTime函数获得当前的UTC时间,GetLocalTime获得当前的本地时间 UTC是协调世界时(Universal Time Coordinated)英文缩写,是由国际无线电咨询委 ...

  2. JAVA集合类型详解

    一.前言 作为java面试的常客[集合类型]是永恒的话题:在开发中,主要了解具体的使用,没有太多的去关注具体的理论说明,掌握那几种常用的集合类型貌似也就够使用了:导致这一些集合类型的理论有可能经常的忘 ...

  3. Android 利用RecyclerView.Adapter刷新列表中的单个view问题

    首先使用RecyclerView的adapter继承:RecyclerView.Adapter public class OrderListAdapter extends RecyclerView.A ...

  4. apache flink 入门

    配置环境 包括 JAVA_HOME jobmanager.rpc.address jobmanager.heap.mb 和 taskmanager.heap.mb taskmanager.number ...

  5. linux常用命令总结

    du -sh * 当前目录下所有文件占用空间大小,df  空间占用 top 资源使用情况 M 根据驻留内存大小进行排序 tail 1.tail -f filename说明:监视filename文件的尾 ...

  6. centos 创建swap 交换分区

    阿里云的服务器是没有交换分区的,如 [www-data@iZbp1ivdq1ie5lmrhp13kjZ ~]$ free -m total used free shared buff/cache av ...

  7. CentOS随笔 不断添加

    一.设置IP (1)临时IP  ifconfig eth0 192.168.120.16 (2)永久IP  vi /etc/sysconfig/network-scripts/ifcfg-eth0   ...

  8. vue-cli 组件的使用

    开始项目之前,先了解如何创建项目: http://www.cnblogs.com/pearl07/p/6247389.html 1,项目目录结构(路由是后来建的,将在下一篇使用路由,此处可忽略). 2 ...

  9. Spark优化之二:集群上运行jar程序,状态一直Accepted且不停止不报错

    如果运行Spark集群时状态一直为Accepted且不停止不报错,比如像下面这样的情况: 15/06/14 11:33:33 INFO yarn.Client: Application report ...

  10. CSS外边距叠加问题

    CSS外边距叠加就是margin-collapse,边距合并指的是,当两个垂直外边距相遇时,它们将形成一个外边距,水平边 距永远不会重合.重叠结果计算规则:①.两个相邻的外边距都是正数时,折叠结果是它 ...