Sie sind auf Seite 1von 11

JS Notes

General Notes
---------------------------------------
* JS is the language of the WWW.
* Scripting language that is functional as well as object oriented.
* Many libraries have been written in it to help you interact with the
web:
- jQuery
- MooTools
- Prototype
- etc.
. Knowing these libraries doesn't mean you actually know JS though.
* Arrays shouldn't use ( for in ). Takes too long.
* Utilizes short circuit eval (second part of a boolean argument only
executed if first arg is true)
- can use this for variable assignment b/c return type of &&, || is
the type of the last argument (not defaulted to boolean)
. i.e.
a = a || 1;
. is equivalent to
a = (a == false) ? 1 : a;
* Use === instead of ==
- former checks for type as well

JavaScript: The Good Parts
---------------------------------------
CHAPTER 1 - Overview
* JS was a rushed language. There are good parts but also bad
parts that shouldn't be used.
- In general, one should seek the good parts of any
language and master them. Figure out the bad and try to avoid them.
* Document Object Model (DOM) is the API of the browser, and
is written very poorly. JS interacts with it.
* Very good ideas implemented such as: functions, loose
typing, dynamic objects & expressive object literal notation.
- Bad ideas include that it's programming model is based on
global variables
* Lambda language and has more in common with Lisp and Scheme
than Java.
- Basically meaning it's functional and can use anonymous
functions
* Functions are first class objects:
- A first class object is an entity that can be dynamically
created, destroyed,
passed to a function, returned as a value,
and have all the rights as other variables in the
programming language.
* JS(Lint/Hint) are great tools to analyze JS
CHAPTER 2 - Specifies the grammar of the language
* Can use // & /* */ for commenting. The latter isn't safe to
use for code because */ can appear in code.
* Numbers are numbers: represented as 64-bit floats (like JAVA
double)
- No designation between int, float, double, etc.
- can use e or E w/ + or - for exponent
- NaN represents a value that can't be produced normally
. It's not equal to anything, including itself.
. Test for it with isNan( number )
- Infinity represents all values greater than
1.79769313486231570e+308
- Global Math object has methods
* Strings use " & ' the same way. No notion of a Character.
- Have a length property
- Have their own methods
* Block statement: {...} do NOT create a new scoope
* Only statements that eval to false:
- false
- null
- undefined (NOT the same as null)
- The empty string ''
- The number 0
- The number NaN
* Has normal statements expected in other languages:
- also has for in statement
E.g.
for (var prop in obj) {
if ( obj.hasownProperty( prop ) ) {
...
}
}
. hasOwnProperty checks if the property name is from the obj
or from the Prototype chain.
* typeof producers: 'number', 'string', 'boolean',
'undefined', 'function', or 'object'
- if the operand is an array or null it returns 'object' -
for better or worse

