2-9 Global environment and Global object

  • Global objects(Ex: window, on browser) and “this” is created by javascript engine
  • At globle level, ‘this’ is equal to ‘window’ inside browser
  • the global (values and functions) are attached to global objects

1
2
3
4
5
6

a = 'hello world';
b = function(){};

console.log(window.a);
console.log(window.b);

Comment and share

2-7 Name/Value pairs and Objects

bigword alert : Name/Value pair

  • a name which maps to an unique value
  • the name may be defined more than once, but only can have one value in any given context
  • value could be another key/value pari

bigword alert : Object(In javascript)

  • a collection of Name/Value pairs

Comment and share

2-6 Syntax Parser, Execution Contex and Lexical Environment

bigword alert : Syntax Parser

  • A program that read your code, determines what it does, and if it’s grama valid

bigword alert : Lexical Environment

  • where something sits physically in the code you write
  • where you write something is IMPORTANT

bigword alert : Execution Contex

  • a wrapper to help manage the code that is running

Comment and share

6-57 Function creator ‘new’, and the history of javascript

history time

  • javascript 之所以叫 javascript,為了吸引 Java programmer XDD
  • new constructor 也是從 Java 搬來的 (笑)

new

  • a operator
  • ‘new’ create a empty object
1
2
3
4
5
6
7
8
9
10
11
12
13

function Person(firstname, lastname){
console.log(this);//Person{}, a new empty object
this.firstname = firstname;
this.lastname = lastname;
console.log("this function is invoked");
}

var john = new Person('John', 'Doe');
console.log(john);

var jane = new Person('Jane', 'Doe');
console.log(jane);
  1. new create a brand new empty object
  2. the function Person() is called
  3. this in the function is point to the new empty object
  4. if the function doesn’t return a value, js engine return the new object

bigword alert : Function Constructors

  • A normal function that is used to construct objects.
  • ‘this’ points to a new empty object.
  • the new empty object is returned from the funciton automatically.

後記:
我到現在才知道在js裡,new後面的是一個function…囧


6-58 Function constructor and ‘.prototype’

Recall

  • .prototype (property) is used only by functions

  • .property is the prototype of any object created(use ‘new’)

  • __proto__ is in all objects(includeing functions)

  • __proto__ is the prototype of the the object

.prototype 是改變所有new 出來的新object 的 prototype

看下面例子,john.__proto__ 指向 Person.prototype

  • good js code sets properties inside the function constructor. But methods are set on the prototype.

∵ methods(function) 也是object,放在function contstrctor,變成每個new 出來的都有一份 methods 的copy
但它們只做一樣的事情 -> 浪費記憶體

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

function Person(firstname, lastname) {

console.log(this);
this.firstname = firstname;
this.lastname = lastname;
console.log('This function is invoked.');

}

Person.prototype.getFullName = function() {
return this.firstname + ' ' + this.lastname;
}

var john = new Person('John', 'Doe');
console.log(john);

var jane = new Person('Jane', 'Doe');
console.log(jane);



Person.prototype.getFormalFullName = function() {
return this.lastname + ', ' + this.firstname;
}

console.log(john.getFormalFullName());

6-59 Dangerous aside : new and function

  • if we invoked a function constructor without new , the function is still run. However, the function will return undefined in default.

  • use capital letter for function constructor

6-60 conceuptual Aside : build-in function constructor

autobox

build-in function constructor
1
2
3
4
5
6
7
8
9
10

var a = new String('John');
var b = new Number(3);
// creating Number object, not primitive type

"John".length //4
// primitive has no methods
//js engine autobox the primitive string into Object String

3.toFixed; //err, js doesn't do autobox on numbers
js easy enhance
1
2
3
4
5
6

// add new method to origin String Object
String.prototype.isLengthGreaterThan = function(limit){
return this.length > limit;
}
console.log('John'.isLengthGreaterThan(3)); //true

6-61 Dangerous Aside: build-in function constructor

  • is better not to use (primitive tpye) built-in function constructors
  • deal with date : moment.js
