Skip to content

Instantly share code, notes, and snippets.

@begeeben
Last active August 29, 2015 14:01
Show Gist options
  • Save begeeben/50942c8e22ca641a7050 to your computer and use it in GitHub Desktop.
Save begeeben/50942c8e22ca641a7050 to your computer and use it in GitHub Desktop.
common javascript scoping problems
// TBC
// call
// apply
// bind
var user = {
firstName: 'Peter',
say: function (message) {
alert(message);
},
sayHi: function () {
alert('Hi, I\'m ' + this.firstName);
}
};
// the context calling the sayHi function after 1000ms is the global object
setTimeout(user.sayHi, 1000); // Hi, I'm undefined
// fix
// use bind to specify the context
setTimeout(user.sayHi.bind(user), 2000); // Hi, I'm Peter
// keep in mind that using bind creates another function
user.sayHi.bind(user) === user.sayHi // false
var arr = ['a', 'b', 'c'];
for (var i = 0; i < arr.length; i++){
setTimeout(function () {
alert(arr[i]); // undefined
}, 1000);
}
// the variable i is in the global scope
// when every alert runs after 1000 ms, i is 3 after the loop
// each trys to alert arr[3] which is undefined
// fix
// wrap the setTimeout in an immediate function and pass i by value
var arr = ['a', 'b', 'c'];
for (var i = 0; i < arr.length; i++){
(function(arr, i) {
setTimeout(function () {
alert(arr[i]);
}, 1000);
})(arr, i);
}
// the closure of sayIt function keeps track of the defaultMessage reference in the containing function
// so defaultMessage can be referred to after the say function returns
function say(message) {
var defaultMessage = message;
function sayIt(message) {
alert(defaultMessage + ' ' + message);
}
return sayIt;
}
var sayHello = say('hello');
sayHello('world'); // hello world
sayHello('javascript'); // hello javascript
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this
// note the difference in strict mode
function sayHello() {
alert(this.greeting);
}
sayHello(); // undefined
var greeting = 'hello world';
sayHello(); // hello world
// in strict mode: undefined
var guy = {};
guy.sayHello = sayHello;
guy.sayHello(); // undefined
guy.greeting = 'hi world';
guy.sayHello(); // hi world
var sayHi = guy.sayHello;
sayHi(); // hello world
// in strict mode: undefined
// intention:
// to make variables private
// http://en.wikipedia.org/wiki/Immediately-invoked_function_expression
(function () {
var message = 'hello world';
alert(message);
})();
// why passing window into the function
// http://stackoverflow.com/a/8275673/1400167
(function (window, undefined){
window.iQuery = window.iQuery || {};
})(window, undefined);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment