denysdovhan / wtfjs Goto Github PK
View Code? Open in Web Editor NEW🤪 A list of funny and tricky JavaScript examples
Home Page: http://bit.ly/wtfjavascript
License: Do What The F*ck You Want To Public License
🤪 A list of funny and tricky JavaScript examples
Home Page: http://bit.ly/wtfjavascript
License: Do What The F*ck You Want To Public License
Nice example of interpretator stupidness 👯 (taken from http://lurkmore.to/Javascript )
function foo(){}
foo()
[1,2,3].map(console.log.bind(console)) // Uncaught TypeError: undefined is not an object
however this works:
function foo(){}
foo()
;[1,2,3].map(console.log.bind(console))
I started https://github.com/JavascriptWTF/JavascriptWTF.github.io a few weeks before you started your project; I suspect we may have been driven by the same thing ;)
I was very impressed to read the articles on this site.
Especially "It's a fail" The part is interesting, so I've created an example that lets you see the case directly.
Can I add a link to this example?
The explanation for the "A constructor
property" section is missing the ?
at the end of the WTF?
string.
In my browser console (firefox) {} + {}
does not give "[object Object][object Object]"
but Nan
.
This is because the first {}
is not treated as an object, but and empty code block.
This does not do anything, so what remains is +{}
and since an empty object can't be turned into a number that returns NaN
.
This only happens when the first {}
is at the start of a statement.
When I do console.log({} + {})
it just prints [object Object][object Object]
Apart from the browser console you can also get this quirk using eval: eval("{} + {}")
will return NaN
also in the nodejs console.
I find this one really funny as well:
var obj = { prop: 3 }
obj[['prop']] // -> 3
Of course the explanation is easy, the bracket operator converts everything you pass to a string, and converting an 1 element array to string is just returning the conversion of that element to string.
Motivation: If you are a beginner, you can use this notes to get deeper dive into the JavaScript. I hope this notes will motivate you to spend more time reading the specification.
I'm beginner in JS, even though i understands most of the examples but the problem is, most of the examples contains ECMA-Spec as a reference for the detailed explanation of the example which is not a beginner friendly approach.
So what i suggest is try to add explanation of examples there only, so that newbies can understands it properly.
And thanks for all the examples. It really improved my knowledge.
Hope you consider it as a feature request.
the right link should be https://www.ecma-international.org/ecma-262/#sec-number.min_value
rather than
JSON.strigify('production') === 'production' //> false
I am able to translate this language [yes/no]
I find an error in the explanation of 'true is false':
true == 'true' // -> true
false == 'false' // -> false
Actually, the result of true == 'true'
should be 'false'. Because true(boolean) is saw as 1(number),but 'true'(string) is saw as NaN(number), they are different.
var foo = {n: 1};
var bar = foo;
foo.x = foo = {n: 2}
foo.x // undefined
foo // {n: 2}
bar // {n: 1, x: {n: 2}}
foo.x == undefined, but bar.x == foo
1 + "1" is "11"
But,
1 - "1" is 0
null == 0 is false
null < 0 is false
null <= 0 is true
A couple of years ago I came across this site:
Maybe you want to include this link somewhere; if it's worth anything!
I am able to translate this language [yes]
Here is another "funny" thing:
a = [,,,];
a.length // ==> 3
a + "" // ==> ",,"
see: https://twitter.com/aemkei/status/870252223762243584 and https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Trailing_commas
If you're clever enough to get some javascript array that was created inside an iframe, then in the parent window you'll get
thatArrayFromIframe instanceof Array
> false
where N is the expression to the right of the tilde
console.log(~~"1"); // 1
console.log(~~true); // 1
console.log(~~false); // 0
~someStr.indexOf("a")
instead of
someStr.indexOf("a") >= 0
Source: https://www.joezimjs.com/javascript/great-mystery-of-the-tilde/
As in MDN "ECMAScript 5 removes octal interpretation". ES5 compatibility table shows only Konq 4.14 and obsolete platforms (Opera 12 and older, IE 8 and older, and Rhino) still have this issue.
Not related to octals, but something to add on:
// parseInt always convert input to string:
parseInt({toString: () => 2, valueOf: () => 1}) // -> 2
Number({toString: () => 2, valueOf: () => 1}) // -> 1
In the readme, couple of hyperlinks for Wikipedia go to the mobile site:
If this isn't intentional, removing the m.
is enough to fix it. Otherwise, close away!
Very very very minor issue 😁
Ran into this while coding... What do you think the below code will do?
var arr = [1,2,3,4,5,6,7,8,9];
function wtfJS(){
let num, num2, els = arr,
len = els.length,
el = els[num = Math.floor(Math.random()*len)],
el2 = els[
(num =! (num2 = Math.floor(Math.random()*len)))
?num2:num?--num:++num];
console.log(num,num2,el, el2);
}
It'll either print out 1 # # 2 or true # # 1. The # # are other number that is not important. What is, is the print of "true" or "1" through the num variable which in turn give me either 1 or 2 through the el2 variable. I think it got something to do with coercer in the turner operand.
function okayJS(){
let num, num2, els, len, el, el2, animLghts;
els = arr;
len = els.length;
num = Math.floor(Math.random()*len);
el = els[num];
num2 = Math.floor(Math.random()*len);
if (num == num2) num2 = (num?--num:++num);
el2 = els[num2];
console.log(num,num2,el, el2);
}
in parseInt is a bad guy section
parseInt('08'); // 0
but i have executed the code in chrome and node.js , the result is 8
There is also https://www.destroyallsoftware.com/talks/wat in which I first time saw wtfjs
Also this one https://twitter.com/jplur_/status/891358168688754688
I am able to translate this language, and I already started to do it. I have over a 70% of the job done. When I finish I will do a pull request.
On the topic parseInt is a bad guy, you missed an , censoring the F word.
"The f in 'fck' is hexadecimal 15."
It's not issue, but doesn't fits appropriately with the article.
Array equality is a monster in JS, think below:
[] == '' // true
[] == 0 // true
[''] == '' // true
[0] == 0 // true
[0] == '' // ----> false
[''] == 0 // ----> true??
[null] == '' // true
[null] == 0 // true
[undefined] == '' // true
[undefined] == 0 // true
[[]] == 0 // true
[[]] == '' // true
[[[[[[]]]]]] == '' // true
[[[[[[]]]]]] == 0 // true
[[[[[[ null ]]]]]] == 0 // true
[[[[[[ null ]]]]]] == '' // true
[[[[[[ undefined ]]]]]] == 0 // true
[[[[[[ undefined ]]]]]] == '' // true
You should be very careful for above!
explanation behind that says it's just coercion of one type plus another.
What is happening there is actually a code block and a unary + which coerces the array into 0.
({} + []) would get the same as ([] + {}) understandably.
I present this as an oddity for your amusement.
class Foo extends Function {
constructor(val) {
super();
this.prototype.val = val;
}
}
new new Foo(':D')().val // => ':D'
Constructors in Javascript are of course just functions with some special treatment. by extending Function using the ES6 class syntax you create a class that, when instantiated, is now a function, which you can then additionally instantiate.
While not exhaustively tested, I believe the last JS statement can be analyzed thus:
(new (new Foo(':D'))()).val
(new newFooInstance()).val
veryNewFooInstance.val
':D'
As a tiny addendum, doing new Function('return "bar";')
of course creates a function with the body return "bar";
. Since super()
in the constructor of our Foo
class is calling Function
's constructor, it should come as no surprise now to see that we can additionally manipulate things in there.
class Foo extends Function {
constructor(val) {
super(`
this.val = arguments[0];
`);
this.prototype.val = val;
}
}
var foo = new new Foo(':D')('D:');
foo.val // -> 'D:'
delete foo.val; // remove the instance prop 'val', deferring back to the prototype's 'val'.
foo.val // -> ':D'
hello Mr., I am a translator, I want to translate English into Indonesian, Because the majority of Indonesian people do not understand English.. I will be sincere if I am in trust
Thought, it should be here as well,
https://charlieharvey.org.uk/page/why_math_max_is_less_than_math_min
function a(x) {
arguments[0] = 'hello';
console.log(x);
}
a(); // -> undefined
a(1); // -> "hello"
var foo = {
toString: function() { return 'foo'},
valueOf: function() { return 5}
}
console.log(foo + 'bar'); //5bar
console.log([foo,'bar'].join('')); //foobar
The explanation just says that return
and the returned expression must be in the same line, but not much else. I'd put these references, explaining that a semicolon is automagically inserted between return
and the returned expression otherwise, and that therefore causes the statement to terminate the function with the default undefined
value:
11.9.1 Rules of Automatic Semicolon Insertion
13.10 The return Statement
NaN++ // NaN
0/0 // NaN
(0/0)++ // invalid lhs, but [0/0][0]++ works of course
NaN = void 0 // undefined
--undefined // NaN
--void 0 // invalid lhs
Bonus fun with the read-only Number.NaN
property:
Object.is(Number.NaN, Number.NaN) // true
Object.is(Number.NaN, NaN) // true
Object.is(NaN, NaN) // true
Number[NaN] // NaN
Number = {NaN: 0} // works in browsers (modifies window.Number), but reassigning Number crashes Node.js v10.2.0 with "TypeError: Number.isSafeInteger is not a function"
Number.NaN // 0
Number.NaN = 1 // 1
Number.NaN // 1
Hi, I'm very interested in knowing more about a tweet by @aemkei Martin Kleppe (author of jsfuck.com)
[666]['\155\141\160']['
\143\157\156\163\164
\162\165\143\164\157
\162']('\141\154\145
\162\164(666)')(666)
// alert(666)
https://twitter.com/aemkei/status/897172907222237185
May be good candidate here too. Thanks.
The explanation to "baNaNa" does indicate that the second plus is actually an unary plus operator, which is (in my opinion) key to understanding the trick, yet the reference only lists the binary plus (numeric addition/string concatenation), which is not as important and is a completely different operator.
Here is the reference to unary plus:
On line 70 you have
I hope this notes will motivate you to spend more time reading the specification.
This should be these. You also should link to the spec
Looks like a comeback of old fun
https://github.com/denysdovhan/wtfjs#function-is-not-a-function
Tried in nodejs v11.8.0
And chrome 71
class Foo extends null {}
new Foo() instanceof null
Thrown:
TypeError: Super constructor null of Foo is not a constructor
at new Foo (repl:1:1)
Doesn't look like expected behavior :/
In case it's expected then there should be a link to current expected behavior which was bug fixed
Can someone explain this?
0 == null -> false
0 == -null -> true
0 === null -> false
0 === -null -> true
Wtf?
It's interesting that passing Infinity
as delay
parameter while setTimeout()
called, the function will executed immediately instead of infinity delay.
setTimeout(() => console.log('called'), Infinity)
I thought you could expand on the NaN being a number type a little.
Type of NaN is a 'number':
typeof NaN; // -> 'number'
+ isNaN(NaN); // -> true
this is almost seemingly contradicting itself because it tells you that NaN is type number, but that NaN is indeed not a number. i understand it makes sense but at first glance i think it makes you think "wtf?"
also, NaN === NaN
or NaN == NaN
is false both times but may not be as applicable to this section
I'd like to help translating to brazilian portuguese. There is any procedure or guidelines I should follow?
thx for the props! lots of ppl helped bring wtfjs to fruition --recently rebirthed the site if you're interested in contributing bits there too! https://wtfjs.com (at https://github.com/brianleroux/wtfjs.com)
(sorry for the issue----wish there was a way to send props in github! 🙏 ❤️ )
Primitive types aren't instances of object wrappers.
42 instanceof Number; //false
Symbol() instanceof Symbol; // false
'foo bar' instanceof String; // false
false instanceof Boolean; // false
I am curious if the default behaviour of array.sort
method worth a WTF?
> [0,1,2,3,4,5,6,7,8,9,10].sort()
[ 0, 1, 10, 2, 3, 4, 5, 6, 7, 8, 9 ]
Explanation:
According to documentation the syntax is arr.sort([compareFunction])
and compareFunction
- is an optional paramter, if ommited the array is sorted according to each character's Unicode code point value, according to the string conversion of each element.
To correctly sort an array of ints valid compareFunction
must be provided:
> [0,1,2,3,4,5,6,7,8,9,10].sort((a,b) => a - b)
[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.