试试看 ? 离奇古怪的javascript题目
来源地址:
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
我们一句一句的分解
这个很简单,直接调用bar 方法,此时的上下文就是foo对象,所以this.x = 20 return 的结果也就是20了
我们看看括号的定义 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
关于引用类型的解释,参考
这一题我也做错了,呵呵
查了查资料,我们先看看
- 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)()
那么,上面的语句中我们可以得知
- Grouping Operator 中的赋值语句返回的是 foot.bar 的函数值(「Value」)
- 该函数执行的上下文作用域为 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
逗号运算符和逻辑运算符(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题目的更多相关文章
- 看看国外的javascript题目,你能全部做对吗?(分享)
本文转自@Aaron的博客,拿过来分享一下.原文:看看国外的javascript题目,你能全部做对吗? 题目一: (function(){ return typeof arguments; })(); ...
- 容易出错的JavaScript题目集锦
容易出错的JavaScript题目集锦 1.typeof(null) 会得到什么?object,在JavaScript中null被认为是一个对象. 2.下列代码将输出控制台的是什么?为什么? 1234 ...
- 汤姆大叔 javascript 系列 第20课 最后的5到javascript题目
博客链接:http://www.cnblogs.com/TomXu/archive/2012/02/10/2342098.html 原题: 大叔注:这些题目也是来自出这5个题目的人,当然如果你能答对4 ...
- 看看国外的javascript题目,你能全部做对吗?
叶小钗 的博客最近都在讨论面试题目 正好以前也看过一篇,就借花献佛拿出来分享一下 http://perfectionkills.com/javascript-quiz/ 附带了自己的理解,答案有争议的 ...
- 我觉得有意思的JavaScript题目(01-05更新中)
对于以下js题目均来至于网络中.有的来至于文章之中,有的也许来至于问答题型中.如果您有更好的问题解释,请留言交流! 1.相关问题描述:到底该怎么去理解闭包? 代码片段A !function(){ va ...
- JavaScript 题目破解过程与解析
题目来源 https://www.hackthissite.org/missions/javascript/ HackThisSite JavaScript mission 1-7 1 我先尝试输入 ...
- 看看这些JavaScript题目你会做吗?
题目1 咋一看这题目,还以为答案选择B呢,其实正确答案为D,知道原因吗?接着往下看 map对数组的每个元素调用定义的回调函数并返回包含结果的数组,咋一看还以为它会像如下这样执行: function t ...
- TOM大叔的几道Javascript题目与解答
几道JS题目 之前没有深入研究js语言,最近几年前端越来越工程化,需要扎实的js基础,看到博客园上有很多大牛分享JS学习文章,幸运看到tom大叔的blog,抽时间潜心学习了其文章,遇到到其出的几道题目 ...
- 分享一道我认为非常有思考价值JavaScript题目
这是一道综合性的题目,如果你能快速清晰的分析整理出来,那我相信你对JavaScript是有一定的理解的了.我会先将题目的图片截取出来,供大家思考,在结尾在给出我的分析过程和答案,作个总结. 好,废话不 ...
随机推荐
- C++: Perfect Forwarding
Link: Rvalue References and Perfect Forwarding in C++0x (https://www.justsoftwaresolutions.co.uk/cpl ...
- iMetro
body { background:#FFFFFF url("http://images.cnblogs.com/cnblogs_com/mookmark/745172/o_8.jpg&qu ...
- pyqt 发射接收信号
翻页控件: 一.定义并发射信号: #!/usr/bin/python # #coding=utf-8 # __author__='' from PyQt4.QtCore import * from P ...
- 德国W家HIPP 奶粉有货播报:2014.7.8 HIPP 奶粉 1+ 4盒装有货啦!
德国W家HIPP 奶粉有货播报:2014.7.8 HIPP 奶粉 1+ 4盒装有货啦!
- Unity Android加密DLL笔记
unity mono 地址:https://github.com/Unity-Technologies/mono 下载与unity版本对应的unity mono. brew安装:http://brew ...
- 使用 SWFObject.js 插入Flash
今天学习了一下使用 SWFObject.js 这个js插入flash. 下载地址:http://code.google.com/p/swfobject/ 这个js的好处 1.IE中没有讨厌的虚框问题了 ...
- Codeforces Round #384 (Div. 2)D-Chloe and pleasant prizes
D. Chloe and pleasant prizes time limit per test 2 seconds memory limit per test 256 megabytes input ...
- svn 应该忽略的文件(visual studio)
*.o *.lo .la ## .*.rej .rej .~ ~ .# .DS_Store thumbs.db Thumbs.db *.bak *.class *.exe *.dll *.mine * ...
- 【hihoCoder】1288 : Font Size
题目:http://hihocoder.com/problemset/problem/1288 手机屏幕大小为 W(宽) * H(长),一篇文章有N段,每段有ai个字,要求使得该文章占用的页数不超过P ...
- HDU---BigZhuGod的粉丝
Problem Description 真正的粉丝,是不需要题目描述的^_^. Input 第一行输入数据组数T(1≤T≤100).接下来T行,每行一个有格式的字符串,详见样例,字符串长度不超过1 ...