2015年9月8日星期二

[笔记] Speaking JavaScript Chapter 1

Speaking JavaScript

Preface

Don't get bogged down by the details.
JavaScript Command Lines: Node.js

Chapter 1: Basic JavaScript

1.1 Syntax

1.1.1 Overview of Syntax

// two slashes start single-line comments

var x; // declaring a variable

x = 3 + y; // assigning a value to the variable 'x'

foo(x, y); // calling function 'foo' with parameters 'x' and 'y'
obj.bar(3); // calling method 'bar' for object 'obj'

//A conditional statement
if (x === 0) { // Is 'x' equal to zero?
x = 123;
}

//Defining function 'baz' with parameters 'a' and 'b'
function baz(a, b) {
return a + b;
}

Note the two different uses of the equal sign:
(1) A single equals sign (=) is used to assign a value to a variable.
(2) A triple equal sign (===) is used to compare two values.


1.1.2 Statements v. Expression

statement: do things
expression: value

JS has two different ways to do if-then-else
(1) statement:
var x;
if (y >= 0) {
x = y;
} else {
x = -y;
}
(2) expression
var x = y >= 0 ? y : -y;


1.1.3 Semicolons: recommended

semicolons terminate statements, but not blocks. There is one case where you will see a semicolon after a block: a function expression is an expression that ends with a block.

var f = function () { }; // function expr. inside var decl.


1.2 Values

1.2.1 Primitive Values v. Objects

JavaScript makes a somewhat arbitrary distinction between values:
(1) The primitive values are booleans, numbers, strings, null and undefined.
(2) All other values are objects.

A major difference between the two is how they are compared; each object has a unique identity and is only(strictly) equal to itself.
In contrast, all primitive values encoding the same value are considered the same.

1.2.2 Primitive Values

(1) Compared by value: the "content" is compared
e.g. 3 === 3 , 'abc' === 'abc'

(2) Always immutable: properties can't be changed

> var str = 'abc';
> str.length = 1; // try to change property 'length'
> str.length // no effect
3

1.2.3 Objects

(1) Plain Objects
{
firstName: 'Jane',
lastName: 'Doe'
}

(2) Arrays
['apple', 'banana', 'cherry']

(3) Regular Expression
/^a+b+$/

(4) Characteristics
Comapred Reference:
1)
> {} === {}
false

2)
> var obj1 = {};
> var obj2 = obj1;
> obj1 === obj2;
true

Mutable by Default:
> var obj = {};
> obj.foo = 123; // add property 'foo'
> obj.foo
123

1.2.4 undefined and null

undefined: no value
null: no object

checking for undefined and null:
if (!x) {...}

1.2.5 typeof and instanceof

(1) type of value
> typeof true
'boolean'
>typeof null
'object' // this is a bug and cannot be fixed

(2) instance of
> {} instanceof Object
true

1.3 Booleans

JavaScript has two kinds of equalty:
(1) Normal, or "lenient", (in) equalty: == and !=
(2) Strict (in)equalty: === and !==
Normal equality is considered (too) many values to be equal (p84) which hide bugs. Therefore, always using strict equality is recommended.

1.4 Numbers

All numbers in JavaScript are floating-point
Special Numbers:
(1) NaN ("Not a Number")
> Number('xyz')
NaN
(2) Infinity: Infinity is LARGER and SMALLER than any other number
> 3 / 0
Infinity

1.5 Operators

+-*/%++--
The global object Math(P31) provides more arithmatic operators

1.6 Strings

slice/trim/indexOf

1.7 Functions

function add(param1, param2) {
return param1 + param2;
}

> add(6, 1)
7
> add('a', 'b')
'ab'

Another way of defining add() is:

var add = function (param1, param2) {
return param1 + param2;
};

1.7.1 Function and var declaration are hoisted, while assignments performed by them are not.

function foo() {
bar(); // OK, bar is hoisted
function bar() {
...
}
}

function foo() {
bar(); // Not OK, bar is still undefined
var bar = function() {
...
}
}

