This is a topic that I like to give anyone interviewing for a JS position at my company. It's a bit of a brain-twister, and unless you really understand how prototypal inheritance works in JS, there's a pretty good chance you'll get it wrong.
What's the difference between:
1. var objB = Object.create(objA);
and
2. var objB = new objA();
When we write #1, objB's internal [[proto]] property points to the object that is objA. That means that when we execute something like:
var objA = {
a:42;
}
var objB = Object.create(objA); //objB.__proto__ === objA
console.log(objB.a);
However, when we have the following scenario, invoking a function as a constructor:
function objA(){
this.a = 42;
}
objA.prototype.b = 43;
var objB = new objA(); //objB.__proto__ === objA.prototype
console.log(objB.a); //42
console.log(objB.b); //43
console.log(objB.__proto__); //objA.prototype
So we see that when when use the new keyword with a function, the object that is created (objB) has it's internal [[proto]] pointing to the function's prototype property (objA.prototype).
A blog about Javascript. For topics on security and hacking, please see my security blog at http://guerresanslarmes.blogspot.com/
Saturday, June 4, 2016
Talking DOMball...
Hello all you baseball fans and JS wahoos, it's time for another season of baseball!!
It's also time for us to discuss the differences between two similar sounding words in Javascript, document, and window.
window is the global object in Javascript. It holds everything, like global variables, global functions, history, location, etc. Global functions, such as setTimeout and console, live on the window as well. Even document lives on the window.
console.log(window.setTimeout === setTimeout); // true
console.log(window.document === document); //true
window can also be thought of as the default scope or this keybinding in browser-based JS (environments like nodejs do not have a window object).
var x = 5; //x in global/window scope
console.log(this.x === window.x); //true
console.log(this === window); //true
document is the DOM. The DOM is a tree of nodes (html tags, like h1, div, span, etc), and may be thought of as an object-oriented representation of the HTML that makes up the page. For an example of what this tree looks like, check out this site:
https://gojs.net/latest/samples/DOMTree.html
document is immensely useful because it allows us to query and manipulate the DOM using Javascript. For example, to grab all h1 elements in the DOM, we would write:
var headers = document.getElementsByTagName('h1');
Check back later, when we'll continue our exploration of window and document.
It's also time for us to discuss the differences between two similar sounding words in Javascript, document, and window.
window is the global object in Javascript. It holds everything, like global variables, global functions, history, location, etc. Global functions, such as setTimeout and console, live on the window as well. Even document lives on the window.
console.log(window.setTimeout === setTimeout); // true
console.log(window.document === document); //true
window can also be thought of as the default scope or this keybinding in browser-based JS (environments like nodejs do not have a window object).
var x = 5; //x in global/window scope
console.log(this.x === window.x); //true
console.log(this === window); //true
document is the DOM. The DOM is a tree of nodes (html tags, like h1, div, span, etc), and may be thought of as an object-oriented representation of the HTML that makes up the page. For an example of what this tree looks like, check out this site:
https://gojs.net/latest/samples/DOMTree.html
document is immensely useful because it allows us to query and manipulate the DOM using Javascript. For example, to grab all h1 elements in the DOM, we would write:
var headers = document.getElementsByTagName('h1');
Check back later, when we'll continue our exploration of window and document.
Friday, May 27, 2016
Interview Prep
It's that time again.
Couple of companies, won't say which until the end. One is an unknown in terms of difficulty, the other can be assumed to have the hardest difficulty of any technical interview. Over the next few weeks, I will document my preparation and practice problems here. I'm not 100% sure which topics should be reviewed/covered, but here's what I'm starting with:
-Sass
-CSS (selectors, specificity, basic transitions/animations, psuedoclasses/elements)
-Basic responsive web refresher
-DNS
-Browsers - Chrome (caching, perf, rendering, etc).
-DOM API
-Javascript
-HTTP
-REST APIs
-Node/Mongo/SQL/Express
-Angular (mostly 1.x, some 2)
-Algorithms (noooooooooooo)
-Review basic dev tools like git/gerrit/npm
Time to go next level!
Couple of companies, won't say which until the end. One is an unknown in terms of difficulty, the other can be assumed to have the hardest difficulty of any technical interview. Over the next few weeks, I will document my preparation and practice problems here. I'm not 100% sure which topics should be reviewed/covered, but here's what I'm starting with:
-Sass
-CSS (selectors, specificity, basic transitions/animations, psuedoclasses/elements)
-Basic responsive web refresher
-DNS
-Browsers - Chrome (caching, perf, rendering, etc).
-DOM API
-Javascript
-HTTP
-REST APIs
-Node/Mongo/SQL/Express
-Angular (mostly 1.x, some 2)
-Algorithms (noooooooooooo)
-Review basic dev tools like git/gerrit/npm
Time to go next level!
Sunday, May 22, 2016
Solving a JS Coding Exercise : Building a Color Picker
This is an coding problem I was asked at an interview a year ago. I understood the concept during the interview, I knew what I had to do, but I didn't code it right in the 30 minutes and I failed the interview.
I did it in five minutes this time. See, practice does work!!
Part 1: Here's the deal. Build a color picker. There should be an input where a user can type in a hex color, like #aabbcc. Whatever color is written in the box should be displayed in a div on the screen. So if I type #aabbcc in the input field, I should see a div whose color is #aabbcc.
For this stage, go ahead and have the background color update whenever any change happens to the input box.
Part 2: Change this code to only update the color when the user clicks on a button.
Solution:
Pretty simple, we want an input that listens for either the 'input' event or a button that listens for the 'click' event. Our event handler should read the hex value from the input, and set the div's background color to that value.
HTML:
<input type="text" id="inputBox">
<button id="inputButton">
Pick Color
</button>
<div id="colorBox">
</div>
CSS:
#colorBox{
margin-top:20px;
height:100px;
width:100px;
border: 2px solid black;
background-color:#fff;
}
JAVASCRIPT For Part 2 (for part 1, listen to 'input' event instead of 'click':
var oInput = document.getElementById("inputBox");
var oButton = document.getElementById("inputButton");
var oBox = document.getElementById("colorBox");
oButton.addEventListener('click', updateColor,false);
function updateColor(){
var color = oInput.value;
oBox.style.backgroundColor = color;
}
I did it in five minutes this time. See, practice does work!!
Part 1: Here's the deal. Build a color picker. There should be an input where a user can type in a hex color, like #aabbcc. Whatever color is written in the box should be displayed in a div on the screen. So if I type #aabbcc in the input field, I should see a div whose color is #aabbcc.
For this stage, go ahead and have the background color update whenever any change happens to the input box.
Part 2: Change this code to only update the color when the user clicks on a button.
Solution:
Pretty simple, we want an input that listens for either the 'input' event or a button that listens for the 'click' event. Our event handler should read the hex value from the input, and set the div's background color to that value.
HTML:
<input type="text" id="inputBox">
<button id="inputButton">
Pick Color
</button>
<div id="colorBox">
</div>
CSS:
#colorBox{
margin-top:20px;
height:100px;
width:100px;
border: 2px solid black;
background-color:#fff;
}
JAVASCRIPT For Part 2 (for part 1, listen to 'input' event instead of 'click':
var oInput = document.getElementById("inputBox");
var oButton = document.getElementById("inputButton");
var oBox = document.getElementById("colorBox");
oButton.addEventListener('click', updateColor,false);
function updateColor(){
var color = oInput.value;
oBox.style.backgroundColor = color;
}
Saturday, May 21, 2016
Solving a JS Coding Exercise: Week 1
Hi Everyone,
I'm going to start a weekly series where I walk through an online Javascript coding exercise. These posts are to give you a feel for the kinds of questions that will be asked of you in Javascript interviews. I will be drawing these questions from sources I find online, from my own experience being interviewed, and from the questions I ask people when I interview them.
Try to solve the problem yourself before reading my solutions. Otherwise, you won't grow.
This problem comes courtesy of Chris Chen.
Time Limit(optional): You should be able to do this in under 30 minutes. I'd aim for 15mins or so.
Here's a link to the live coding exercise:
http://codepen.io/chris-chen-nbcuni/pen/mnfBG
If that doesn't work, here's the problem description:
HTML:
<!--
Instructions:
When the value changes in the text field, multiply the 2 values and display in span with ID total.
If the total is greater than 0, make the text green. Everything else make it red.
-->
<input id="value1" type="text" value="" /> x <span id="value2">1234</span> = <span id="total" class="other">?</span>
CSS:
.positive { color: green; }
.other { color: red; }
Javascript:
SOLUTION:
We need to perform a mathematical operation whenever someone changes the contents of the input box. Your first thought immediately should have been to assign an event listener to that input box. How?
// #1: get a reference to the input box and other elements
var oInput = document.getElementById('value1');
var CONST = 1234;
var oOutput = document.getElementById('total');
// #2: and assign it an event listener for the 'input' event
oInput.addEventListener('input',onInputEvent,false);
The input event fires whenever the contents of an <input> or <textarea> element change.
https://developer.mozilla.org/en-US/docs/Web/Events/input
You could probably solve this by listening to other events, but input makes the most sense here.
Now, we need to multiply the value in the <input> element by 1234 whenever the input changes, and check to see if it's greater than zero. We also want to display the product of this multiplication as well.
// #3: write out the function for the event listener
function onInputEvent(){
var nResult = CONST * parseInt(oInput.value);
oOutput.innerHTML = nResult;
if(nResult){
oOutput.classList.remove('other');
oOutput.classList.add('positive');
}else{
oOutput.classList.remove('positive');
oOutput.classList.add('other');
}
}
That does the trick. I prefer to get the references to the DOM elements outside of the listener function, so that they aren't rerun every time the event handler fires.
I'm going to start a weekly series where I walk through an online Javascript coding exercise. These posts are to give you a feel for the kinds of questions that will be asked of you in Javascript interviews. I will be drawing these questions from sources I find online, from my own experience being interviewed, and from the questions I ask people when I interview them.
Try to solve the problem yourself before reading my solutions. Otherwise, you won't grow.
This problem comes courtesy of Chris Chen.
Time Limit(optional): You should be able to do this in under 30 minutes. I'd aim for 15mins or so.
Here's a link to the live coding exercise:
http://codepen.io/chris-chen-nbcuni/pen/mnfBG
If that doesn't work, here's the problem description:
HTML:
<!--
Instructions:
When the value changes in the text field, multiply the 2 values and display in span with ID total.
If the total is greater than 0, make the text green. Everything else make it red.
-->
<input id="value1" type="text" value="" /> x <span id="value2">1234</span> = <span id="total" class="other">?</span>
CSS:
.positive { color: green; }
.other { color: red; }
Javascript:
SOLUTION:
We need to perform a mathematical operation whenever someone changes the contents of the input box. Your first thought immediately should have been to assign an event listener to that input box. How?
// #1: get a reference to the input box and other elements
var oInput = document.getElementById('value1');
var CONST = 1234;
var oOutput = document.getElementById('total');
// #2: and assign it an event listener for the 'input' event
oInput.addEventListener('input',onInputEvent,false);
The input event fires whenever the contents of an <input> or <textarea> element change.
https://developer.mozilla.org/en-US/docs/Web/Events/input
You could probably solve this by listening to other events, but input makes the most sense here.
Now, we need to multiply the value in the <input> element by 1234 whenever the input changes, and check to see if it's greater than zero. We also want to display the product of this multiplication as well.
// #3: write out the function for the event listener
function onInputEvent(){
var nResult = CONST * parseInt(oInput.value);
oOutput.innerHTML = nResult;
if(nResult){
oOutput.classList.remove('other');
oOutput.classList.add('positive');
}else{
oOutput.classList.remove('positive');
oOutput.classList.add('other');
}
}
That does the trick. I prefer to get the references to the DOM elements outside of the listener function, so that they aren't rerun every time the event handler fires.
Friday, May 20, 2016
Javascript's Type Coercion
Hi Everyone,
Today we are going to tackle an interesting, and somewhat controversial, topic in Javascript - Type Coercion.
Quick recap - Javascript DOES have types. You'd be surprised how often people get that simple fact wrong.
Javascript types are:
-Primitives-
number
string
boolean
undefined
null
-Complex-
Object
Symbol (ES6)
Type coercion is different from type conversion in that it is handled implicitly by the JS engine at runtime, as opposed to being handled explicitly by the author at writing time.
An example of type conversion would be:
1 + Number("12");
Here, we are explicitly converting the string "12" to a number by calling the function Number.
An implicit coercion would be:
1 + "12";
which returns the string "112". Somehow, our number 1 was coerced into a string!
So, coercion is basically what happens when you give the Javascript engine operands of different types, without explicitly converting one into the other.
Today, we are going to learn which rules Javascript applies when coercing values.
*A quick point before we begin. Every Javascript coercion will result in a scalar primitive value; either a number, string, or boolean. That's it! Never anything complex like an object or a function.
In section 9, the ES5 spec defines what are called abstract value operations. These are internal-only operations that are used in coercion. We will look at four of them here; ToString, ToNumber, ToBoolean, and ToPrimitive.
ToString:
Anytime a non-string value is coerced into a string, ToString is invoked internally.
For primitives, the result is pretty straightforward:
null -> "null"
undefined -> "undefined"
true -> "true"
42 -> "42"
Things are more interesting if you are trying to convert something like an object or a function.
Unless you choose to override an object's ToString method, it will use the default one of Object.prototype.toString(), which will return the internal [[Class]] property of that object. This is why you usually see something like "[object Object]" when you run something like console.log({});
See if you can predict the output of the following code:
true + " " + 42
Answer:
It's the string "true 42"
So far so good? Let's move on to the next abstract operation.
ToNumber:
This comes into play whenever a non-number value is forced to behave like a number - for example, in a mathematical operation. For example, in 3 - '2'; The string '2' needs to behave like a number.
Some basics, when toNumber is called on each of the following:
true -> 1
false -> 0
undefined -> NaN
null -> 0
strings will be NaN if it can't be coerced into a meaningful number.
"7" -> 7
"seven" -> NaN
Objects and arrays will first be converted to their primitive value ( one of the types we just discussed) via toPrimitive. From there, the resulting value is coerced to a number via toNumber.
You might be wondering just how toPrimitive takes something like an object and turns it into a primitive. In the next update, we will discuss just how this works.
ToPrimitive:
Today we are going to tackle an interesting, and somewhat controversial, topic in Javascript - Type Coercion.
Quick recap - Javascript DOES have types. You'd be surprised how often people get that simple fact wrong.
Javascript types are:
-Primitives-
number
string
boolean
undefined
null
-Complex-
Object
Symbol (ES6)
Type coercion is different from type conversion in that it is handled implicitly by the JS engine at runtime, as opposed to being handled explicitly by the author at writing time.
An example of type conversion would be:
1 + Number("12");
Here, we are explicitly converting the string "12" to a number by calling the function Number.
An implicit coercion would be:
1 + "12";
which returns the string "112". Somehow, our number 1 was coerced into a string!
So, coercion is basically what happens when you give the Javascript engine operands of different types, without explicitly converting one into the other.
Today, we are going to learn which rules Javascript applies when coercing values.
*A quick point before we begin. Every Javascript coercion will result in a scalar primitive value; either a number, string, or boolean. That's it! Never anything complex like an object or a function.
In section 9, the ES5 spec defines what are called abstract value operations. These are internal-only operations that are used in coercion. We will look at four of them here; ToString, ToNumber, ToBoolean, and ToPrimitive.
ToString:
Anytime a non-string value is coerced into a string, ToString is invoked internally.
For primitives, the result is pretty straightforward:
null -> "null"
undefined -> "undefined"
true -> "true"
42 -> "42"
Things are more interesting if you are trying to convert something like an object or a function.
Unless you choose to override an object's ToString method, it will use the default one of Object.prototype.toString(), which will return the internal [[Class]] property of that object. This is why you usually see something like "[object Object]" when you run something like console.log({});
See if you can predict the output of the following code:
true + " " + 42
Answer:
It's the string "true 42"
So far so good? Let's move on to the next abstract operation.
ToNumber:
This comes into play whenever a non-number value is forced to behave like a number - for example, in a mathematical operation. For example, in 3 - '2'; The string '2' needs to behave like a number.
Some basics, when toNumber is called on each of the following:
true -> 1
false -> 0
undefined -> NaN
null -> 0
strings will be NaN if it can't be coerced into a meaningful number.
"7" -> 7
"seven" -> NaN
Objects and arrays will first be converted to their primitive value ( one of the types we just discussed) via toPrimitive. From there, the resulting value is coerced to a number via toNumber.
You might be wondering just how toPrimitive takes something like an object and turns it into a primitive. In the next update, we will discuss just how this works.
ToPrimitive:
Wednesday, April 13, 2016
Debugging Minified Code
In this blog post, I'm going to step through a task that I'm currently focusing on at work. Sadly, it involves stepping through heavily minified code (with no code-maps), so it's going to be a bit of a doozy.
My employer doesn't open-source its code, but it's all js served to a client browser anyway, so basically public.
The Background: Part of our code injects a js package into a webpage which fires off tracking beacons to an external server at certain intervals. For example, if we inject an advertisement, it will fire a beacon when the ad is loaded (AD_LOADED), when the ad starts playing (AD_STARTED), when the ad has played 25%, 50%, etc.
The Bug: For some weird reason, in our minified code the AD_START beacon is firing twice, when it should fire only once. This isn't occurring in unminified code, so it sounds like a minification issue.
The Build: As part of our build process, we use the Google Closure Library's most optimized minification option (ADVANCED_OPTIONS). Some background on the compiler can be found on Google's site: https://developers.google.com/closure/compiler/docs/api-tutorial3#better
The Process: I've started by opening up my non-minified code in IntelliJ, and stepping though it to get a feel for how/when we are firing beacons. Once I am able to understand this in the non-minified code, I can start mapping it over to the minified code, and begin debugging there.
I'm using Chrome Dev tools to step through the code, and the Charles web proxy to monitor when beacons are firing.
This process goes on for several hours until I eventually discover the error. Closure is renaming the following property:
delete oSWFAdParameters.media.tracking
to
delete a.media.zk
and in this case, 'zk' is undefined, meaning that the tracking data is not being deleted, and is still being passed through to the AS3.
My employer doesn't open-source its code, but it's all js served to a client browser anyway, so basically public.
The Background: Part of our code injects a js package into a webpage which fires off tracking beacons to an external server at certain intervals. For example, if we inject an advertisement, it will fire a beacon when the ad is loaded (AD_LOADED), when the ad starts playing (AD_STARTED), when the ad has played 25%, 50%, etc.
The Bug: For some weird reason, in our minified code the AD_START beacon is firing twice, when it should fire only once. This isn't occurring in unminified code, so it sounds like a minification issue.
The Build: As part of our build process, we use the Google Closure Library's most optimized minification option (ADVANCED_OPTIONS). Some background on the compiler can be found on Google's site: https://developers.google.com/closure/compiler/docs/api-tutorial3#better
The Process: I've started by opening up my non-minified code in IntelliJ, and stepping though it to get a feel for how/when we are firing beacons. Once I am able to understand this in the non-minified code, I can start mapping it over to the minified code, and begin debugging there.
I'm using Chrome Dev tools to step through the code, and the Charles web proxy to monitor when beacons are firing.
This process goes on for several hours until I eventually discover the error. Closure is renaming the following property:
delete oSWFAdParameters.media.tracking
to
delete a.media.zk
and in this case, 'zk' is undefined, meaning that the tracking data is not being deleted, and is still being passed through to the AS3.
Saturday, March 28, 2015
Understanding Javascript's this keyword
Funny thing happened the other day. I'm talking to a developer who is designing a project using a MEAN stack, and we're discussing some best practices in JS. We're on the subject of Angular controllers when he says something to the effect of, "I don't really get why we always have to alias this as var self in out controllers. Isn't this always just a reference to that current class object?".
Uh-oh. This developer is a good friend of mine, and a very smart guy and an even sharper software engineer, but this underscores just how few people understand just what the keyword this actually means in Javascript. To be fair, it can have like four different bindings, so let's jump into how this actually works in Javascript:
Quick disclaimer, if you want to really understand the keyword this in JS, look no further than Kyle Simpson's excellent book here.
Ok, onto this. But first, there was something even more subtle in my fellow developer's confusion. Internally, Javascript doesn't have any notion of a class, at all. And it's dynamic, not static, so that whole thought pattern of "In Java or C++, this is a reference to the object itself bound at compile time" isn't going to serve you well.
Basically, in Javascript this is bound at runtime, and can point to one of four things, depending on how it is called:
1. if the new keyword is used, this points to the newly constructed object. As in:
function Person(name){
this.name = name;
}
var bob = new Person("bob");
bob.name; //bob
2. If there is any sort of explicit or hard-binding going on as evidenced by the use of call, apply, or bind, then this will point to the specified object. For example (taken from Kyle Simpson's book):
function foo(){
console.log(this.a);
}
var obj = {
a:2
};
var bar = function(){
foo.call(obj);
};
bar(); //2
setTimeout(bar,100); //2
bar.call(window); //2
With call(), bind(), etc the first parameter is basically the object to which this bound. So when bar calls foo() via call() and passes it obj, it is forcibly binding its internal call to foo with obj. This cannot be overwritten at a later time, as we see when we invoke bar.call(window) in the last line. In this case, we say that the binding of obj to the this reference in foo() is both explicit and strong, hence, hard-binding.
3. If there is an object that makes or "owns" the call, it is said to set the context for that object. In this case, this will look to that object for binding. For example:
var obj = {
a:2,
f:foo //hoisting, if you are curios why this works
};
var obj2 = {
a:4,
f:foo
};
function foo(){
console.log(this.a);
}
obj.foo(); //2
obj2.foo(); //4
4. The last case is when there is no other way to provide context to the object. In this case, the global scope is used. Unless we are using strict mode, in which case it is undefined.
function foo(){
console.log(this.a);
}
var a = 5;
foo(); // 5. Unless 'use strict'; at which point undefined
That's about it, just follow this checklist when you need to resolve a this binding issue. It's worth the time to study how binding can be forced, as in example 2, which will probably be the subject of a future blog post. Until then, happy Javascripting!
Uh-oh. This developer is a good friend of mine, and a very smart guy and an even sharper software engineer, but this underscores just how few people understand just what the keyword this actually means in Javascript. To be fair, it can have like four different bindings, so let's jump into how this actually works in Javascript:
Quick disclaimer, if you want to really understand the keyword this in JS, look no further than Kyle Simpson's excellent book here.
Ok, onto this. But first, there was something even more subtle in my fellow developer's confusion. Internally, Javascript doesn't have any notion of a class, at all. And it's dynamic, not static, so that whole thought pattern of "In Java or C++, this is a reference to the object itself bound at compile time" isn't going to serve you well.
Basically, in Javascript this is bound at runtime, and can point to one of four things, depending on how it is called:
1. if the new keyword is used, this points to the newly constructed object. As in:
function Person(name){
this.name = name;
}
var bob = new Person("bob");
bob.name; //bob
2. If there is any sort of explicit or hard-binding going on as evidenced by the use of call, apply, or bind, then this will point to the specified object. For example (taken from Kyle Simpson's book):
function foo(){
console.log(this.a);
}
var obj = {
a:2
};
var bar = function(){
foo.call(obj);
};
bar(); //2
setTimeout(bar,100); //2
bar.call(window); //2
With call(), bind(), etc the first parameter is basically the object to which this bound. So when bar calls foo() via call() and passes it obj, it is forcibly binding its internal call to foo with obj. This cannot be overwritten at a later time, as we see when we invoke bar.call(window) in the last line. In this case, we say that the binding of obj to the this reference in foo() is both explicit and strong, hence, hard-binding.
3. If there is an object that makes or "owns" the call, it is said to set the context for that object. In this case, this will look to that object for binding. For example:
var obj = {
a:2,
f:foo //hoisting, if you are curios why this works
};
var obj2 = {
a:4,
f:foo
};
function foo(){
console.log(this.a);
}
obj.foo(); //2
obj2.foo(); //4
4. The last case is when there is no other way to provide context to the object. In this case, the global scope is used. Unless we are using strict mode, in which case it is undefined.
function foo(){
console.log(this.a);
}
var a = 5;
foo(); // 5. Unless 'use strict'; at which point undefined
That's about it, just follow this checklist when you need to resolve a this binding issue. It's worth the time to study how binding can be forced, as in example 2, which will probably be the subject of a future blog post. Until then, happy Javascripting!
Friday, March 27, 2015
Extending Native Types in JS
Saw this as an interview question the other day, and thought it was pretty interesting.
The question, in its original form is:
The question, in its original form is:
Define a repeatify function on the String object. The function accepts an integer that specifies how many times the string has to be repeated. The function returns the number of times specified. For example:
console.log('hello'.repeatify(3));
prints hellohellohello
The first step in attacking this problem is to realize what it is asking us to do. We need to define a property on the String object that we can use on native string types like 'hello'. More to the point, we need to define this on the prototype object of String so that 'hello' can find it via [[prototype]] delegation. This, we want something like:
String.prototype.repeatify = function(n){
var ret = '';
for(var i = 0; i < n; i++){
ret += this;
}
return ret;
}
console.log('hello'.repeatify(3)); //hellohellohello
This is great, and does what we want. But there is something missing here - can you spot it?
What if we are trying to polyfill this repeatify function, but it already exists (or may exist) on String? Our above code would simply overwrite the existing functionality, which is probably bad. Thus, we add an extra step:
String.prototype.repeatify = String.prototype.repeatify || function(n){
var ret = '';
for(var i = 0; i < n; i++){
ret += this;
}
return ret;
}
console.log('hello'.repeatify(3)); //hellohellohello
And that's it!
Thursday, March 26, 2015
Polyfilling Object.create in pre-ES5 Environments
As you might be aware, there are two primary ways of creating a [[prototype]] link between two objects in Javascript:
Using Object.create()
var obj1 = {
a:2
};
var obj2 = Object.create(obj1);
console.log(obj2.a); //2
Using a function as a constructor
function Obj1(){
this.a = 2;
}
var obj2 = new Obj1();
console.log(obj2.a); //2
In both cases, obj2.a will return a value of 2, although in the first case the property 'a' actually lives on obj1 and is found through [[prototype]] delegation, whereas in the second, "constructed" case, the property 'a' actually lives on obj2.
Generally speaking, it is somewhat cleaner to use Object.create() to link an object to another as opposed to making a function call as a construction (imagine if Obj1() had some sort of side effects in addition to just returning an object). However, in some older environments it is necessary to create a partial polyfill of Object.create(), which can be accomplished very easily with the following code snippet:
if( !Object.create ){
Object.create = function(o){
function F(){};
F.prototype = o;
return new F();
};
}
In line one we check to see if the function already exists, if not, we begin defining it in line two by creating the 'create' property on Object and assigning it a function that takes an object as its argument. in line three, we create a throw-away function called F, and set its prototype object to the parameter 'o'. We then return a new instance of F(), which will be linked to 'o', since that is what we reassigned F's prototype object to reference.
Pretty simple polyfill hack. Some developers argue that this isn't a best practice since we haven't technically completely polyfilled Object.create. Object.create an also take an option object of arguments that will be assigned to the object that it creates, such as:
var obj2 = Object.create(obj1, { b:{},c:{} });
In this case, we have to define each of these properties by hand, such as setting b's enumerable, writable, configurable descriptors, etc. This is not supported in pre ES5 browsers, but this form is very rarely used, so most developers are okay with the partial polyfill, but if it bothers you, it's okay to simply create a different function that handles the partial polyfill, such as:
function object_create_link(o){
function F(){};
F.prototype = o;
return new F();
}
var obj1 = {
a:2
};
var obj2 = object_create_link(obj1);
obj2.a; //2
That's a wrap. I like this example because it provides a nice discussion of how Object.create() and functions as constructors differ in creating an object.
Thanks for reading!
-nate
Monday, November 3, 2014
A Taste of Java...script. Hoisting
Javascript has been getting some popularity lately, and it's not really a secret. I've posted some links to my Twitter feed of recent articles that I've read detailing node.js and using Javascript for full-stack dev. I'll post them here as well:
http://www.toptal.com/nodejs/why-the-hell-would-i-use-node-js
http://www.toptal.com/javascript/guide-to-full-stack-javascript-initjs
Interesting stuff. This just means that now - more than ever - we as software engineers need to know how Javascript works, and we need to know it well if we want to use it for full-stack development.
The strange thing about Javascript is that it's well...strange. Devs coming from a background in C++ or Java, or even Python will be surprised at some of the things Javascript takes for granted, like hoisting...
This should break, right?
Example 1:
console.log(square(2));
function square(x){
return x*x;
}
but it doesn't. It produces 4 just like if you had written:
function square(x){
return x*x;
}
console.log(square(2));
hmm....okay. So this works too then?
Example 2:
console.log(square(2));
var square = function(x){
return x*x;
}
well...no, not at all. Example 1 runs perfectly, example 2 will generate an undefined reference error. So, what exactly is going on here?
In Javascript, there is something called variable hoisting, which applies to variables and functions, and basically moves them to the top of their enclosing scope (remember, in Javascript, functions define scope, not braces). This is because the Javascript compiler runs through the program first, allocates variables and references, and then the execution engine runs through and actually runs stuff. So in example 1, the compiler sees the function declaration, handles it, and then when the execution engine runs, it calls console.log(...) and finds the reference to the square function no problem.
Cool, so why does example 2 fail?
Well, to answer that, here's example 3:
console.log(x);
var x = 3;
Works, right? Nah, it's an undefined reference error too.
The deal is that variable declarations are hoisted, but assignments are not, so in example 3, the compiler more or less produces:
var x;
console.log(x);
x = 3;
So it's obvious why it's an undefined reference. It's basically the same for example 2. The Javascript compiler will generate the following code for the execution engine:
var square;
console.log(square(2));
square = function(x){
return x*x;
}
So, hoisting can come in handy in many situations, but be wary of the fact that it can catch you off guard sometimes.
Friday, September 26, 2014
Solving a subset of the Infinite Monkey Theorem in Python
Way back in the early part of the 20th century, a French mathematician by the name of Emile Borel had the zany idea that if you gently set a monkey in front of a typewriter and gave him an infinite amount of time (and paper, and ink, and probably banana incentives), that he would almost certainly type out any string of text (an example often cited is the complete works of Shakespeare, although it's more likely that Borel needed someone to type up a conference paper, and didn't have a PhD student on hand). There are variants of this theorem that involve an infinite number of typists, and so forth. Let's start with a simple example to check the reality of this theorem. Say we have a keyboard with only 26 keys - one for each letter of the English alphabet. The monkey sets to work trying to type out the string "Borel", note that we don't distinguish between a capitalized letter and a non-capitalized letter. The monkey has a 1/26 chance of typing any one letter, and assuming each keystroke is statistically independent, he then has a (1/26) * (1/26) * (1/26) * (1/26) * (1/26) = 8.4165e-8. Not exactly good odds, but not exactly zero - therefore statistically possibly.
Now, as a simple, fun exercise. Let's replace the monkey with a snake and write a Python script that tries to generate the Shakespeare quote "Live, Love, and let be". To make things a bit easier, we will ignore the uppercase and the commas for now and only search for the string "live love and let be".
Here is the code, in all of its simian glory:
import random
#live love and let be len==20
def generator(strlen):
sigma='abcdefghijklmnopqrstuvwxyz '
result = ''
for i in range(strlen):
result = result + sigma[random.randrange(27)]
return result
Now, as a simple, fun exercise. Let's replace the monkey with a snake and write a Python script that tries to generate the Shakespeare quote "Live, Love, and let be". To make things a bit easier, we will ignore the uppercase and the commas for now and only search for the string "live love and let be".
Here is the code, in all of its simian glory:
import random
#live love and let be len==20
def generator(strlen):
sigma='abcdefghijklmnopqrstuvwxyz '
result = ''
for i in range(strlen):
result = result + sigma[random.randrange(27)]
return result
def score_function(target_str,gen_str):
score = 0.0
for i in range(len(target_str)):
if target_str[i] == gen_str[i]:
score = score + 1
return score / len(target_str)
def main():
target = 'live love and let be'
gen = generator(20)
best_score = 0
curr_score = score_function(target, gen)
while curr_score < 1:
if curr_score > best_score:
print gen,curr_score
best_score = curr_score
gen = generator(20)
curr_score = score_function(target, gen)
main()
I let this run for a few minutes on an Intel i3 with 2GB ram, and the highest match I saw was a 0.4.
Let's go ahead and break down the algorithm at a higher level, and then delve into it line by line. We basically want to generate a random string of characters of some length using the generator function. We then want to see how well that generated string of characters compares to our target Shakespeare quote by using the score function. Score returns a value between 0 and 1. 0 meaning none of the characters matched, and 1 meaning it was a direct hit. We then use our main routine to generate and score strings until we find a perfect match, all the while providing updates on what the longest match so far was.
Subscribe to:
Posts (Atom)