Skip to content

Instantly share code, notes, and snippets.

@homleen
Created June 15, 2013 12:07
Show Gist options
  • Save homleen/5787912 to your computer and use it in GitHub Desktop.
Save homleen/5787912 to your computer and use it in GitHub Desktop.
有趣的Javascript Array
// 先来定义一个数组,并尝试输出其结果
> var a = [1, 2, 3];
> a
[1, 2, 3]
// 目前来看一切正常,没有任何问题
// ok,开始做点有意思的事
> a[-1] = 4;
// 数组发生变化了吗?
> a
[1, 2, 3]
// 没有?
> console.log(a)
[1, 2, 3, -1: 4]
// 多出了一个?尝试另一种输出
> dir(a)
Array(3)
// 看起来仍是长度为3的数组。但是... 如果点开左侧的三角
// 仍旧看到了-1:4
> a.length
3
// 那这个索引(-1)可以访问么?
> a[-1]
4
// 的确可以
// 暂时不管,再来挑战一下极限
> a[NaN] = 5;
> a
[1, 2, 3]
// ( ⊙ o ⊙ )!
// 来真正的挑战一下“极限”
> a[-Infinity] = "P";
> a[-Infinity+3] = "NP";
// 没有报错信息,这也可以
> a[-Infinity] === a[-Infinity+3]
true
// 再来看一下数组a的情况
> console.log(a);
[1, 2, 3, -1: 4, NaN: 5, -Infinity: "NP"]
// 有些混乱了,不妨多输出些信息再来看看
> typeof a
"object"
// 在Javascript的世界里,Array本身就是Object,这没什么值得好奇的
> a.length
3
// ok,继续
> a[function]='err';
SyntaxError: Unexpected token ]
> a[typeof console.log] = "duh";
> a['~'] = '<';
> a[a[typeof a]='huh', void a] = 'puh';
> a[{do: 'break'}] = 'thanks';
> a.continue = ["-",+"you"+"","+"][3,2,1][2];
> a.return = function(p){ return p;};
// 还记得当初的a么?
> a
[1, 2, 3]
// 难道什么都没有发生过么?
> a[a|a] = 3;
> a[-~a&-~a] = 2;
> a[-~-~!a] = 1;
> a
[3, 2, 1]
// Good, good, nicely reversed
> a['!'-1]
5
// Whoaa? Dude?
> '!'-1
NaN
// Oh yeah, I forgot about that I already have NaN in there
// console.log will reveal other interesting things for sure
> console.log(a);
[
-Infinity: "NP",
0: 3,
1: 2,
2: 1,
-1: 4,
NaN: 5,
[object Object]: "thanks",
continue: "N",
function: "duh",
length: 3,
object: "huh",
return: function (p){ return p;},
undefined: "puh",
~: "<"
]
// Hmm, there are couple of nice ones
> a.length = 2;
> a
[3, 2]
// Sorry for that
> a[{}];
"thanks"
> a['[object Object]'] = "you're welcome";
// Also, where did that continue: "N" come from? Was that from example with N=NP?
// Not really... that actually reminds me of one episode from my famous
// "JavaScript sucks" series:
// You should try this one. Just put the following into your favorite JS console:
// Or are you afraid of JavaScript? :)
> (({}-1)+"")[2]+({}+[])[1]+" "+((~-1<~[0])+"")[1/(1/0)]+((/./>/^/)+"")[4]+(""+!!(3^3))[1]+(""+!!(_="$"))[1]+"!"
// ... result stripped ... I won't make it that easy for you.
// Let's reveal one of the sneaky ones
// (that has actually nothing to do with arrays):
> a[100] = "Never gonna \
give you up,";
> a[101] = "Never gonna \
let you down";
SyntaxError: Unexpected token ILLEGAL
// Wow ... I thing I have been just Rickrolled by Chrome interpreter
// and I thought he would never gonna run around and desert me
// Do you know how this happened? BroTip: Try to copypaste it into your console.
// Talking about Syntax Errors, let's say we need a function that performs
// this importing-like functionality for us. Let's call it import.
> function import() {}
SyntaxError: Unexpected token import
// One thing I haven't tried yet is doing a bit of recursion in array
> a.me = a;
> console.log(a);
[... me: Array[3] ...] // striped other previously messed up things
> console.log(a.me.me.me)
[... me: Array[3] ...]
// If you would run the same thing in Node.JS you would see more explanatory
> console.log(a.me.me.me)
[ me: [Circular] ]
// Let's run simple one liner to try to iterate through recursive object
> for(var i=0, c=a; c=c.me; console.log(i), i++);
0
1
...
26012391
...
// Ok, Node.JS is still running, no simple way to kill it.
// What about Chrome console?
> for(var i=0, c=a; c=c.me; console.log(i), i++);
0
1
...
314
...
2679
...
// Chrome died. Goodbye a. See you in Silicon Heaven.
// That reminds me of good old times when I tried to view 5MB XML without
// line breakings in Chrome, Opera, IE, Firefox...
// Let's start chrome console again with clean array
> var a = [];
> a.me = a;
// Hmm I need to add some elem to array, so I can just copypaste that loop again
> a[1] = 2
> a
[undefined × 1, 2]
// That's interesting - array is 'filled up' with undefineds and Chrome
// prints that out neatly
// Let's test how long this loop take
> console.time('evt'); for(var i=0, c=a; c=c.me, i < 10000; console.log(i), i++); console.timeEnd('evt');
evt: 1552.587ms
// Let's try the same thing with object to see if there's any difference
> var o = {};
> o.me = o;
> console.time('evt'); for(var i=0, c=o; c=c.me, i < 10000; console.log(i), i++); console.timeEnd('evt');
evt: 1610.678ms
// Not really - so what to take from this: Arrays are Objects, essentially.
// And yes, proving that by executing console.log multiple times is just
// plain stupid.
// One last interesting thing
> i
10000
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment