├── LICENSE └── README.md /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Ufostation 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Javascript Anomaly Page 2 | 3 | This page created for javascript beginner programmers to show not obvious behaviors, let's call all of them "anomalies" 4 | 5 | * [Assignment Anomaly](#assignment-anomaly) 6 | * [Reference Anomaly](#reference-anomaly) 7 | * [New Anomaly](#new-anomaly) 8 | * [Closure Anomaly](#closure-anomaly) 9 | * [Context Anomay](#context-anomaly) 10 | * [Delete Anomaly](#delete-anomaly) 11 | * [Type Anomaly](#type-anomaly) 12 | * [Compare Anomaly](#compare-anomaly) 13 | * [Math Anomaly](#math-anomaly) 14 | * [Logic Anomaly](#logic-anomaly) 15 | * [Variable scope Anomaly](#variable-scope-anomaly) 16 | * [Function Arguments Anomaly](#function-arguments-anomaly) 17 | * [toString Anomaly](#tostring-anomaly) 18 | * [New line Anomaly](#new-line-anomaly) 19 | * [Variable hoisting Anomaly](#variable-hoisting-anomaly) 20 | 21 | ### Assignment Anomaly 22 | 23 | ``` 24 | (function(){ 25 | var a = b = 3; 26 | })(); 27 | 28 | console.log(typeof a); 29 | // output: undefined 30 | 31 | console.log(typeof b); 32 | // output: number 33 | 34 | 35 | var a={}, 36 | b={key:'b'}, 37 | c={key:'c'}; 38 | 39 | a[b]=123; 40 | a[c]=456; 41 | 42 | console.log(a[b]); 43 | // output: 456 44 | ``` 45 | 46 | ### Reference Anomaly 47 | 48 | ``` 49 | var a = { value: 1 }; 50 | var b = a; 51 | b.value = 2; 52 | 53 | console.log(a.value); 54 | // output: 2 55 | ``` 56 | 57 | ### New Anomaly 58 | 59 | ``` 60 | var myClass = function() { 61 | this.a = 1; 62 | this.b = 2; 63 | }; 64 | 65 | var myClass2 = function() { 66 | this.a = 1; 67 | this.b = 2; 68 | 69 | return { 70 | a: 2 71 | }; 72 | }; 73 | 74 | var myObject = new myClass(); 75 | var myObject2 = new myClass2(); 76 | 77 | console.log(typeof myObject.b); 78 | // output: number 79 | console.log(typeof myObject2.b); 80 | // output: undefined 81 | ``` 82 | 83 | ### Closure Anomaly 84 | ``` 85 | for (var i = 0; i < 3; i++) { 86 | setTimeout(function() { 87 | console.log(i); 88 | }, 100); 89 | } 90 | 91 | // output: 3 92 | // output: 3 93 | // output: 3 94 | ``` 95 | 96 | ### Context Anomaly 97 | 98 | ``` 99 | var message = { 100 | content: 'Hello world!', 101 | send: function () { 102 | console.log(this.content) 103 | } 104 | }; 105 | 106 | setTimeout(message.send); 107 | 108 | // output: undefined 109 | ``` 110 | 111 | ### Delete Anomaly 112 | 113 | ``` 114 | var x = 1; 115 | var output = (function(){ 116 | delete x; 117 | return x; 118 | })(); 119 | 120 | console.log(output); 121 | // output: 1 122 | ``` 123 | 124 | 125 | ### Type Anomaly 126 | 127 | ``` 128 | console.log(typeof null); 129 | // output: object 130 | 131 | 132 | console.log(null instanceof Object); 133 | // output: false 134 | 135 | console.log(typeof NaN); 136 | // output: number 137 | 138 | console.log(typeof function () {}); 139 | // output: function 140 | // but there's no function type http://ecma-international.org/ecma-262/5.1/#sec-8 141 | ``` 142 | 143 | 144 | ### Compare Anomaly 145 | 146 | 147 | ``` 148 | console.log('' == '0'); 149 | // output: false 150 | 151 | console.log(0 == ''); 152 | // output: true 153 | 154 | console.log(0 == '0'); 155 | // output: true 156 | 157 | console.log(false == 'false'); 158 | // output: false 159 | 160 | console.log(false == '0'); 161 | // output: true 162 | 163 | console.log(false == undefined); 164 | // output: false 165 | 166 | console.log(false == null); 167 | // output: false 168 | 169 | console.log(null == undefined); 170 | // output: true 171 | 172 | console.log(' \t\r\n ' == 0); 173 | // output: true 174 | 175 | console.log("abc" == new String("abc")); 176 | // output: true 177 | 178 | console.log("abc" === new String("abc")); 179 | // output: false 180 | 181 | console.log(0.1 + 0.2 == 0.3); 182 | // output: false 183 | // sum of float values is not equals obvious float value 184 | 185 | console.log(NaN != NaN); 186 | // output: true 187 | 188 | console.log(NaN == NaN); 189 | // output: false 190 | 191 | console.log(NaN === NaN); 192 | // output: false 193 | 194 | console.log(!!undefined); 195 | // output: false 196 | 197 | console.log(!!NaN); 198 | // output: false 199 | 200 | console.log(!!null); 201 | // output: false 202 | 203 | console.log([1, 2, 3] == [1, 2, 3]); 204 | // output: false 205 | // How to detect array equality in JavaScript? 206 | 207 | console.log(new Array(3) == ",,"); 208 | // output: true 209 | 210 | console.log(new Array(3) === ",,"); 211 | // output: false 212 | 213 | console.log("a" > "b"); 214 | // output: false 215 | 216 | console.log("abcd" < "abcd"); 217 | // output: false 218 | 219 | console.log("abcd" < "abdc"); 220 | // output: true 221 | 222 | console.log("123" > "13"); 223 | // output: false 224 | ``` 225 | 226 | 227 | ### Math Anomaly 228 | 229 | ``` 230 | console.log("2" * "3"); 231 | // output: 6 232 | 233 | console.log("2" * "3" + "4"); 234 | // output: "64" 235 | 236 | console.log("2" * "3" + "4" * "5") 237 | // output: 26 238 | 239 | console.log("test " + 1); 240 | // output: test 1 241 | 242 | console.log("test " + 1 + 1); 243 | // output: test 11 244 | 245 | console.log("days" * 2); 246 | // output: NaN 247 | 248 | console.log(null + null); 249 | // output: 0 250 | 251 | console.log({} + {}); 252 | // output: [object Object][object Object] 253 | 254 | console.log({} + []); 255 | // output: [object Object] 256 | 257 | console.log({} + 5); 258 | // output: [object Object]5 259 | 260 | console.log([] + {}); 261 | // output: [object Object] 262 | 263 | console.log([] + []); 264 | // output: 265 | // will output empty string '' 266 | 267 | console.log([] + 5); 268 | // output: 5 269 | 270 | console.log(++[[]][+[]]+[+[]]); 271 | // output: "10" 272 | ``` 273 | 274 | ### Logic Anomaly 275 | 276 | ``` 277 | console.log(0 || 'a'); 278 | // output: a 279 | 280 | console.log(0 || undefined); 281 | // output: undefined 282 | 283 | console.log({} && 'a'); 284 | // output: a 285 | 286 | console.log(0 && 'a'); 287 | // output: 0 288 | ``` 289 | 290 | ### Variable scope Anomaly 291 | 292 | ``` 293 | function Foo(value) { 294 | this.bar = value; 295 | } 296 | var test = new Foo('test'); 297 | console.log(test.bar); 298 | // output: test 299 | 300 | Foo('test'); 301 | console.log(bar); 302 | // output: test 303 | ``` 304 | 305 | 306 | ### Function Arguments Anomaly 307 | 308 | ``` 309 | (function (foo, bar) { 310 | console.log(typeof arguments); 311 | // output: object 312 | 313 | arguments[0] = 999; 314 | console.log(foo); 315 | // output: 999 316 | })(1, 2); 317 | ``` 318 | 319 | 320 | ### toString Anomaly 321 | 322 | ``` 323 | try { 324 | eval("2.toString()") 325 | } catch (err) { 326 | console.log(err.message) 327 | // output: Unexpected token ILLEGAL 328 | } 329 | 330 | console.log(2..toString()); 331 | // output: 2 332 | 333 | console.log(2 .toString()); 334 | // output 2 335 | 336 | console.log((2).toString()); 337 | // output: 2 338 | 339 | console.log([1, 2, 3].toString()) 340 | // output: 1,2,3 341 | 342 | var a = {b: 2, c: 3}; 343 | console.log(a.toString()) 344 | // output: [object Object] 345 | ``` 346 | 347 | ### New line Anomaly 348 | 349 | ``` 350 | function foo() { 351 | return "Yeah"; 352 | } 353 | 354 | function bar() { 355 | return 356 | "Yeah"; 357 | } 358 | 359 | console.log(foo()); 360 | // output: Yeah 361 | 362 | console.log(bar()); 363 | // output: 364 | ``` 365 | 366 | ### Variable hoisting Anomaly 367 | 368 | ``` 369 | var a = 1; 370 | function bar() { 371 | if (!a) { 372 | var a = 10; 373 | } 374 | console.log(a); 375 | } 376 | bar(); 377 | // output: 10 378 | ``` 379 | 380 | ``` 381 | var a = 1; 382 | function b() { 383 | a = 10; 384 | return; 385 | function a() {} 386 | } 387 | b(); 388 | console.log(a); 389 | // output: 1 390 | ``` 391 | 392 | Note that `anomaly` word has only literary turnover, it's not a technical term. 393 | --------------------------------------------------------------------------------