1
2
3
4
5
6
7
8
9

var a = 3;
var b = new Number(3);

a == b //true

a === b // false

var c = Number("3"); //convert string to primitive number

6-62 Dangerous Aside : Arrays and for…in

  • index(0,1,2…) is the property name
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

// Array.prototype.myCustomFeature = 'cool!';

var arr = ['John','Jane','Jim'];

for(var prop in arr){
console.log(prop + ' : ' + arr[prop]);
}

/*
0 : John
1 : Jane
2 : Jim
*/

/*
0 : John
1 : Jane
2 : Jim
myCustomFeature : cool!
*/

// use standard for loop to avoid this

6-63 Object.create and Pure Prototypal Inheritance

  • Pure Prototypal Inheritance
  • Object.create create a empty object with prototype point to the argument
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

var person = {
firstname : 'Default',
lastname : 'Default',
greet : function(){
return 'Hi' + this.firstname;
// this point to the object person
// if there is no this, js engine would find firstname in greet function's execution context
// then find firstname in outer environment(in this case, it's global object)
}
}

var john = Object.create(person);
console.log(john);
// john has default name!! because of the prototype

john.firstname = 'John';
john.lastname = 'Doe';
console.log(john);

if browser doesn’t support Object.create… Polyfill!!

bigword alert : Polyfill

  • code that adds a feature the engine may lack
object.create polyfill
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

//if object.create not exist, undefined
// undefined is coerced to boolean
if (!Object.create) {
Object.create = function (o) {
if (arguments.length > 1) {
throw new Error('Object.create implementation'
+ ' only accepts the first parameter.');
}
function F() {}
F.prototype = o;
return new F();
};
}

var person = {
firstname: 'Default',
lastname: 'Default',
greet: function() {
return 'Hi ' + this.firstname;
}
}

var john = Object.create(person);
john.firstname = 'John';
john.lastname = 'Doe';
console.log(john);

6-64 ES6 and Classes

  • ES6 has new keywords : class
  • 但作者認為這只是個syntatic sugur, 本質上還是 prototypal inheritance
  • 仍然建議使用prototypal inheritance 的方式
ES6 class
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

// note that this is a Object, a created object
// it exist in memory already
class Person{
constructor(firstname, lastname){
this.firstname = firstname;
this.lastname = lastname;
}

greet(){
return 'Hi ' + firstname;
}
}

var john = new Person('John', 'Doe');

Comment and share

#5-53 Classical vs prototypal ingeritance

bigword alert : Inheritance

  • one object gets access to the properties and methods of another object

#5-54 Understanding Prototype

  • every object in js has a property called proto
  • proto is a object too.
  • js engine do the search in prototype chain for the properties and methods
  • this in __proto__ point to the origin object, not the __proto__ object
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

var person = {
firstname : 'Default',
lastname : 'Default',
getFullName : function(){
return this.firstname + ' ' + this.lastname;
}
}

var john = {
firstname : 'John',
lastname : 'Doe'
}

var jane = {
firstname : 'Jane'
}

// don't do this EVER! for demo purposes only!!
// performance issue
john.__proto__ = person;
jane.__proto__ = person;
console.log(john.getFullName());
console.log(john.firstname);
console.log(jane.getFullName);

#5-55 Every things is an object(or a primitive)

  • all thing has __proto__, except basic object
  • Object is the bottom of prototype chain
1
2
3
4
5
6
7
8

var a = {};
var b = function(){};
var c = [];

a.__proto__ //object{}
b.__proto__ //Empty(){}
c.__proto__ //[]

#5-56 Reflection and Extend

bigword alert : Reflection

  • an object can look at itself, listing and changing its properties and methods.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

var person = {
firstname : 'Default',
lastname : 'Default',
getFullName : function(){
return this.firstname + ' ' + this.lastname;
}
}

var john = {
firstname : 'John',
lastname : 'Doe'
}

// don't do this EVER! for demo purposes only!!
john.__proto__ = person;