1.7.2 You can call any function in JavaScript with an arbitrary amount of arguments; the language will never complain.

1.7.3 special variable argument

1.8 Strict Mode

1.9 Variables Are Function-Scoped, Hoisted

1.10 Closure

Each function stays connected to the variables of the functions that surround it, even after it leaves the scope in which it is created.

function createIncrementor(start) {
return function() { // (1)
start++;
return start;
}
}

The function starting in line (1) leaves the context in which it is created, but stays connected to a live version of start:

> var inc = cerateIncrement(5);
> inc()
6
> inc()
7
> inc()
8

A closure is a function plus the connection to the variables of its surrounding scopes. Thus, what createIncrementor() returns a closure.

1.11 Objects and Constructors

1.11.1 Single Objects

You could consider an object to be a set of properties, where each property is a (key, value) pair. The key is a string, and the value is any JavaScript value.

'use strict'
var jane = {
name: 'Jane',

describe: function () {
return 'Person named' + this.name;
}
}

> jane.name // get
'Jane'
> jane.name = 'John'; // set
> jane.newProperty = 'abc'; // property created automatically

The in operator checks whether a property exists:

> 'newProperty' in jane
true
> 'foo' in jane
false

The delete operator removes a property:

> delete jane.newProperty
true

1.11.2 Arbitrary Property Keys

Use square brackets to get and set the property:

> var obj = { hello: 'world' };
> var x = 'hello';

> obj[x]
'world'
> obj['hel' + 'lo']
'world'

1.11.3 Extracting Methods

If you extract a method, it loses its connection with the object. On its own, the function is not a method anymore, and this has the value undefined (in strict mode).

Extract the method describe from jane, put it into a variable func, and call it. However, that doesn't work:

> var func = jane.describe;
> func()
TypeError: Cannot read property 'name' of undefined

Solution: use the method bind(). It creates a new function whose this always has the given value.

> var func2 = jane.describe.bind(jane);
> func2()
'Person named Jane'

1.11.4 Functions inside a method (这里有点没搞懂)

Every function has its own special variable this. This is inconvenient if you nest a function inside a method, because you can't access the method's this from the function. The following is an example where we call forEach with a function to iterate over an array:

var jane = {
name: 'Jane',
friends: [ 'Tarzan', 'Cheeta' ],
logHiToFriends: function () {
'use strict';
this.friends.forEach(function (friend) {
// 'this' is undefined here
console.log(this.name + ' says hi to ' + friend);
});
}
}

> jane.logHiToFriends()
TypeError: Cannot read property 'name' of undefined

Solution 1: store this in a different variable

logHiToFriends: function () {
'use strict';
var that = this;
this.friends.forEach(function (friend) {
console.log(that.name + ' says hi to ' + friend);
});
}

Solution 2: forEach has a second parameter that allows you to provide a value for this:

logHiToFriends: function () {
'use strict';
this.firends.forEach(function (friend) {
console.log(that.name + ' says hi to ' + friend);
}, this);
}

Attention: Function expression are often used as arguments in function calls in JavaScript. Always be careful when you refer to this from one of those function expressions.

1.11.5 Constructors: Factories for Objects

// Set up instance data
function Point(x, y) {
this.x = x;
this.y = y;
}

//Method
Point.prototyoe.dist = function () {
return Math.sqrt(this.x*this.x + this.y*this.y);
}

> var p = new Point(3, 5);
> p.x
3
> p.dist()
5.83....

p is an instance of Point:

> p instanceof Point
true

1.12 Arrays

Array Methods:
slice/push/pop/shift/indexOf/join

map creates a new array by applying a function to each element of an existing array:
> [1,2,3].map(function (x) { return  x*x })
[ 1, 4, 9 ]

1.13 Regular Expression(Chapter 19)

Method: test(): Is There a Match?
> /^a+b+$/.test('aaab')
true
> /^a+b+$/.test('aaa')
false

没有评论:

发表评论