Austin Story

Ruby, Rails and Javascript Blog

Powered by Genesis

Javascript Var Definitions Gotcha

December 19, 2016 By Austin Story Leave a Comment

This is one of the most common gotchas in Javascript.

What does this code do inside of a function?

‘var a = b = 0;’

Since javascript is right associative for assignments, at first glance you might expect it to create and set the variables a and b to 0. But there is a subtle gotcha hidden here. It actually does this

var a; //compile step initializes memory for a

b = 0; //we are in a scope, since b is not initialized in this scope (compile step misses it), javascript will go up the scope chain, assuming no parent scopes have b variable, the global scope will initialize var b for us and send it back.
a = b;

So more englishy, a is functionally scoped to the local function because it has the var in front of it. b is defined implicitly so it is put on the global scope.

Here is an example that demonstrates this further

[code]
function foo() {
var a = b = ‘assign in foo’;
function bar() {
var c = d = ‘assign in bar nested in foo’;
c; // ‘assign in bar nested in foo’
d; // ‘assign in bar nested in foo’
}
bar();
a; // ‘assign in foo’
b; // ‘assign in foo’
c; // ReferenceError, c only available in bar function
d; // ReferenceError, d available in bar and globally
}

foo();

a; // ReferenceError, because a is functionally scoped to the foo function
b; // ‘assign in foo’
c; // ReferenceError, because c is functionally scoped to the bar function
d; // ‘assign in bar nested in foo’
[/code]

After the invocation of foo in the code above, both b and d are now global variable.

Filed Under: Javascript Tagged With: gotchas, Javascript

What is a thunk in javascript?

October 25, 2016 By Austin Story 2 Comments

A thunks is a function that contains all of the context (state, functions, etc) it will need in order to carry out some sort of logic in the future.

Another way to say that, they are a function closure that begins with all of the arguments it will need in order to execute. You just don’t want to execute it now, it will be sometime in the future.

Synchronous Example

[code]
const add = (x,y) => x + y;

const thunk = () => add(1,2);

thunk() // 3
[/code]

 

Asyncrhonous

[code]
const addAsync = (x,y,callback) => {
setTimeout(function() { callback(x + y) }
}

var thunk = (callback) => addAsync(10,15,callback);

thunk( function() {
sum; // 25
}
[/code]

Filed Under: Javascript, Theory Tagged With: Javascript, thunk

ES6 Desctructuring with Spread Operator

June 4, 2016 By Austin Story Leave a Comment

Destructuring in ES6 deals with take either an Array or an Object, and get or set variables based on the elements of that Array or Object.

First lets talk about the syntax. To destructure something in ES6 you put … in front of the Array or Object you are wanting to pull apart.
[javascript]
//Array example
var numbers = [1,2,3];

console.log(numbers) //logs [1,2,3]
console.log(…numbers) //logs 1, 2, 3
[/javascript]

In the second example, … has precedence so the [1,2,3] is first split into 3 separate values, then console.log(…numbers) becomes console.log(1,2,3).

That is how we easily get at them, here is an example of the setting pattern.
[javascript]
function getAddress() {
return {city: ‘St. Louis’, state: ‘Missouri’, country: ‘USA’}
}

let {city, state, country} = getAddress();

console.log(city, state, country) //logs ‘St. Louis’, ‘Missouri’, ‘USA’
[/javascript]

This works because we know that getAddress will return a value that is matching what we have in curly braces on the left. So we know getAddress will return a city, so we call it city in the let.

We can also alias variables in our let statement, in the example below, we tell javascript to map the value of getAddress().city to cityAlias locally.
[javascript]
let {city: cityAlias, state, country} = getAddress();

console.log(cityAlias, state, country) //logs ‘St. Louis’, ‘Missouri’, ‘USA’
console.log(city) //Reference error because city is not defined
[/javascript]

You can use this pattern anywhere and it may be more readable. Here is an example in a function call.
[javascript]
function printUserAddress({city, state, country}) {
console.log(city, state, country);
}

printUserAddress(getAddres());
////logs ‘St. Louis’, ‘Missouri’, ‘USA’
[/javascript]

You can also set default values to deal with cases where the object passed in does not have the value you are trying to get.
[javascript]
function printUserAddress({city, state, country, zip=’N/A’}) {
console.log(city, state, country, zip);
}

printUserAddress(getAddres());
//logs ‘St. Louis’, ‘Missouri’, ‘USA’, ‘N/A’
[/javascript]

Under the hood here are the rules.

{} on the left means that the object on the right MUST have the properties, or it will be an error
[javascript]
function printUserAddress({city, state, country, zip}) {
console.log(city, state, country, zip);
}

printUserAddress(getAddres());
//throws b/c zip is not in the object
[/javascript]

You can bypass the throw by adding a ? in front of the attribute which may or may not be defined
[javascript]
//zip is optional
function printUserAddress({city, state, country, ?zip}) {
console.log(city, state, country, zip);
}

printUserAddress(getAddres());
//logs ‘St. Louis’, ‘Missouri’, ‘USA’, ‘undefined’

//entire object is optional
function printUserAddress(?{city, state, country, zip}) {
console.log(city, state, country, zip);
}

printUserAddress(getAddres());
//logs ‘St. Louis’, ‘Missouri’, ‘USA’, ‘undefined’
[/javascript]

Filed Under: ES6, Javascript Tagged With: ES6, Javascript

  • 1
  • 2
  • Next Page »

Categories

  • AngularJS
  • Books
  • Devise
  • Elasticsearch
  • ES6
  • Information Security
  • Integrations
  • Javascript
  • Linux
  • Minitest
  • PhoneGap
  • Programming
  • React
  • Redux
  • Ruby
  • Ruby on Rails
  • Stripe
  • Testing
  • Theory
  • TypeScript
  • Uncategorized
  • Vue
  • Webpack