#TIL : Bypass CORS by using JSONP callback

Sometimes you are blocked from request a cross-origin resource. Instead of adding our domain to allowed list of them, we can use another way to retrieve data from their API by using JSONP (in case they support it).

The mechanism of JSONP is simple, instead of returning a JSON data. It will return a javascript text with passing your data into a function, whose name is declared in query string. So you just add a new script element with the URL and waiting the callback.

Example :

1
2
3
4
5
6
7
8
function callMeBaby(data) {
console.log(data);
}

var s = document.createElement("script");
s.type = "text/javascript";
s.src = "https://freegeoip.net/json/?callback=callMeBaby";
document.head.appendChild(s);

or using jQuery (hide magic)

1
2
3
4
5
6
7
8
$.ajax({
url: "https://freegeoip.net/json/",
jsonp: "callback",
dataType: "jsonp",
success: function( data ) {
console.log( data );
}
});

#TIL : Debug js code using console.trace

Browsers provide an useful function help you debug easier than using simple console.log function.

That is console.trace, which prints a stack trace to called function.

Example :

1
2
3
4
5
6
7
8
9
10
function foo() {
var a = 1;
bar(a);
}
function bar(x) {
console.log(x);
console.trace();
}

foo();

#TIL : Define property of an object in hacking way

Sometimes, we want to define a property of an advanced object (has setter and getter function).

Now, we could use this helper function Object.defineProperty to define property of an object in a cool way.

Example :

1
2
3
4
5
6
7
8
9
10
const foo = {};

Object.defineProperty(a, 'bar', {
value: 'hogehoge',
writable: false,
});

console.log(foo.bar); // 'hogehoge'
foo.bar = 'foo bar'; // throw an error in strict mode
console.log(foo.bar); // still be 'hogehoge'

Modifying setter, getter function

1
2
3
4
5
6
7
8
9
10
11
// Get callstack which function is getting or setting cookie value
Object.defineProperty(document, 'cookie', {
get: function() {
console.log('get !');
console.trace();
},
set: function(val) {
console.log('set = ', val);
console.trace();
},
});

#TIL : Eval function and with block

JS code will be slower if engine detects any of ‘eval’ function or ‘with’ block b/c compiler stop optimizing the code

#TIL : Scope and Closure

Run this code

1
2
3
4
5
for (var i=1; i<=5; i++) {
setTimeout( function timer(){
console.log( i );
}, i*1000 );
}

What you expected

1
2
3
4
5
1
2
3
4
5

But, result is

1
2
3
4
5
6
6
6
6
6

Solution is

1
2
3
4
5
6
7
for (var i = 1; i <= 5; i++) {
setTimeout((function timer(j) {
return function() {
console.log(j);
}
})(i), i * 1000);
}

or

1
2
3
4
5
6
7
for (var i=1; i<=5; i++) {
(function(j){
setTimeout( function timer(){
console.log( j );
}, j*1000 );
})(i);
}