for(var prop in john){
console.log(prop + ' : ' + john[prop]);//show all properties including proto's
//use object.hasOwnProperty to check
}
underscore extend
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// require underscore

var john = {
firstname : 'John',
lastname : 'Doe'
}

var jane = {
address : '111 Main St.';
getformalFullName : function (){
return this.lastname + ', ' + this.firstname;
}
}

var jim = {
getFirstName : function(){
return firstname;
}
}

_.extend(john, jane, jim);
console.log(john);
source code of _
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

// Extend a given object with all the properties in passed-in object(s).
_.extend = createAssigner(_.allKeys);

// An internal function for creating assigner functions.
var createAssigner = function(keysFunc, undefinedOnly) {
return function(obj) {
var length = arguments.length;
if (length < 2 || obj == null) return obj;
for (var index = 1; index < length; index++) {
var source = arguments[index],
keys = keysFunc(source),
l = keys.length;
for (var i = 0; i < l; i++) {
var key = keys[i];
if (!undefinedOnly || obj[key] === void 0) obj[key] = source[key];
}
}
return obj;
};
};

Comment and share

Requirements

  1. Write a program to determine your system’s byte ordering. Explain how does it work and present your test results.

  2. Write a client program and a server program to continuously report the number of processes currently running on a specified host (UNIX) computer. Make sure your server supports multiple concurrent clients and handle socket-related exceptions.

Continue reading

4-51 Functional Programming

  • 利用first class function 特性,將function當成參數傳入另一個function 或回傳一個function
  • 盡量減少funciton side-effect,不更改原變數,不依賴全域變數 -> 每次function執行,結果都要相同
selfdefined map function
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

function mapForEach(arr, fn) {

var newArr = [];
for (var i=0; i < arr.length; i++) {
newArr.push(
fn(arr[i])
)
};

return newArr;
}

var arr1 = [1,2,3];
console.log(arr1);


var arr2 = mapForEach(arr1, function(item) {
return item * 2;
});
console.log(arr2);


var arr3 = mapForEach(arr1, function(item) {
return item > 2;
});
console.log(arr3);


var checkPastLimit = function(limiter, item) {
return item > limiter;
}
var arr4 = mapForEach(arr1, checkPastLimit.bind(this, 1));
console.log(arr4);


var checkPastLimitSimplified = function(limiter) {
return function(limiter, item) {
return item > limiter;
}.bind(this, limiter);
};

var arr5 = mapForEach(arr1, checkPastLimitSimplified(1));
console.log(arr5);

4-51 Functional Programming

  • Read code of open source library
  • underscore.js
  • lodash.js

Comment and share

4-50 call(), apply(), and bind()

bigword alert : Function currying

  • creating a copy of a function but with some preset parameters.

  • The bind() method creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called.REF


bind 複製function,並將其中的 this 設成給定的物件,回傳複製的function

  • The call() method calls a function with a given this value and arguments provided individually.REF

call 將function中的this改為thisArg, 並用後面的參數invoked 該function

  • The apply() method calls a function with a given this value and arguments provided as an array REF

apply和call功能相同,差別只有function的參數要用array傳入

1
2

fun.call(thisArg[, arg1[, arg2[, ...]]])
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

var person = {
firstname = 'John';
lastname = 'Doe';
getFullName : function(){
var fullname = this.firstname + ' ' + this.lastname;
return fullname;
}
}

var logName = function(lang1,lang2){
console.log('Logged : ' + this.getFullName());
console.log('Arguments: ' + lang1 + ' ' + lang2);
}

var logPersonName = logName.bind(person);
logName();
logName.call(person,'en','es');
logName.apply(person,['en','es']);

When is this used in real life?

  • function borrowing
function borrowing
1
2
3
4
5
6

var person2 = {
firstname : 'Jane';
lastname : 'Doe';
}
person.getFullName.apply(person2);
  • function currying
function currying
1
2
3
4
5
6
7

function multiply(a,b){
return a * b;
}
var multiplyByTwo = multiply.bind(this,2);
// set first parameter(a) = 2, reutrn a new copy of multiply function
console.log(multiplyByTwo(4));

