Global footprint
最后更新于:2022-04-01 03:13:00
# Global footprint
If you are developing a module, which might be running on a web page, which also runs other modules, then you must beware the variable name overlapping.
Suppose we are developing a counter module:
~~~
var myCounter = {
number : 0,
plusPlus : function(){
this.number : this.number + 1;
},
isGreaterThanTen : function(){
return this.number > 10;
}
}
~~~
> ***Note:*** this technique is often used with closures, to make the internal state immutable from the outside.
The module now takes only one variable name — `myCounter`. If any other module on the page makes use of such names like `number` or `isGreaterThanTen` then it's perfectly safe, because we will not override each others values;
Enumeration
最后更新于:2022-04-01 03:12:58
# Enumeration
The `for in` statement can loop over all of the property names in an object. The enumeration will include functions and prototype properties.
~~~
var fruit = {
apple: 2,
orange:5,
pear:1
},
sentence = 'I have ',
quantity;
for (kind in fruit){
quantity = fruit[kind];
sentence += quantity+' '+kind+
(quantity===1?'':'s')+
', ';
}
// The following line removes the trailing coma.
sentence = sentence.substr(0,sentence.length-2)+'.';
// I have 2 apples, 5 oranges, 1 pear.
~~~
Delete
最后更新于:2022-04-01 03:12:56
# Delete
`delete` can be used to **remove a property** from an object. It will remove a property from theobject if it has one. It will not look further in the prototype chain.Removing a property from an object may allow a property from the prototype chain to shine through:
~~~
var adult = {age:26},
child = Object.create(adult);
child.age = 8;
delete child.age;
/* Remove age property from child, revealing the age of the prototype, because then it is not overriden. */
var prototypeAge = child.age;
// 26, because child does not have its own age property.
~~~
Prototype
最后更新于:2022-04-01 03:12:53
# Prototype
Every object is linked to a prototype object from which it inherits properties.
All objects created from object literals (`{}`) are automatically linked to Object.prototype, which is an object that comes standard with JavaScript.
When a JavaScript interpreter (a module in your browser) tries to find a property, which You want to retrieve, like in the following code:
~~~
var adult = {age: 26},
retrievedProperty = adult.age;
// The line above
~~~
First, the interpreter looks through every property the object itself has. For example, `adult` has only one own property — `age`. But besides that one it actually has a few more properties, which were inherited from Object.prototype.
~~~
var stringRepresentation = adult.toString();
// the variable has value of '[object Object]'
~~~
`toString` is an Object.prototype's property, which was inherited. It has a value of a function, which returns a string representation of the object. If you want it to return a more meaningful representation, then you can override it. Simply add a new property to the adult object.
~~~
adult.toString = function(){
return "I'm "+this.age;
}
~~~
If you call the `toString` function now, the interpreter will find the new property in the object itself and stop.
Thus the interpreter retrieves the first property it will find on the way from the object itself and further through its prototype.
To set your own object as a prototype instead of the default Object.prototype, you can invoke `Object.create` as follows:
~~~
var child = Object.create(adult);
/* This way of creating objects lets us easily replace the default Object.prototype with the one we want. In this case, the child's prototype is the adult object. */
child.age = 8;
/* Previously, child didn't have its own age property, and the interpreter had to look further to the child's prototype to find it.
Now, when we set the child's own age, the interpreter will not go further.
Note: adult's age is still 26. */
var stringRepresentation = child.toString();
// The value is "I'm 8".
/* Note: we have not overridden the child's toString property, thus the adult's method will be invoked. If adult did not have toString property, then Object.prototype's toString method would be invoked, and we would get "[object Object]" instead of "I'm 8" */
~~~
`child`'s prototype is `adult`, whose prototype is `Object.prototype`. This sequence of prototypes is called **prototype chain**.
Reference
最后更新于:2022-04-01 03:12:51
# Reference
Objects are **never copied**. They are passed around by reference.
~~~
// Imagine I had a pizza
var myPizza = {slices: 5};
// And I shared it with You
var yourPizza = myPizza;
// I eat another slice
myPizza.slices = myPizza.slices - 1;
var numberOfSlicesLeft = yourPizza.slices;
// Now We have 4 slices because myPizza and yourPizza
// reference to the same pizza object.
var a = {}, b = {}, c = {};
// a, b, and c each refer to a
// different empty object
a = b = c = {};
// a, b, and c all refer to
// the same empty object
~~~
Mutable
最后更新于:2022-04-01 03:12:49
# Mutable
The difference between objects and primitive values is that **we can change objects**, whereas primitive values are immutable.
~~~
var myPrimitive = "first value";
myPrimitive = "another value";
// myPrimitive now points to another string.
var myObject = { key: "first value"};
myObject.key = "another value";
// myObject points to the same object.
~~~
Properties
最后更新于:2022-04-01 03:12:46
# Properties
Object's property is a `propertyName`: `propertyValue` pair, where **property name can be only a string**. If it's not a string, it gets casted into a string. You can specify properties **when creating** an object **or later**. There may be zero or more properties separated by commas.
~~~
var language = {
name: 'JavaScript',
isSupportedByBrowsers: true,
createdIn: 1995,
author:{
firstName: 'Brendan',
lastName: 'Eich'
},
// Yes, objects can be nested!
getAuthorFullName: function(){
return this.author.firstName + " " + this.author.lastName;
}
// Yes, functions can be values too!
};
~~~
The following code demonstates how to **get** a property's value.
~~~
var variable = language.name;
// variable now contains "JavaScript" string.
variable = language['name'];
// The lines above do the same thing. The difference is that the second one lets you use litteraly any string as a property name, but it's less readable.
variable = language.newProperty;
// variable is now undefined, because we have not assigned this property yet.
~~~
The following example shows how to **add** a new property **or change** an existing one.
~~~
language.newProperty = 'new value';
// Now the object has a new property. If the property already exists, its value will be replaced.
language['newProperty'] = 'changed value';
// Once again, you can access properties both ways. The first one (dot notation) is recomended.
~~~
Creation
最后更新于:2022-04-01 03:12:44
# Creation
There are two ways to create an `object` in JavaScript:
1\. literal
~~~
var object = {};
// Yes, simply a pair of curly braces!
~~~
> ***Note:*** this is the **recomended** way.
2\. and object-oriented
~~~
var object = new Object();
~~~
> ***Note:*** it's almost like Java.
Objects
最后更新于:2022-04-01 03:12:42
# Objects
The primitive types of JavaScript are `true`, `false`, numbers, strings, `null` and `undefined`. **Every other value is an `object`.**
In JavaScript objects contain `propertyName`: `propertyValue` pairs.
Higher order
最后更新于:2022-04-01 03:12:40
# Higher Order Functions
Higher order functions are functions that manipulate other functions.For example, a function can take other functions as arguments and/or produce a function as its return value.Such *fancy* functional techniques are powerful constructs available to you in JavaScript and other high-level languages like python, lisp, etc.
We will now create two simple functions, `add_2` and `double`, and a higher order function called `map`. `map` will accept two arguments, `func` and `list` (its declaration will therefore begin `map(func,list)`), and return an array. `func` (the first argument) will be a function that will be applied to each of the elements in the array `list` (the second argument).
~~~
// Define two simple functions
var add_2 = function(x) {
return x + 2;
};
var double = function(x) {
return 2 * x;
};
// map is cool function that accepts 2 arguments:
// func the function to call
// list a array of values to call func on
var map = function(func, list) {
var output=[]; // output list
for(idx in list) {
output.push( func(list[idx]) );
}
return output;
}
// We use map to apply a function to an entire list
// of inputs to "map" them to a list of corresponding outputs
map(add_2, [5,6,7]) // => [7, 8, 9]
map(double, [5,6,7]) // => [10, 12, 14]
~~~
The functions in the above example are simple. However, when passed as arguments to other functions, they can be composed in unforeseen ways to build more complex functions.
For example, if we notice that we use the invocations `map(add_2, ...)` and `map(double, ...)` very often in our code, we could decide we want to create two special-purpose list processing functions that have the desired operation baked into them. Using function composition, we could do this as follows:
~~~
process_add_2 = function(list) {
return map(add_2, list);
}
process_double = function(list) {
return map(double, list);
}
process_add_2([5,6,7]) // => [7, 8, 9]
process_double([5,6,7]) // => [10, 12, 14]
~~~
Now let's create a function called `buildProcessor` that takes a function `func` as inputand returns a `func`-processor, that is, a function that applies `func` to each input in list.
~~~
// a function that generates a list processor that performs
var buildProcessor = function(func) {
var process_func = function(list) {
return map(func, list);
}
return process_func;
}
// calling buildProcessor returns a function which is called with a list input
// using buildProcessor we could generate the add_2 and double list processors as follows:
process_add_2 = buildProcessor(add_2);
process_double = buildProcessor(double);
process_add_2([5,6,7]) // => [7, 8, 9]
process_double([5,6,7]) // => [10, 12, 14]
~~~
Let's look at another example.We'll create a function called `buildMultiplier` that takes a number `x` as input and returns a function that multiplies its argument by `x` :
~~~
var buildMultiplier = function(x) {
return function(y) {
return x * y;
}
}
var double = buildMultiplier(2);
var triple = buildMultiplier(3);
double(3); // => 6
triple(3); // => 9
~~~
Exercise
Define a function named `negate` that takes `add1` as argument and returns a function, that returns the negation of the value returned by `add1`. (Things get a bit more complicated ;) )
~~~
var add1 = function (x) {
return x + 1;
};
var negate = function(func) {
// TODO
};
// Should return -6
// Because (5+1) * -1 = -6
negate(add1)(5);
~~~
Declare
最后更新于:2022-04-01 03:12:37
# Declaring Functions
Functions, like variables, must be declared. Let's declare a function `double` that accepts an **argument** called `x` and **returns** the double of x :
~~~
function double(x) {
return 2 * x;
}
~~~
> *Note:* the function above **may** be referenced before it has been defined.
Functions are also values in JavaScript; they can be stored in variables (just like numbers, strings, etc ...) and given to other functions as arguments :
~~~
var double = function(x) {
return 2 * x;
};
~~~
> *Note:* the function above **may not** be referenced before it is defined, just like any other variable.
Exercise
Declare a function named `triple` that takes an argument and returns its triple.
~~~
~~~
Functions
最后更新于:2022-04-01 03:12:35
# Functions
Functions, are one of the most powerful and essential notions in programming.
Functions like mathematical functions perform transformations, they take input values called **arguments** and **return** an output value.
Do…While
最后更新于:2022-04-01 03:12:33
# Do...While Loop
The do...while statement creates a loop that executes a specified statement until the test condition evaluates to be false. The condition is evaluated after executing the statement. Syntax for do... while is
~~~
do{
// statement
}
while(expression) ;
~~~
Lets for example see how to print numbers less than 10 using `do...while` loop:
~~~
var i = 0;
do {
document.write(i + " ");
i++; // incrementing i by 1
} while (i < 10);
~~~
> ***Note***: `i = i + 1` can be written `i++`.
Exercise
Using a do...while-loop, print numbers between less than 5.
~~~
var i = 0;
~~~
While
最后更新于:2022-04-01 03:12:30
# While Loop
While Loops repetitively execute a block of code as long as a specified condition is true.
~~~
while(condition){
// do it as long as condition is true
}
~~~
For example, the loop in this example will repetitively execute its block of code as long as the variable i is less than 5:
~~~
var i = 0, x = "";
while (i < 5) {
x = x + "The number is " + i;
i++;
}
~~~
The Do/While Loop is a variant of the while loop. This loop will execute the code block once before checking if the condition is true. It then repeats the loop as long as the condition is true:
~~~
do {
// code block to be executed
} while (condition);
~~~
**Note**: Be careful to avoid infinite looping if the condition is always true!
Exercise
Using a while-loop, create a variable named `message` that equals the concatenation of integers (0, 1, 2, ...) as long as its length (`message.length`) is less than 100.
~~~
var message = "";
~~~
For
最后更新于:2022-04-01 03:12:28
# For Loop
The easiest form of a loop is the for statement. This one has a syntax that is similar to an if statement, but with more options:
~~~
for(condition; end condition; change){
// do it, do it now
}
~~~
Lets for example see how to execute the same code ten-times using a `for` loop:
~~~
for(var i = 0; i < 10; i = i + 1){
// do this code ten-times
}
~~~
> ***Note***: `i = i + 1` can be written `i++`.
Exercise
Using a for-loop, create a variable named `message` that equals the concatenation of integers (0, 1, 2, ...) from 0 to 99.
~~~
var message = "";
~~~
Loops
最后更新于:2022-04-01 03:12:26
# Loops
Loops are repetitive conditions where one variable in the loop changes. Loops are handy, if you want to run the same code over and over again, each time with a different value.
Instead of writing:
~~~
doThing(cars[0]);
doThing(cars[1]);
doThing(cars[2]);
doThing(cars[3]);
doThing(cars[4]);
~~~
You can write:
~~~
for (var i=0; i < cars.length; i++) {
doThing(cars[i]);
}
~~~
Length
最后更新于:2022-04-01 03:12:24
# Length
Arrays have a property called length, and it's pretty much exactly as it sounds, it's the length of the array.
~~~
var array = [1 , 2, 3];
// Result: l = 3
var l = array.length;
~~~
Exercise
Define the variable a to be the number value of the length of the array
~~~
var array = [1, 1, 2, 3, 5, 8];
var l = array.length;
var a =
~~~
Indices
最后更新于:2022-04-01 03:12:21
# Indices
So you have your array of data elements, but what if you want to access a specific element? That is where indices come in. An **index** refers to a spot in the array. indices logically progress one by one, but it should be noted that the first index in an array is 0, as it is in most languages. Brackets [] are used to signify you are referring to an index of an array.
~~~
// This is an array of strings
var fruits = ["apple", "banana", "pineapple", "strawberry"];
// We set the variable banana to the value of the second element of
// the fruits array. Remember that indices start at 0, so 1 is the
// second element. Result: banana = "banana"
var banana = fruits[1];
~~~
Exercise
Define the variables using the indices of the array
~~~
var cars = ["Mazda", "Honda", "Chevy", "Ford"]
var honda =
var ford =
var chevy =
var mazda =
~~~
Arrays
最后更新于:2022-04-01 03:12:19
# Arrays
Arrays are a fundamental part of programming. An array is a list of data. We can store a lot of data in one variable, which makes our code more readable and easier to understand. It also makes it much easier to perform functions on related data.
The data in arrays are called **elements**.
Here is a simple array:
~~~
// 1, 1, 2, 3, 5, and 8 are the elements in this array
var numbers = [1, 1, 2, 3, 5, 8];
~~~
Concatenate
最后更新于:2022-04-01 03:12:17
# Concatenate conditions
Furthermore you can concatenate different conditions with "or” or “and” statements, to test whether either statement is true, or both are true, respectively.
In JavaScript “or” is written as `||` and “and” is written as `&&`.
Say you want to test if the value of x is between 10 and 20—you could do that with a condition stating:
~~~
if(x > 10 && x < 20) {
...
}
~~~
If you want to make sure that country is either “England” or “Germany” you use:
~~~
if(country === 'England' || country === 'Germany') {
...
}
~~~
**Note**: Just like operations on numbers, Condtions can be grouped using parenthesis, ex: `if ( (name === 'John' || name === 'Jennifer') && country === 'France')`.
Exercise
Fill up the 2 conditions so that `primaryCategory` equals `"E/J"` only if name equals `"John"` and country is `"England"`, and so that `secondaryCategory` equals `"E|J"` only if name equals `"John"` or country is `"England"`
~~~
var name = "John";
var country = "England";
var primaryCategory, secondaryCategory;
if ( /* Fill here */ ) {
primaryCategory = "E/J";
}
if ( /* Fill here */ ) {
secondaryCategory = "E|J";
}
~~~