CHAPTER 3 - Objects
* Almost everything is an object in JS
* They are mutable (can be changed i.e. not final), keyed
collections
* Basically a container of properties. Each property has a
name and value -> {name : value}
* Class-free w/ no naming contraints
* JS has prototype linkage to allow property inheritance
* Can be empty and can hold other objects
E.g.
var flight = {
airline: "Oceanic",
number: 815,
departure: {
IATA: "SYD",
time: "2004-09-22 14:55",
city: "Sydney"
},
arrival: {
IATA: "LAX",
time: "2004-09-23 10:42",
city: "Los Angeles"
}
};
- values can be accessed two ways:
. flight["airline"]
. flight.airline
. later is preferred
- if you try to retrieve a nonexistent member i.e.
flight.pilot - undefined will be returned
- a TypeError is returned if you try to retrieve something
from an undefined object i.e. flight.pilot.name
. safe practice is to test for flight.pilot &&
flight.pilot.name before doing anything with flight.pilot.name
* Pass by Reference
* Every object is linked to a prototype which it inherits
properties from
* Any object made from an object literal inherits from
Object.prototype
* Adding the following function allows user to select the
prototype of an object (function name is irrelevant):
if (typeof Object.beget !=== 'function') {
Object.beget = function (o) {
var F = function () {};
F.prototype = o
return new F();
};
}
- then you can add a prototype to an object like so:
var new_flight = Object.beget(flight);
- Making changes to an object doesn't affect prototype, the
reverse isn't true. Changing the prototype affects ancestors immed.
* using a global variable to hold your app greatly improves
the resilency of your apps
- reduces chances of bad interactions
with other apps
i.e.
var MYAPP = {};
MYAPP.flight = {
airline: "Oceanic",
number: 815,
departure: {
IATA: "SYD",
time: "2004-09-22 14:55",
city: "Sydney"
},
arrival: {
IATA: "LAX",
time: "2004-09-23 10:42",
city: "Los Angeles"
}
};
MYAPP.flight.airline -> "Oceanic"
CHAPTER 4 - Functions
* Functions are objects.
- all functions are linked to Function.prototype, which is
linked back to Object.prototype
- functions also created with:
. hidden context of the function
. hidden code which implements function
. a prototype property that holds a constructor (it's value
is an object constructor whose value is the function:
function func = {
prototype: {
constructor: func
},
context : hidden..,
code : hidden..
};
* behave just like an object, but also can be invoked
* When function invoked it's given two parameters:
- arguments
- this
. value dependent on invocation pattern: method, function,
constructor or apply are the different patterns
* When function is a property of an object and/or invoked
with . or ["property"] expression it uses the method pattern
- (this) is the object which called it.
* When function isn't a property of an object it uses the
function pattern
- (this) is bound to the global object...not much of use to
the programmer b/c inner functions can't use the outer objects (this)
- There is a workaround Have the object's method declare
another variable as it's this:
var that = this;
- now within inner (helper) functions, that can be used to
refer to the outer object instead of the global object
* If a function is invoked with the (new) prefix it will use
the constructor pattern
- think of it like a constructor in OOP
- literally is almost exactly a constructor when implemented
as such
- holds hidden link to the functions prototype
- (this) is the new object that is created
* Functions can have methods. calling the apply() method on a
function lets us constuct an array of arguments to use on invocation
- takes to arguments:
. value of (this)
. array of arguments
- Think of apply as applying this functions essence to
another function.
* Functions are also given an arguments array
- it holdsthe arguments given to function: including those
not specified.
E.g.
var sum = function ( ) {
var i, sum = 0;
for (i = 0; i < arguments.length; i
+= 1) {
sum += arguments[i];
}
return sum;
};
- arguments ins't really an array - it doesn't have all the
array methods
- it does have the length property though
* All functions return an object something...if you don't
specify it'll return 'undefined'
- if a function invokes the constructor pattern and it's
return value isn't an object, (this) is returned
* Exceptions can the thrown with an Exception object:
throw {
name : "Type of Error"
message: "message..."
}
* Acts like other exception functionality -> try/catch/finally
methodology
* Adding a function to a prototype (as stated earlier) adds
the function to all inherited objects
- using this function allows you to call the prototype
object w/o using the prototype prop. and add a method
E.g.
Function.prototype.method = function (name, func) {
this.prototype[name] = func;
return this;
};

- Then you can say, add an integer method to all numbers to
pull out the integer part of the number

Number.method('integer', function ( ) {
return Math[this < 0 ? 'ceiling' : 'floor']
(this);
});
(10.5).integer(); => 10
- you can use this to enhance the JS language
- b/c the basic types are public it is easy to contaminate
other apps
- use this construct when defining methods on prototypes to
guard against this:
Function.prototype.method = function (name, func) {
if (!this.prototype[name]) {
this.prototype[name] = func;
}
};
. conditional method declaration
* Recursive functions - need to work on my knowledge of these
in all aspects of comp sci.
- good for walking the DOM's tree-like structure
- JS doesn't support tail recursive optimization (tail call
opt.)
. this is when a compiler will not allocate new stack space
if the tail call in a function is a call to another function

Not Tail recursion:
var factorial = function(n) {
if (n < 2)
return n;
else
return n * factorial(n-1);
};

Tail recursive counterpart:
var tailRecFactorial = function(n,a) {
a = a || 1;
if (n < 2)
return a;
else
return factorial(n - 1, a * n);
};
* Scope is not block - like most modern languages
- Any variable in defined in a function is visible anywhere
in the function
. it's best to define all variables used in the function at
the beginning of the function

* Closure allows for a function to have access to the context
(or state, if you will) in which it was created
- if a function has access to other variables from an outer
function,
when that outer function has ended, the inner function
still has access to those variables
. Bad Example:
// Make a function that assigns event handler
functions to an array of nodes the wrong way.
// When you click on a node, an alert box is
supposed to display the ordinal of the node.
// But it always displays the number of nodes
instead.
var add_the_handlers = function (nodes) {
var i;
for (i = 0; i < nodes.length; i +=
1) {
nodes[i].onclick = function
(e) {
alert(i);
}
}
};
. Good Example:
// Make a function that assigns event handler
functions to an array of nodes the right way.
// When you click on a node, an alert box
will display the ordinal of the node.
var add_the_handlers = function (nodes) {
var i;
for (i = 0; i < nodes.length; i +=
1) {
nodes[i].onclick = function
(i) {
return function (e)
{
alert(i);
};
}(i);
}
};
* Can use functions and closure to make modules
- Module is a function or object that presents an interface
but hides its state and implementation
* jQuery's method chaining is a side-effect of standard JS
behaviour (cascades)
- allowed when a method has no return type
* Currying is a functional programming thing...don't feel like
learning it at the moment, but no that it might come back up.
- basically when you take a function which takes multiple
args and break it down
into many functions which take part of the arguments
- there's also something called partial application which
isn't the same thing
* Memoization is another programming construct not exclusive
to JS
- using objects to remember the results of previous
operations
- example can be shown with fibonacci sequence
. Normal version makes so many calls to itself
var fibonacci = function (n) {
return n < 2 ? n : fibonacci(n - 1)
+ fibonacci(n - 2);
};
. Memoized version keeps an array that stores previous calls
to the same function with the same arg.
. This cuts down on how many times a certain function will
actually be called.
var fibonacci = function (n) {
var memo = [0,1];
var fib = function (n) {
var result = memo[n];
if (typeof result !==
'number') {
result = fib(n-1) *
fib(n-2);
memo[n] = result;
}
return result;
};
return fib;
}( );
. Using a memoizer function you can cut down the amount of
work done to create memoized
. Such a function takes in the memo object and a fundamental
function, then creates a shell of the function
which manages the memo object and
var memoizer = function (memo, fundamental) {
var shell = function (n) {
var result = memo[n]
if (typeof result !==
'number') {
result =
fundamental(shell, n);
memo[n] = result;
}
return result;
};
return shell;
};
. Then to use this to create fibonacci or factorial try:
var fibonacci = memoizer(memo[0,1], function
(shell, n) {
return shell(n-1) + shell(n-2);
}; // memo holds the base cases for the
fibonnaci function
var factorial = memoizer(memo[1,1] function
(shell, n) {
return n * shell(n-1);
}; // memo holds the base case for the
factorial function
CHAPTER 5 - Inheritance
* 3 major inheritance patters:
- Pseudoclassical
- Prototypal
- Functional
* JS is pseudoclassical. Instead of directly inheriting from
other objects new objects are created using constructor funcs
- Pseudoclassicalness is kind of ugly, but we can augment
the language to clean it up.
- Basically you can decide what an objects immediate prototype
is my assigning an object to its prototype property
- must use the (new) operator or (this) will be bound to the
global object
Var Cat = function (name) {
this.name = name;
this.saying = "meow";
};
Cat.prototype = new Mammal() // assuming a class
Mammal exists
- can also create functions like 'inherits' to help with
pseudoclassical coding
- Constructor functions should be capitalized
- I'm not compelled to use the pseudoclassical nature of JS
* Object specifiers instead of multi arg functions can make
constructor functions easier to use:
- This:
var myObject = maker({
first: f,
last : l,
state: s,
city : c
});
- Instead of this:
var myObject = maker(f, l, s, c);
* Prototypal is pretty easy
- No Classes!
- Just create a useful object. When you need one like it,
just create a new object that inherits from it.
- Only deal with objects and decide on the differences
between then as need be (differential inheritance)
* Functional Pattern adds benefit of privacy:
- We will create a new function (functional constructor)that
creates objects (like a constructor function but (new)
will not be used with it)
. First it creates a new object
- in whatever way it feels is right
. can define instance variables and functions (will be
private but can be defined as usual with the (var) keyword
. augments new object with methods
. returns the new object
- Functional pattern is suggested inheritance pattern for
javascript - from this book

CHAPTER 6 - Arrays
* Not what I think is an array
* Array Literal format:
var empty = [];
var numbers = ['zero', 'one', two', 'three']
* has a length property
- it's not an upper bound
* has a push() method that adds an element to the end of the
array
* can use delete to remove elements
- leaves a hole...better to use splice
* splice() takes two args:
- where you should start deleting
- how many elements to delete
- it updates the array by moving everything to the right of
the deletion over to the left by how many elements were deleted
* Since Arrays are objects it's hard to distinguish between
the two...typeof array is actually an object so you much
check for an arrays constructor === Array as well as it's
type being 'object'
- this doens't work, however for arrays made in different
windows and frames so this is a more stable, albeit longer vers:
var is_array = function (value) {
return value &&
typeof value === 'object' &&
typeof value.length ===
'number' &&
typeof value.splice ===
'function' &&
!
(value.propertyIsEnumerable('length'));
};
* Arrays aren't really multi-dim but you can mimick by having
an array of arrays
CHAPTER 7 - Regex
* Methods that work with them:
- regexp.exec
- regexp.test
- string.match
- string.replace
- string.search
- string.split
* Need to understand this from more of a general point before
I can dive into JS issues
* JS has a RegExp Object with properties and methods
CHAPTER 8 - Methods
* Reference of the standard methods on the standard objects of
the language
CHAPTER 9 - Style
* Notes on authors styling conventions
CHAPTER 10 -
* Excerpt of the author's writing from another book on beautiful
code

Das könnte Ihnen auch gefallen