{"action":"created","issue":{"url":"https://api.github.com/repos/xiaoyu2er/blog/issues/3","repository_url":"https://api.github.com/repos/xiaoyu2er/blog","labels_url":"https://api.github.com/repos/xiaoyu2er/blog/issues/3/labels{/name}","comments_url":"https://api.github.com/repos/xiaoyu2er/blog/issues/3/comments","events_url":"https://api.github.com/repos/xiaoyu2er/blog/issues/3/events","html_url":"https://github.com/xiaoyu2er/blog/issues/3","id":159418153,"number":3,"title":"44个 Javascript 变态题解析 (下)","user":{"login":"xiaoyu2er","id":10123916,"avatar_url":"https://avatars.githubusercontent.com/u/10123916?v=3","gravatar_id":"","url":"https://api.github.com/users/xiaoyu2er","html_url":"https://github.com/xiaoyu2er","followers_url":"https://api.github.com/users/xiaoyu2er/followers","following_url":"https://api.github.com/users/xiaoyu2er/following{/other_user}","gists_url":"https://api.github.com/users/xiaoyu2er/gists{/gist_id}","starred_url":"https://api.github.com/users/xiaoyu2er/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/xiaoyu2er/subscriptions","organizations_url":"https://api.github.com/users/xiaoyu2er/orgs","repos_url":"https://api.github.com/users/xiaoyu2er/repos","events_url":"https://api.github.com/users/xiaoyu2er/events{/privacy}","received_events_url":"https://api.github.com/users/xiaoyu2er/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":3,"created_at":"2016-06-09T14:12:43Z","updated_at":"2016-06-12T03:04:13Z","closed_at":null,"body":"承接上篇 [44个 Javascript 变态题解析 (上)](https://github.com/xiaoyu2er/blog/issues/1)\r\n\r\n\r\n## 第23题\r\n\r\n```\r\n[1 < 2 < 3, 3 < 2 < 1]\r\n```\r\n\r\n这个题也还可以.\r\n\r\n这个题会让人误以为是 `2 > 1 && 2 < 3` 其实不是的.\r\n\r\n这个题等价于\r\n\r\n```\r\n 1 < 2 => true;\r\n true < 3 =>  1 < 3 => true;\r\n 3 < 2 => false;\r\n false < 1 => 0 < 1 => true;\r\n```\r\n\r\n答案是  `[true, true]`\r\n\r\n## 第24题\r\n\r\n```\r\n// the most classic wtf\r\n2 == [[[2]]]\r\n```\r\n\r\n这个题我是猜的. 我猜的 `true`, 至于为什么.....\r\n\r\n`both objects get converted to strings and in both cases the resulting string is \"2\"` 我不能信服...\r\n\r\n##  第25题\r\n\r\n```\r\n3.toString()\r\n3..toString()\r\n3...toString()\r\n```\r\n\r\n这个题也挺逗, 我做对了 :) 答案是 `error, '3', error`\r\n\r\n你如果换一个写法就更费解了\r\n\r\n```\r\nvar a = 3;\r\na.toString()\r\n```\r\n\r\n这个答案就是 `'3'`;\r\n\r\n为啥呢?\r\n\r\n因为在 js 中 `1.1`, `1.`, `.1` 都是合法的数字. 那么在解析 `3.toString` 的时候这个 `.` 到底是属于这个数字还是函数调用呢? 只能是数字, 因为`3.`合法啊!\r\n\r\n## 第26题\r\n\r\n```\r\n          \r\n(function(){\r\n  var x = y = 1;\r\n})();\r\nconsole.log(y);\r\nconsole.log(x);\r\n```\r\n答案是 `1, error`\r\n\r\ny 被赋值到全局. x 是局部变量. 所以打印 x 的时候会报 `ReferenceError`\r\n\r\n\r\n## 第27题\r\n\r\n```\r\nvar a = /123/,\r\n    b = /123/;\r\na == b\r\na === b\r\n```\r\n\r\n即使正则的字面量一致, 他们也不相等.\r\n\r\n答案 `false, false`\r\n\r\n## 第28题\r\n\r\n```\r\nvar a = [1, 2, 3],\r\n    b = [1, 2, 3],\r\n    c = [1, 2, 4]\r\na ==  b\r\na === b\r\na >   c\r\na <   c\r\n```\r\n\r\n字面量相等的数组也不相等.\r\n\r\n数组在比较大小的时候按照字典序比较\r\n\r\n答案 `false, false, false, true`\r\n\r\n## 第29题\r\n\r\n```\r\nvar a = {}, b = Object.prototype;\r\n[a.prototype === b, Object.getPrototypeOf(a) === b]\r\n```\r\n\r\n知识点:\r\n\r\n+ [Object/getPrototypeOf](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getPrototypeOf)\r\n\r\n只有 Function 拥有一个 prototype 的属性. 所以 `a.prototype` 为 `undefined`.\r\n\r\n而 `Object.getPrototypeOf(obj)` 返回一个具体对象的原型(该对象的内部`[[prototype]]`值)\r\n\r\n答案 `false, true`\r\n\r\n## 第30题\r\n\r\n```\r\nfunction f() {}\r\nvar a = f.prototype, b = Object.getPrototypeOf(f);\r\na === b\r\n```\r\n\r\nf.prototype is the object that will become the parent of any objects created with new f while Object.getPrototypeOf returns the parent in the inheritance hierarchy.\r\n\r\nf.prototype 是使用使用 new 创建的 f 实例的原型. 而 Object.getPrototypeOf 是 f 函数的原型.\r\n\r\n请看:\r\n\r\n```\r\n\r\na === Object.getPrototypeOf(new f()) // true\r\nb === Function.prototype // true\r\n```\r\n\r\n答案 `false`\r\n\r\n## 31\r\n\r\n```\r\nfunction foo() { }\r\nvar oldName = foo.name;\r\nfoo.name = \"bar\";\r\n[oldName, foo.name]\r\n```\r\n\r\n答案 `['foo', 'foo']`\r\n\r\n知识点:\r\n\r\n+ [Function/name](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name)\r\n\r\n因为**函数的名字不可变**.\r\n\r\n## 第32题\r\n\r\n```\r\n\"1 2 3\".replace(/\\d/g, parseInt)\r\n```\r\n\r\n知识点:\r\n\r\n+ [String/replace#Specifying_a_function_as_a_parameter](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#Specifying_a_function_as_a_parameter)\r\n\r\n`str.replace(regexp|substr, newSubStr|function)`\r\n\r\n如果replace函数传入的第二个参数是函数, 那么这个函数将接受如下参数\r\n\r\n+ match 首先是匹配的字符串\r\n+ p1, p2 .... 然后是正则的分组\r\n+ offset match 匹配的index\r\n+ string 整个字符串\r\n\r\n由于题目中的正则没有分组, 所以等价于问\r\n\r\n```\r\nparseInt('1', 0)\r\nparseInt('2', 2)\r\nparseInt('3', 4)\r\n```\r\n\r\n答案: `1, NaN, 3`\r\n\r\n##  第33题\r\n\r\n```\r\nfunction f() {}\r\nvar parent = Object.getPrototypeOf(f);\r\nf.name // ?\r\nparent.name // ?\r\ntypeof eval(f.name) // ?\r\ntypeof eval(parent.name) //  ?\r\n```\r\n\r\n先说以下答案 `'f', 'Empty', 'function', error` 这个答案并不重要.....\r\n\r\n这里第一小问和第三小问很简单不解释了.\r\n\r\n第二小问笔者在自己的浏览器测试的时候是 `''`, 第四问是 `'undefined'`\r\n\r\n所以应该是平台相关的. 这里明白 `parent === Function.prototype` 就好了.\r\n\r\n## 第34题\r\n\r\n```\r\nvar lowerCaseOnly =  /^[a-z]+$/;\r\n[lowerCaseOnly.test(null), lowerCaseOnly.test()]\r\n```\r\n\r\n知识点:\r\n\r\n+ [RegExp/test](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/test)\r\n\r\n这里 test 函数会将参数转为字符串. ` 'nul'`, `'undefined'` 自然都是全小写了\r\n\r\n答案: `true, true`\r\n\r\n## 第35题\r\n\r\n```\r\n[,,,].join(\", \")\r\n```\r\n`[,,,] => [undefined × 3]`\r\n\r\n因为javascript 在定义数组的时候允许最后一个元素后跟一个`,`, 所以这是个长度为三的稀疏数组(这是长度为三, 并没有 0, 1, 2三个属性哦)\r\n\r\n答案: `\", , \"`\r\n\r\n## 第36题\r\n\r\n```\r\nvar a = {class: \"Animal\", name: 'Fido'};\r\na.class\r\n```\r\n\r\n这个题比较流氓.. 因为是浏览器相关, `class`是个保留字(现在是个关键字了)\r\n\r\n所以答案不重要, 重要的是自己在取属性名称的时候尽量避免保留字. 如果使用的话请加引号  `a['class']`\r\n        \r\n\r\n## 第37题\r\n\r\n```\r\nvar a = new Date(\"epoch\")\r\n```\r\n\r\n知识点:\r\n\r\n+ [Date](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date)\r\n+ [Date/parse](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse)\r\n\r\n简单来说, 如果调用 Date 的构造函数传入一个字符串的话需要符合规范, 即满足 Date.parse 的条件.\r\n\r\n另外需要注意的是 如果格式错误 构造函数返回的仍是一个Date 的实例 `Invalid Date`.\r\n\r\n答案 `Invalid Date`\r\n\r\n## 第38题\r\n\r\n```\r\nvar a = Function.length,\r\n    b = new Function().length\r\na === b\r\n```\r\n我们知道一个function(Function 的实例)的 `length` 属性就是函数签名的参数个数, 所以 b.length == 0.\r\n\r\n另外 Function.length 定义为1......\r\n\r\n所以不相等.......答案 `false`\r\n\r\n## 第39题\r\n\r\n```\r\nvar a = Date(0);\r\nvar b = new Date(0);\r\nvar c = new Date();\r\n[a === b, b === c, a === c]\r\n```\r\n\r\n还是关于Date 的题, 需要注意的是 \r\n\r\n+ 如果不传参数等价于当前时间. \r\n+ 如果是函数调用 返回一个字符串.\r\n\r\n答案 `false, false, false`\r\n\r\n## 第40题\r\n\r\n```\r\nvar min = Math.min(), max = Math.max()\r\nmin < max\r\n```\r\n\r\n知识点:\r\n\r\n+ [Math/min](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/min)\r\n+ [Math/max](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/max)\r\n\r\n有趣的是, Math.min 不传参数返回 `Infinity`, Math.max 不传参数返回 `-Infinity` 😆 \r\n \r\n答案: `false`\r\n\r\n## 第41题\r\n\r\n```\r\nfunction captureOne(re, str) {\r\n  var match = re.exec(str);\r\n  return match && match[1];\r\n}\r\nvar numRe  = /num=(\\d+)/ig,\r\n    wordRe = /word=(\\w+)/i,\r\n    a1 = captureOne(numRe,  \"num=1\"),\r\n    a2 = captureOne(wordRe, \"word=1\"),\r\n    a3 = captureOne(numRe,  \"NUM=2\"),\r\n    a4 = captureOne(wordRe,  \"WORD=2\");\r\n[a1 === a2, a3 === a4]\r\n```\r\n\r\n知识点:\r\n+ [RegExp/exec](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/exec)\r\n\r\n通俗的讲\r\n\r\n因为第一个正则有一个 g 选项 它会‘记忆’他所匹配的内容, 等匹配后他会从上次匹配的索引继续, 而第二个正则不会\r\n\r\n举个例子\r\n\r\n```\r\nvar myRe = /ab*/g;\r\nvar str = 'abbcdefabh';\r\nvar myArray;\r\nwhile ((myArray = myRe.exec(str)) !== null) {\r\n  var msg = 'Found ' + myArray[0] + '. ';\r\n  msg += 'Next match starts at ' + myRe.lastIndex;\r\n  console.log(msg);\r\n}\r\n// Found abb. Next match starts at 3\r\n// Found ab. Next match starts at 9\r\n```\r\n\r\n所以 a1 = '1'; a2 = '1'; a3 = null; a4 = '2'\r\n\r\n答案 `[true, false]`\r\n\r\n\r\n## 第42题\r\n\r\n```\r\nvar a = new Date(\"2014-03-19\"),\r\n    b = new Date(2014, 03, 19);\r\n[a.getDay() === b.getDay(), a.getMonth() === b.getMonth()]\r\n\r\n```\r\n\r\n这个....\r\n\r\n>JavaScript inherits 40 years old design from C: days are 1-indexed in C's struct tm, but months are 0 indexed. In addition to that, getDay returns the 0-indexed day of the week, to get the 1-indexed day of the month you have to use getDate, which doesn't return a Date object.\r\n\r\n```\r\na.getDay()\r\n3\r\nb.getDay()\r\n6\r\na.getMonth()\r\n2\r\nb.getMonth()\r\n3\r\n```\r\n\r\n都是套路!\r\n\r\n答案 `[false, false]`\r\n\r\n## 第43题\r\n\r\n```\r\nif ('http://giftwrapped.com/picture.jpg'.match('.gif')) {\r\n  'a gif file'\r\n} else {\r\n  'not a gif file'\r\n}\r\n```\r\n\r\n知识点:\r\n\r\n+ [String/match](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/match)\r\n\r\nString.prototype.match 接受一个正则, 如果不是, 按照 `new RegExp(obj)` 转化. 所以 `.` 并不会转义\r\n那么 `/gif` 就匹配了 /.gif/ \r\n\r\n答案: `'a gif file'`\r\n\r\n\r\n## 第44题\r\n\r\n```\r\nfunction foo(a) {\r\n    var a;\r\n    return a;\r\n}\r\nfunction bar(a) {\r\n    var a = 'bye';\r\n    return a;\r\n}\r\n[foo('hello'), bar('hello')]\r\n```\r\n\r\n在两个函数里, a作为参数其实已经声明了, 所以 `var a; var a = 'bye'` 其实就是 `a; a ='bye'`\r\n\r\n所以答案 `'hello', 'bye'`\r\n\r\n\r\n全部结束!\r\n\r\n==================\r\n\r\n# 总结\r\n\r\n由于笔者水平有限, 如果解释有误, 还望指出 😄 \r\n\r\n通过整理, 笔者发现绝大部分题目都是因为自己对于基础知识或者说某个 API 的参数理解偏差才做错的.\r\n\r\n笔者的重灾区在原型那一块, 所以这次被虐和整理还是很有意义呀.\r\n\r\n笔者相信 坚实的基础是深入编程的前提. 所以基础书还是要常看啊 🐹 \r\n\r\n最后这些变态题现在看看还变态嘛?\r\n\r\n\r\n\r\n"},"comment":{"url":"https://api.github.com/repos/xiaoyu2er/blog/issues/comments/225407062","html_url":"https://github.com/xiaoyu2er/blog/issues/3#issuecomment-225407062","issue_url":"https://api.github.com/repos/xiaoyu2er/blog/issues/3","id":225407062,"user":{"login":"xiaoyu2er","id":10123916,"avatar_url":"https://avatars.githubusercontent.com/u/10123916?v=3","gravatar_id":"","url":"https://api.github.com/users/xiaoyu2er","html_url":"https://github.com/xiaoyu2er","followers_url":"https://api.github.com/users/xiaoyu2er/followers","following_url":"https://api.github.com/users/xiaoyu2er/following{/other_user}","gists_url":"https://api.github.com/users/xiaoyu2er/gists{/gist_id}","starred_url":"https://api.github.com/users/xiaoyu2er/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/xiaoyu2er/subscriptions","organizations_url":"https://api.github.com/users/xiaoyu2er/orgs","repos_url":"https://api.github.com/users/xiaoyu2er/repos","events_url":"https://api.github.com/users/xiaoyu2er/events{/privacy}","received_events_url":"https://api.github.com/users/xiaoyu2er/received_events","type":"User","site_admin":false},"created_at":"2016-06-12T03:04:13Z","updated_at":"2016-06-12T03:04:13Z","body":"@rambo-panda 😄 那很厉害了"}}
{"actor":{"display_login":"xiaoyu2er"}}