Tuesday, February 2nd 2016
The issue:
http://jsbin.com/miweje/edit?js,console
The link is meant to demonstrate the different behavior of Object.create with functions vs. objects. Native properties can be accessed with Object.create for objects, but NOT for functions. So in regards to the challenges, I thought that the Object.create was a method used on functions, not realizing that they are also used on objects. So, if in the challenges, obj1 and obj2 were functions, (not objects - though functions are objects....yeah) then the Object.create would make it so that obj2 would NOT be able to access obj1.x. However, because they WERE objects, obj2 had access to obj1 via the prototype chain. So...why? Prototype inheritance of course!
Object.create()
"The Object.create() method creates a new object with the specified prototype object and properties."
Object.create() creates a new object with the prototype object and properties. The keyword here is prototype object. Why does this matter? Well lets check this out:
var obj1 = {x:10};
var obj2 = Object.create(obj1);
console.log(obj2.x); //10;
console.log(Object.keys); // []
Object.create extends obj2's prototype chain, such that when we call on obj2.x, it is forced to look up the prototype chain because x is not a native property of obj2. But check this out:
var bird = Object.create(Animal);
bird.prototype = Object.create(Animal.prototype);
console.log(bird.x); //undefined
What?? That's crazy! Well, not really. When we look at what the prototype object is, we can actually see it references the Animal function as a whole:
function() { this.x = 10; };
Because its referencing a function rather than a specific set of properties, our bird variable does not have access to the x property. It does, however, have access to that constructor function.
new
var obj1 = {x:10};
var obj2 = new obj1; //error!
An error? What, why? Because obj1 is not a function.
"The new operator creates an instance of a user-defined object type or of one of the built-in object types that has a constructor function."
We cannot use the new keyword to extend the prototype object of objects. They can only (reasonably) be used on function objects. Whereas, if we use it correctly:
var Animal = function () { x:10 };
var bird = new Animal();
console.log(Object.keys(bird)); //['x'];
The new keyword invokes the constructor function, thereby creating another object that has access to the constructor function's native properties. It doesn't have to look in the prototype chain. Therefor, bird has its own 'this.x' property that is equal to '10'.
The main difference between Object.create() and new in regards to functions is that Object.create() doesn't fire the constructor. With Object.create, you have the option of firing the object constructor that forms the prototype of the new object, where as in the new Function() form, the declared properties/functions do not form the prototype.
It's as Johnathan Kvicky, mentor, said, ""Very simply said, new X is Object.create(X.prototype) with additionally running the constructor function. (And giving the constructor the chance to return the actual object that should be the result of the expression instead of this)".
References:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain
http://javascript.info/tutorial/inheritance
http://www.htmlgoodies.com/html5/tutorials/javascript-prototypical-inheritance-explained.html#fbid=WDOO4VJLwnp
Getting Shit Done takes a combination of language proficiency, problem solving and google-fu. Take a look at how I briefly review topics of interest to help everyday programmers gain quick, simple and fundamental knowledge of not-so-simple programming concepts.
Monday, January 25, 2016
Tuesday, January 19, 2016
Polymorphism, Constructors and setInterval
Monday, February 1st 2016
Instantiation Types:
Instantiation Types:
- Polymorphism, Subclasses and prototype Inheritance
- Reviewing most of the instantiation patterns helped me realize how powerful polymorphism can be, particularly when it pertains to managing methods in the prototype chain. To do this before, you would have to go back, change all of your code (functional, functional-shared) to make changes to your methods. But with Psuedoclassical code, we can simply append changes to the methods at any point in time, and it can change the superclass and the subclasses alike, in one spot. But we already knew that ;p.
- Polymorphism refers to the idea that we can design objects to share behaviors (method access) across multiple subclasses in an easy way. However, we have to watch out for the context 'this', and sometimes ensure our context is correct by 'bind'ing our 'this' contexts. Polymorphism = object design to share behaviors.
- Prototype inheritance just refers to prototype chain extension. So if your building a Car superclass and car's generally 'turn on', then it would make sense to share this behavior with all subclasses of Cars, including subclasses like 'mercedes' and 'vw'
- Examples here: http://jsbin.com/vazutoj/edit?js,console
- Recursion Permutations
- So the toy problem was difficult today, but it was important. We had to come up with a function, either with the use of for loops (messy and iffy) or recursion (solid), to express the sequential possibilities of rock paper scissors after 'x' number of rounds.
- While there are a number of different ways to solve this, this is the solution that was handed to us (was disappointed that I couldn't figure it out).
- var rockPaperScissors = function (rounds) {var rpsArray = ['r', 'p', 's'];var results = [];var recurse = function (currentArray) {if(currentArray.length === rounds) {results.push(currentArray);return;}for (var i = 0; i < rpsArray.length; i++) {recurse(currentArray.concat(
rpsArray[i])); }};recurse([]);//Concat results to match expected formatif(results.length > 1) {for(var i = 0; i < results.length; i++){results[i] = results[i].reduce(function(a, b) {return a + b;}, '');}}return results;}; - The first part simply establishes an set array of possibilities. This rpsArray is important to the function because the set range of possibilities remains constant. It is either 'rock' or 'paper' or 'scissors'. We also establish an array of results, whereby we'll push each permutation.
- The second part is our recursive function. Our base case is if the length of the currentArray is equal to the rounds, then we will return that specific solution. Our recursive function will iterate through and concate each combination of our rpsArray, then call back on the recurse function. Once a '1', '2', '3' etc digit number is reached, it will push that into our results array.
- The third part is a simple concat function that combines our results, making them into strings using a reduce method.
- Even after reviewing it, it's difficult for me to understand. I think recursion is one of those things that takes a lot of practice to get used to. Also, I'm not so sure that some of the people who figured it out used outside sources to help them, or if they really did figure it out on their own. If they figured it out on their own, I'd love to see the code!
- Object.create() vs new
- Bird.prototype = Animal.prototype;
- all changes you make to the latter will also be reflected in
Animal
and all other classes that inherit from it. not good! - Bird.prototype = new Animal();
- animal requires arguments, which you may not want to pass any into and invoking animal may have unintended side effects, like increasing a counter instance.
- Bird.prototype = Object.create(Animal.prototype);
- No real drawbacks. This is what we should use.
- setInterval vs. setTimeout
setTimeout(expression, timeout);
runs the code/function once after the timeout.setInterval(expression, timeout);
runs the code/function in intervals, with the length of the timeout between them.- There is a significant performance discrepency between the two. Only use setInterval for minute or limited tasks, as this can really bog down your rig if used incorrectly.
Friday, January 15, 2016
Closures
Friday, January 15th 2016
- Closures are typically referred to a variable, not a function, (closure variables) because they refer to values that are outside of their own native scope.
- var createCounter = function () {
- var counter = 0;
- return function () {
- counter+= 1;
- return counter;
- };
- };
- var myCounterX = createCounter();
- myCounterX();
- myCounterX();
- var result1 = myCounter();
- //What is the value of resutl1? Answer: 3. Why?
- Does NOT fire on declaration.
- First call, counter = 1;
- Second call, counter = 2;
- when assigned to result1, it is fired for a 3rd and final time, equating to 3.
- var result = 0;
- for(var i=0; i < 3; i++) {
- setTimeout(function() {
- result += i;
- }, 1000);
- }
- What is the result of result? Answer: 9. Why?
- SetTimeout stores values in some invisible event loop behind the curtains until the code has fully finished running. Afterwards, the for loop (not the event loop!) finished iterating, i is 3, upon which the 3 saved setTimeout functions then fire, adding 3 + 3 + 3 = 9.
- var x = 10;
- function inc () {
- return x + 1;
- }
- How many closures? Answer: 1. Why?
- function window () {
- var x = 10;
- function inc () {
- return x + 1;
- }
- }
- inc closes over window (through variable x);
- var x = 10;
- function inc (x) {
- return x + 1;
- }
- How many closures? Answer: 0. Why?
- No reference is made to the outside scope. All variables within the function in are native.
- var add = function (x, y) {
- return x + y;
- };
- var double = function (x) {
- return add(x, x);
- };
- How many closures? Answer: 1. Why? Think of it as:
- function double (x) {
- function add (x, y) {
- return x + y;
- }
- return add(x, x);
- }
- add is nested within double via x, because add is accessing double's (x) parameter in the computation.
- var x = 10;
- var add = function (y) {
- return x + y;
- };
- var double = function (x) {
- return add(x);
- };
- How many closures? Answer: 2. Wtf why?
- Don't let add() fool you. The parameter names never have, never will matter.
- The x variable in add is being taken from the global scope, whereas y is the value of x from the double scope.
- Ok, enough of closures. I'm going to redo my post for yesterday to do a brief summary on the first two of four advanced data structures. I'll cover the last two here.
- Hashed functions.
- There was a lot of confusion over this topic for the entire class, including me, due to miscommunication in the program. Anyways, after a day, we all got it.
- So arrays are awesome because they are O(1) for accessing (arr[54]; //'cat'; BAM), but are not so awesome for inserting (unless push), searching, or deleting values because the entire collection is contiguous.
- Can we make is such that the entire process is, more or less, constant? Yes we can!
- Turns out that obj's key:value pair isn't the BEST way to store information. Arrays got the right ideas. Why? Because computer can iterator through numbers much more quickly than strings, and keys in objs are converted to strings! Hence the obj['key'].
- Knowing this, we can translate the key, using some hash function, into an address via sequence of numbers and then store the key:value pair into a point in storage using that address. If we want that value, we simply use the hash function to convert our key to retrieve the value. BAM! Constant!
- But what if our hash function sucks? What if I give it a key for some value, but then another value gets return?
- 'theCatGoes': 'Meow!'; -> hash f(x) -> Address: 1212
- 'theCowGoes': 'Moo!'; -> hash f(x) -> Address: 1212
- request 'key1' -> hash f(x) -> 1212 -> 'theCatGoesMoo!' //Wait, wtf?!
- Hint: cat's don't moo.
- So what happened? We didn't adjust our hash table (the place that stores all of the key-value pairs and addresses) to deal with 'collisions'. A collision takes place when you give the hash function a key, and get the wrong value back (the key shares the same address as another). To avoid this, we next our [k, p] in another [], and add a condition whereby the system checks if there is another existing value in the collection and if so, simply adds the additional [k, p] to the address. (Notice its nest in an array). Accessing the right value for a key is done via checking each nested array.value for the same value, since we know what the value is...hence why we know the key:value pair was wrong in the first place.
- OKAY, so what does all that shit mean? It means that 99% of the time, hash functions will be O(1), but when there is a collision, it is O(n) because it has to iterator through an array of arrays to check for each [k,v].
- BAM! Examples of using hash functions are:
- Encryption
- Think about it. The hash function is the encryption device that 'encrypts' or 'translates' some value into some other value. In this case, it's done to boost efficiency (via numerical index vs. str-based index).
- google (results are instantaneous and I think someone said they use hash functions)
BigO Time Complexity
Wednesday, January 13th 2016
- Big-0 complexity analysis (time)
- Where n is the number of inputs, what is the relationship between n and time to compute?
- O(1) - Constant
- No matter the number of inputs (1 or 10^100), the function will take the same amount of time to compute. As n grows, time remains constant.
- Eg:
- Looking through an array
- hash table insertion
- O(log(n))
- As the number of inputs (1 or 10^100) grows, time to compute will increase but at a decreasing rate.
- Eg:
- Binary Search
- O(n) - Linear
- The number of inputs (1 or 10^100) will impact the performance of the function, whether it is 2n, 4n, or 100n, it doesn't matter (the rate of growth is constant). As n grows, time will grow at some constant pace (multiple of n).
- Eg:
- Finding an element in an unsorted array
- O(n^2) - Quadratic
- The time to compute n increases at an increasing rate.
- Eg:
- multiplying two n's using a simple algorithm
- operations/functions nested within one another
- bubble, shell, selection, insertion sort
- O(c^n) - Exponential
- Each computation is an order of magnitude(>=10) based on each additional n
- Eg:
- brute force password hacking (each digit could be any number of possibilities)
- brute-force search
Thursday, January 14, 2016
Basic Data Structures and Instantiation Styles
Tuesday, January 12th 2016
- Basic Data Structures and Instantiation Styles:
- Stacks
- Last in, first out (LiFo)
- Data organized like plates. After washing a plate, you pile it on top of an already existing pile of plates. When you need a plate, you take the one on top. Stack = pile of plates.
- 0 -> []; 1-> [0]; 2 -> [0, 1]; 3 -> [0, 1, 2]; [0, 1, 2, 3] -> 3; [0, 1, 2] -> 2;
- Queue
- First in, first out (FiFo)
- Data organized like people in line at a grocery store. The first ones to enter the line are the first to exist the line.
- 0 -> []; 1 -> [0]; 2 -> [0, 1]; [0, 1, 2] -> 0; [1, 2] -> 1;
- Instantiation patterns (http://callmenick.com/post/instantiation-patterns-in-javascript)
- Confiding into a single pattern with respect to creating a new class object. The realization of a new object with class properties that are shared with others, using a specific style (or pattern).
- Functional Instantiation
- var Func = function () {
- someInstance = {};
- var a = 1;
- someInstance.logA = function () { console.log(1); }
- return someInstance;};
- var myFunc = func();
- func.logA() //1
- Creating an object within a function so that every time the function is called we have methods that are attached to that object.
- Pros: Readability. It's obvious how the code works.
- Cons: This pattern creates a new set of functions in memory for each instance of that function, making it awfully inefficient in enterprise-level software.
- Functional Shared Instantiation
- var Func = function () {
- someInstance = {};
- var a = 1;
- _.extend(someInstance, funcMethods)
- return someInstance; };
- var funcMethods = {};
- funcMethod.logA = console.log(this.a);
- var myFunc = Func();
- someInstance.logA() //1
- Creating a function and an object with methods and then conjoining the two such that the instance created within the function shares the same methods as the outside object.
- Pros: Allows for greater memory management because methods are referenced outside of the function rather than from within itself.
- Cons: If we want to edit the methods at some point in the future, we cannot easily do so because all of the changes to the objects before the change still retain those old methods.
- Prototypal Instantiation
- var Func = function () {
- someInstance = Object.create(funcMethods);
- someInstance.a = 1;
- return someInstance; };
- var funcMethods = {};
- funcMethods.logA = console.log(1);
- var myFunc = Func();
- myFunc.logA() //1
- Despite its name, this instantiation doesn't actually utilize the prototype keyword. Rather, it attaches the methods from the Object.create(*obj*) to the prototype chain of 'someInstance'.
- Pros: Allows for you to change the methods in funcMethods easily, since all you have to do is change the source obj (funcMethods) in the prototype chain.
- Cons: Apparently, not many, though this instantiation pattern is not as idiomatic and the psuedoClassical.
- Psuedo-Classical Instantiation
- var Func = function() {
- this.a = 1;};
- Func.prototype.logA = function () { console.log(1) };
- var myFunc = new Func();
- myFunc.logA() // 1
- Instances are created with the 'new' keyword rather than the Object.create() method. Though it retains the same functionality as the prototypal instantiation (utilizes prototype-chains to keep methods attached to realized object classes)
- Pros: Less code and apparently the most efficient instantiation pattern. Its also the most idiomatic and is often used in enterprise-level code.
- Cons: None, its perfect unless you have no idea how 'this' is utilized.
References:
https://www.cs.cmu.edu/~adamchik/15-121/lectures/Stacks%20and%20Queues/Stacks%20and%20Queues.html
http://stackoverflow.com/questions/10974922/what-is-the-basic-difference-between-stack-and-queue
http://www.ryanatkinson.io/javascript-instantiation-patterns/
https://www.cs.cmu.edu/~adamchik/15-121/lectures/Stacks%20and%20Queues/Stacks%20and%20Queues.html
http://stackoverflow.com/questions/10974922/what-is-the-basic-difference-between-stack-and-queue
http://www.ryanatkinson.io/javascript-instantiation-patterns/
Subscribe to:
Posts (Atom)