Comment and share

4-46 Understanding Closures

  • why whattosay is still exist when invoking sayHi ?

  • greet function is pop off the execution stack, so whattosay should be clear.

  • Closures: closing in all variables that the function supposed to have access to

  • the execution context has closed in its outer environment reference(only variables, not values), even though those outer execution contexts are gone.

1
2
3
4
5
6
7
8
9

function greet(whattosay){
return function(name){
console.log(whattosay + ', ' + name);
}
}
greet('Hey')('Necisam');//Hey, Necisam
var sayHi = greet('Hey');// a function
sayHi('Necisam');

4-47 Understanding Closures part2

Closures close only the variables, not the values.

  • Free variables : it is outside a function, but that you have access to.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

function buildFunctions(){
var arr = [];
for(var i = 0; i < 3; i++){
arr.push(
function(){
console.log(i);
}
);
}
return arr;
}
var fs = buildFunctions();
fs[0]();
fs[1]();
fs[2]();
// 3 3 3
// i is set to 3 after the loop
//

to execute the functions to get different execution context that contains different J s.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function buildFunctions(){
var arr = [];
for(var i = 0; i < 3; i++){
arr.push(
(function(j){
return console.log(j);
}(i))
);
}
return arr;
}
var fs = buildFunctions();
fs[0]();
fs[1]();
fs[2]();

ES6 solution

  • let allows you to declare variables that are limited in scope to the block, statement, or expression on which it is used.
  • each j would be a new variables in mem(just like c language)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

function buildFunctions(){
var arr = [];
for(var i = 0; i < 3; i++){
let j = i;
arr.push(
function(){
console.log(j);
}
);
}
return arr;
}
var fs = buildFunctions();
fs[0]();
fs[1]();
fs[2]();

4-48 Funciton factories

  • Every time the function be invoked, a new execution context is created.
  • This lets us create functions from other functions.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

function makeGreeting(language){
return function(firstname,lastname){
if(language === 'en'){
console.log('Hello '+ firstname + lastname);
}
if(language === 'es'){
console.log('Hola' + firstname + lastname);
}
}
}

var gEnglish = makeGreeting('en');
var gSpanish = makeGreeting('es');
gEnglish('YuCheng','Cheng');
gSpanish('YuCheng','Cheng');

4-49 Closures and Callbacks

bigword alert : Callback funcion

  • A function you give to another function, to be run when the other function is finished
1
2
3
4
5
6
7
8
9
10

function sayHiLater(){
var greeting = 'Hi!';

setTimeout(functions(){
console.log.(greeting);
}, 3000);
}

sayHiLater();

Comment and share

4-43 White space

4-44 Immediately invoked function expressions(IIFEs)

function 被宣告後馬上被執行,回傳hello字串給greeting

IIFEs
1
2
3
4
5

var greeting = function (name){
return ('Hello ' + name);
}('Necisam');
//greeting hold the string returned by function

syntax parse saw function keyword in the starting in a line, it expects that this is a function statement

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

3;// an expression

// an expressions
{
name : "necisam",
country : "Taiwan"
}

// expressions
function (name){
return "Hello " + name;
}

//to trick syntax parser, make it become an expression
//parenthesis is a operator in JS
(function (name){
return "Hello " + name;
});

//invoke a function expression !!
(function (name){
return "Hello " + name;
}('Necisam'));

4-45 IIFEs and safe code

因為是呼叫function,有自己的 execution context
所有function 不會動到 global
如果真的需要global的內容,下面給了一個範例
能夠安全的access global content

1
2
3
4
5
6
7
8
9
10
11

var greeting = 'Hola';

// objects are passed by reference
(function (global, name){
var greeting = 'Hello';
global.greeting = 'Hello';
console.log(greeting + ' ' + name);
}(window, 'Necisam'));

console.log(greeting);//Hello, modfied by function

Comment and share

Author's picture

Necisam

author.bio


author.job


Tainan, Taiwan