Shakespeare once said, "A good memory is not as good as a bad pen."
Chapter 1 Introduction to JavaScript#
1.1 Brief History of JavaScript#
1.2 Implementation of JavaScript#
-
A complete JavaScript implementation should consist of three different parts: core (ECMAScript), Document Object Model (DOM), and Browser Object Model (BOM).
-
ECMAScript: provides core language functionality; DOM: provides methods and interfaces for accessing and manipulating web content; BOM: provides methods and interfaces for interacting with the browser.
1.3 Versions of JavaScript#
Chapter 2 Using JavaScript in HTML#
2.1 script Element#
-
Position of the tag: To avoid noticeable delays in rendering the page by the browser, modern web applications generally place all JavaScript references at the end of the content in the element.
-
Deferred scripts: The defer attribute indicates that the script will not affect the construction of the page when executed; the script will be delayed until the entire page is parsed; applicable only to external script files.
<script defer="defer" src="example.js"></script>
- Asynchronous scripts: The async attribute indicates that the current script does not need to wait for other scripts and does not block document rendering, telling the browser to download the file immediately, and does not guarantee that scripts marked as async will execute in the order they were added; applicable only to external script files.
<script async src="example1.js"></script>
<script async src="example2.js"></script>
2.2 Embedded Code and External Files#
2.3 Document Modes#
- Quirks mode and Standards mode; to enable Standards mode:
<!-- HTML 5 -->
<!DOCTYPE html>
2.4 noscript Element#
Chapter 3 Basic Concepts#
3.1 Syntax#
-
Case sensitivity: Everything in ECMAScript is case sensitive.
-
Strict mode: In strict mode, some ambiguous behaviors in ECMAScript 3 will be addressed, and errors will be thrown for certain unsafe operations. Add the following code at the top:
"use strict"
3.2 Keywords and Reserved Words#
3.3 Variables#
- Assigning a value to an undeclared variable will throw a ReferenceError in strict mode.
3.4 Data Types#
-
The typeof operator is used to detect the data type of a variable.
-
Five primitive data types: Undefined, Null, Boolean, Number, String; one complex data type (reference type): Object.
-
Undefined type: When a variable is declared with var but not initialized, its value is undefined.
-
Null type: A null value represents a null object pointer; as long as a variable intended to hold an object has not actually stored an object, it should explicitly hold a null value.
-
Boolean type: To convert other types to Boolean type, use the Boolean() function.
-
Number type: To convert other types to Number type, commonly used function parseInt(); when converting strings, if the first character is not a numeric character or a negative sign, it will return NaN; the second parameter is optional and indicates the base.
-
String type: Strings are immutable; to convert other types to String type, use the toString() or String() function or add an empty string (1 + '').
-
Object type
Methods to create an object:
var o = new Object();
Creating an instance of the Object object and adding properties or methods to it allows for the creation of custom objects;
The Object type is the basis for all its instances, with the following properties and methods:
-
constructor: holds the function used to create the current object, i.e., the constructor;
-
hasOwnProperty(propertyName): checks if the given property exists in the current object instance;
-
isPrototypeOf(object): checks if the passed object is the prototype of the passed object;
-
propertyIsEnumerable(); toLocaleString();
-
toString(): returns the string representation of the object;
-
valueOf(): returns the string, numeric, or boolean representation of the object;
3.5 Operators#
- When comparing strings, what is actually compared are the character encoding values of each character in the corresponding positions of the two strings.
"23" < "3" // true
-
When comparing numbers and strings, the strings will be converted to numbers and then compared numerically; if they cannot be converted to numbers, they will be converted to NaN.
-
Any operand compared with NaN will result in false.
NaN == NaN // false
NaN === NaN // false
NaN > NaN // false
NaN < NaN // false
- Equality (==) and strict equality (===): Strict equality returns true only when the two operands are equal without conversion.
"55" == 55 // true
"55" === 55 // false
- Conditional operator
variable = boolean_expression ? true_value : false_value;
3.6 Statements#
- Since there is no block scope in ECMAScript, variables defined inside a loop can also be accessed from outside:
for (var i = 0; i < 10; i++) {
var j = 1;
}
console.log(i, j); // 10 1
- The for-in statement can be used to enumerate the properties of an object.
for (property in expression) {
...
}
- The break and continue statements can be used in conjunction with label statements: this often occurs in nested loops.
var num = 0;
outermost:
for (var i = 0; i < 10; i++) {
for (var j = 0; j < 10; j++) {
if (i == 5 && j == 5) {
break outermost;
}
num++;
}
}
console.log(num); // 55
3.7 Functions#
- Function parameters: Parameters are represented internally as an array; the function always receives this array, regardless of what functions are included in the array; named parameters are provided for convenience but are not required; the values in the arguments object are independent of the memory space of the corresponding named parameters, but their values will be synchronized.
function example(name, age) {
console.log('arguments:', arguments);
console.log('name:', name, 'age:', age);
name = 'DIYgod';
console.log(arguments[0]);
}
example('Anotherhome', '556', 'www.anotherhome.net');
// arguments: ["Anotherhome", "556", "www.anotherhome.net"]
// name: Anotherhome age: 556
// DIYgod
Chapter 4 Variables, Scope, and Memory Issues#
4.1 Values of Primitive Types and Reference Types#
-
When operating on objects, you are actually operating on the reference to the object rather than the actual object.
-
When copying a value of a primitive type from one variable to another, a copy of that value is created; when copying a value of a reference type from one variable to another, what is copied is a pointer to an object stored in the heap, and after copying, both variables point to the same object.
var o1 = {};
var o2 = o1;
o1.name = 'DIYgod';
console.log(o2.name); // DIYgod
var n1 = 1;
var n2 = n1;
n1 = 2;
console.log(n2); // 1
- Passing parameters: Parameters can only be passed by value; when the parameter is an object, the same object is accessed within the function.
function setName(o) {
o.name = 'DIYgod';
o = {};
o.name = 'Anotherhome';
}
var p = {};
setName(p);
console.log(p.name); // DIYgod
- To determine what kind of primitive type a value is, you can use the typeof operator, while to determine what kind of reference type a value is, you can use the instanceof operator.
4.2 Execution Environment and Scope#
-
There are global execution environments and function execution environments; each execution environment has an associated variable object; each time a new execution environment is entered, a scope chain is created for searching variables and functions, with the front of the chain being the variable environment where the currently executing code resides, and the last object being the variable object of the global execution environment.
-
Querying identifiers: Start from the front of the scope chain and query upwards, stopping when found; if not found, continue tracing back to the variable object of the global environment.
4.3 Garbage Collection#
-
The most commonly used garbage collection method is mark-and-sweep: the garbage collector will mark all variables stored in memory, then remove the marks from variables in the environment and those referenced by variables in the environment, and any variables that still have marks afterward are considered ready for deletion, as these variables can no longer be accessed.
-
Optimizing memory usage: Only keep necessary data for executing code; once data is no longer useful, it is best to release its reference by setting its value to null—dereferencing; the purpose of dereferencing is to detach its value from the execution environment so that the garbage collector can reclaim it during its next run.
Chapter 5 Reference Types#
5.1 Object Type#
- Creating Object instances: using the Object constructor; object literal.
// Using the new operator
var o1 = new Object();
o1.name = 'DIYgod';
o1.age = 20;
// Object literal notation
var o1 = {
name: 'DIYgod',
age: 20
}
- Accessing object properties: dot notation; bracket notation. It is recommended to use dot notation.
// Dot notation
console.log(o.name);
// Bracket notation
console.log(o['name']);
var n = 'name';
console.log(o[n]);
console.log(o['first name']);
5.2 Array Type#
- Creating arrays: using the Array constructor; using array literal notation.
var a1 = new Array();
var a2 = new Array(20);
var a3 = new Array('red', 'blue', 'green');
var a4 = [];
var a5 = ['red', 'blue', 'green'];
- Adding new items at the end using length.
var a = ['a', 'b'];
a[a.length] = 'c';
-
Detecting arrays: Array.isArray() (solves the issue of instanceof detection errors when there are more than two global execution environments).
-
Stack methods and queue methods: push() adds an item to the end of the array; pop() removes an item from the end of the array; shift() removes the first item from the array; unshift() adds an item to the front of the array.
-
Reordering
-
reverse(): reverses the order of array items.
-
sort(): by default, converts array items to strings and sorts them in ascending order. It can accept a comparison function as a parameter.
The comparison function takes two parameters; if the first parameter is before the second parameter, it returns a negative number; if equal, it returns 0; if the second parameter is before the first parameter, it returns a positive number.
var a = [0, 1, 15, 10, 5];
a.sort();
console.log(a) // [0, 1, 10, 15, 5]
function compare(value1, value2) {
return value1 - value2;
}
a.sort(compare);
console.log(a) // [0, 1, 5, 10, 15]
- Manipulation methods
- concat(): adds items
var a1 = ['red', 'green', 'blue'];
var a2 = a1.concat('yellow', ['black', 'brown']);
console.log(a2) // ["red", "green", "blue", "yellow", "black", "brown"]
- slice(): extracts
var a = ["red", "green", "blue", "yellow", "black", "brown"];
console.log(a.slice(1), a.slice(1, 4)) // ["green", "blue", "yellow", "black", "brown"] ["green", "blue", "yellow"]
- splice(): deletes, inserts, replaces
var a = ["red", "green", "blue", "yellow", "black", "brown"];
console.log(a.splice(2, 1), a); // deleted item; ["blue"] ["red", "green", "yellow", "black", "brown"]
console.log(a.splice(1, 0, 'yellow', 'orange'), a); // inserted item; [] ["red", "yellow", "orange", "green", "yellow", "black", "brown"]
console.log(a.splice(1, 1, 'red', 'purple'), a); // replaced item; ["yellow"] ["red", "red", "purple", "orange", "green", "yellow", "black", "brown"]
- Position methods: indexOf() lastIndexOf() accepts two parameters: the item to search for and (optional) the index to start searching from; indexOf() searches from front to back, lastIndexOf() searches from back to front; returns the position of the item being searched for, or -1 if not found.
var a = ["red", "purple", "orange", "green", "red", "yellow", "black", "brown"];
console.log(a.indexOf('red')); // 0
console.log(a.lastIndexOf('red')); // 4
console.log(a.indexOf('red', 1)); // 4
console.log(a.lastIndexOf('red', 1)); // 0
- Iteration methods: every() some() filter() map() forEach().
var a = [1, 2, 3, 4, 5, 4, 3, 2, 1];
var everyResult = a.every(function (item, index, array) {
return (item > 2);
});
console.log(everyResult); // false
var someResult = a.some(function (item, index, array) {
return (item > 2);
});
console.log(someResult); // true
var filterResult = a.filter(function (item, index, array) {
return (item > 2);
});
console.log(filterResult); // [3, 4, 5, 4, 3]
var mapResult = a.map(function (item, index, array) {
return (item * 2);
});
console.log(mapResult); // [2, 4, 6, 8, 10, 8, 6, 4, 2]
var forEachResult = a.forEach(function (item, index, array) {
console.log(item);
});
console.log(forEachResult); // undefined
- Reducing methods
var a = [1, 2, 3, 2, 1];
var sum1 = a.reduce(function (prev, cur, index, array) {
console.log(index); // 1 2 3 4
return prev + cur;
});
console.log(sum1); // 9
var sum2 = a.reduceRight(function (prev, cur, index, array) {
console.log(index); // 3 2 1 0
return prev + cur;
});
console.log(sum2); // 9
5.3 Date Type#
- Creating date objects: months are zero-based (January is 0, February is 1...).
var d1 = new Date();
var d2 = new Date(2015, 2, 5, 17, 55, 55); // March 5, 2015, 5:55:55 PM
- Getting the date and time in milliseconds at the time of the call can be used to analyze code.
var start = Date.now();
doSomething();
var stop = Date.now();
var result = stop - start;
- Date formatting methods: local indicates displaying in a locale-specific format.
var d2 = new Date(2015, 2, 5, 17, 55, 55);
d2.toString(); // "Thu Mar 05 2015 17:55:55 GMT+0800 (CST)"
d2.toDateString(); // "Thu Mar 05 2015"
d2.toTimeString(); // "17:55:55 GMT+0800 (CST)"
d2.toLocaleString(); // "2015/3/5 下午5:55:55"
d2.toLocaleDateString(); // "2015/3/5"
d2.toLocaleTimeString(); // "下午5:55:55"
5.4 RegExp Type#
- Creating a regular expression:
The pattern part is the regular expression
Flags indicate the behavior of the regular expression: g for global mode; i for case-insensitive; m for multi-line mode.
var exp1 = / pattern / flags
var exp2 = new RegExp('pattern', 'flags');
- Instance methods:
- exec(): returns an array of information about the first match, where the first item is the string that matches the entire pattern, and other items are the strings that match the capture groups in the pattern; it also includes two additional properties, index and input.
var text = "I'm DIYgod, and this is Anotherhome";
var pattern = /and( this( is)?)?/gi;
var matches = pattern.exec(text);
console.log(matches.index); // 12
console.log(matches.input); // I'm DIYgod, and this is Anotherhome
console.log(matches[0]); // and this is
console.log(matches[1]); // this is
console.log(matches[2]); // is
- test(): returns true if the pattern matches the parameter, otherwise returns false.
var text = "I'm DIYgod, and this is Anotherhome";
var pattern = /DIYgod/;
var matches = pattern.test(text);
console.log(matches); // true
- The RegExp constructor includes some properties that apply to all regular expressions in the scope, recording information about the last regular expression operation.
5.5 Function Type#
- Defining functions, functions are actually instances of the Function type, so functions are also objects.
// Using function declaration syntax
function f1 (n1, n2) {
return n1 + n2;
}
// Using function expression
var f2 = function (n1, n2) {
return n1 + n2;
};
// Using constructor function, not recommended
var f3 = new Function('n1', 'n2', 'return n1 + n2');
- The function name is a pointer to the function object.
function f1 (n1, n2) {
return n1 + n2;
}
var f2 = f1;
f1 = null;
console.log(f2(1, 1)); // 2
-
There is no function overloading in ECMAScript.
-
Differences between function declarations and function expressions: the interpreter reads function declarations first and makes them available before executing any code (function declaration hoisting); function expressions are not interpreted until the interpreter reaches the line where they are located.
console.log(f1(1, 1)); // 2
function f1 (n1, n2) {
return n1 + n2;
}
console.log(f2(1, 1)); // Uncaught TypeError: f2 is not a function
var f2 = function(n1, n2) {
return n1 + n2;
}
- Internal properties of functions
- The callee property of the function's arguments object: is a pointer that points to the function that owns this arguments object. It can reduce coupling between the function and the function name during recursion.
// The second way is obviously better
function factorial1 (num) {
if (num <= 1) {
return 1;
}
else {
return num * factorial1(num - 1);
}
}
function factorial2 (num) {
if (num <= 1) {
return 1;
}
else {
return num * arguments.callee(num - 1);
}
}
- The caller property: holds a reference to the function that called the current function.
function outer() {
inner();
}
function inner() {
console.log(arguments.callee.caller); // function outer()...
}
outer();
- Function properties and methods
- The length property: indicates the number of named parameters the function expects to receive.
function f (n1, n2) {
return n1 + n2;
}
console.log(f.length); // 2
- apply() call(): used to change the value of the this object of the function.
window.color = 'red';
var o = {
color: 'blue'
};
function sayColor (n1, n2) {
console.log(this.color);
return n1 + n2;
}
sayColor(1, 1); // red
o.sayColor = sayColor;
o.sayColor(); // blue
// Using call and apply can eliminate the coupling between the object and the method
sayColor.call(window, 1, 1); // red
sayColor.call(o, 1, 1); // blue
sayColor.apply(window, [1, 1]); // red
sayColor.apply(o, [1, 1]); // blue
5.6 Basic Wrapper Types#
Boolean type, Number type, String type
Temporarily skipped
5.7 Global Built-in Objects#
Global object, Math object
Temporarily skipped
Chapter 6 Object-Oriented Programming#
6.1 Understanding Objects#
- Two types of properties: data properties and accessor properties. Characteristics: describe various features of properties, used for the JavaScript engine, cannot be accessed directly.
- Data properties have 4 characteristics:
-
[[Configurable]]: indicates whether the property can be deleted via delete, whether the property characteristics can be modified, and whether the property can be changed to an accessor property.
-
[[Enumerable]]: indicates whether the property can be returned via a for-in loop.
-
[[Writable]]: indicates whether the property value can be modified.
-
[[Value]]: contains the data value of the property.
- Accessor properties have 4 characteristics:
-
[[Configurable]]: indicates whether the property can be deleted via delete, whether the property characteristics can be modified, and whether the property can be changed to a data property.
-
[[Enumerable]]: indicates whether the property can be returned via a for-in loop.
-
[[Get]]: the function called when reading the property.
-
[[Set]]: the function called when writing the property.
- Defining and reading characteristics: Object.defineProperty() Object.defineProperties() Object.getOwnPropertyDescriptor()
6.2 Creating Objects#
- Factory pattern: While it solves the problem of creating multiple similar objects, it does not solve the problem of object identification.
function createPerson(name, age, job) {
var o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.sayName = function () {
console.log(this.name);
}
return o;
}
var p1 = createPerson('DIYgod', 20, 'Software Engineer');
var p2 = createPerson('Anotherhome', 2, 'Website');
- Constructor function pattern. (Constructor functions should start with a capital letter)
function Person(name, age, job) {
this.name = name;
this.age = age;
this.job = job;
this.sayName = function () {
console.log(this.name);
}
}
var p1 = new Person('DIYgod', 20, 'Software Engineer');
var p2 = new Person('Anotherhome', 2, 'Website');
// p1 and p2 each hold a different instance of Person, both objects have a constructor property that points to Person
console.log(p1.constructor); // function Person(name, age, job) {...
console.log(p1 instanceof Object); // true
console.log(p1 instanceof Person); // true
This method goes through 4 steps:
-
Create a new object
-
Assign the constructor function's scope to the new object (this points to this new object)
-
Execute the code in the constructor function (adding properties to the new object)
-
Return the new object
The problem with constructor functions: each method has to be recreated on each instance.
console.log(p1.sayName === p2.sayName); // false
- Prototype pattern: Every function has a prototype property, which is a pointer to an object (the function's prototype object) that contains properties and methods that can be shared by all instances of that type.
// Combining constructor function pattern with prototype pattern
function Person(name, age, job) {
this.name = name;
this.age = age;
this.job = job;
}
Person.prototype.sayName = function () {
console.log(this.name);
}
var p1 = new Person('DIYgod', 20, 'Software Engineer');
var p2 = new Person('Anotherhome', 2, 'Website');
console.log(p1.sayName === p2.sayName); // true
- Understanding prototype objects:
-
Whenever a new function is created, a prototype property is created for that function according to a specific set of rules, pointing to the prototype object.
-
By default, all prototype objects receive a constructor property that points to the function of the prototype property.
-
After calling the constructor function to create a new instance, the instance will have a proto property that points to the constructor function's prototype object, this pointer is called [[Prototype]], and the default prototype points to Object.
-
Instances and constructors have no direct relationship.
-
Reading properties: searching starts from the object instance itself; if not found, it searches the prototype object.
-
Use isPrototypeOf() to check if there is a relationship between the constructor and the instance.
-
Use hasOwnProperty() to check if a property exists in the instance or in the prototype.
- Prototypes and the in operator
// The in operator returns true if the property can be accessed through the object
console.log('name' in p1); // true
// Enumerating properties
for (var prop in p1) {
console.log(prop); // name age job sayName
}
- Overwriting the prototype object with an object literal
function Person() {
}
Person.prototype = {
constructor: Person, // Here the prototype is overwritten, no longer has the default constructor property
name: 'DIYgod',
age: 20
};
- Dynamic prototype pattern, parasitic constructor pattern, and sturdy constructor pattern
6.3 Inheritance#
- The most commonly used inheritance in JavaScript: combination inheritance. It combines the advantages of the prototype chain and constructor functions.
function SuperType(name) {
this.name = name;
this.color = ['red', 'blue', 'green'];
}
SuperType.prototype.sayName = function () {
console.log(this.name);
}
function SubType(name, age) {
SuperType.call(this, name); // Borrowing constructor
this.age = age;
}
SubType.prototype = new SuperType(); // Prototype chain
SubType.prototype.constructor = SubType; // The constructor was overwritten in the previous line
SubType.prototype.sayAge = function () {
console.log(this.age);
}
var instance = new SubType('DIYgod', 20);
instance.sayName(); // DIYgod
instance.sayAge(); // 20
- Determining the relationship between the prototype and the instance. Continuing from the previous example:
console.log(instance instanceof SuperType); // true
console.log(SuperType.prototype.isPrototypeOf(instance)); // true
- Prototypal inheritance, parasitic inheritance, and parasitic combination inheritance
Chapter 7 Function Expressions#
7.1 Recursion#
7.2 Closures#
-
A closure is a function that has access to variables in another function's scope.
-
(See scope chain in 4.2) An inner function defined inside an outer function will include the outer function's activation object in its scope; after the outer function completes execution, its activation object will not be destroyed because the inner function's scope chain still references this activation object; after the outer function completes execution, the inner function can still access all the variables it defined.
function outer () {
var name = 'DIYgod';
return function () {
console.log(name);
}
}
var inner = outer();
inner(); // DIYgod
inner = null; // Dereference the anonymous function inside outer to free memory
- Closures can only capture the last value of any variable within the function.
function createFunction () {
var result = [];
for (var i = 0; i < 10; i++) {
result[i] = function () {
return i;
}
}
return result;
}
console.log(createFunction()[0]()); // 10
console.log(createFunction()[1]()); // 10
// Both return the same variable i
- The this of an anonymous function usually points to the window.
var name = 'The Window';
var object = {
name: 'My Object',
getNameFunc: function () {
return function () {
return this.name;
}
}
}
console.log(object.getNameFunc()()); // The Window
7.3 Mimicking Block Scope#
- Using an anonymous function to mimic block scope: The first parentheses convert the function declaration into a function expression (function declarations cannot be called by adding parentheses afterward), and the second parentheses call this function.
(function () {
var i = 9;
console.log(i); // 9
})();
console.log(i); // Uncaught ReferenceError: i is not defined
7.4 Static Objects#
-
Any variable defined within a function can be considered a private variable.
-
Public methods that have access to private variables and private functions are called privileged methods.
function MyObject() {
// Private variables and private functions
var privateVariable = 'DIYgod';
function privateFunction() {
console.log('lalala');
}
// Privileged method
this.publicMethod = function () {
console.log(privateVariable);
privateFunction();
};
}
var o = new MyObject();
o.publicMethod(); // DIYgod lalala
o.privateFunction(); // Uncaught TypeError: o.privateFunction is not a function
...
Chapter 13 Events#
13.1 Event Flow#
-
Event bubbling: The event starts by being received by the most specific element and then propagates upward to less specific nodes; IE9, Firefox, Chrome, and Safari will bubble the event all the way up to the window object.
-
Event capturing: Rarely used because older versions of browsers do not support it.
-
The event flow defined by "DOM Level 2 Events" includes three phases: event capturing phase, target phase, and event bubbling phase.
13.2 Event Handlers#
- HTML event handlers: Extend the scope, allowing access to document and the element's members inside the function as if accessing local variables, for example:
<input type="button" value="Click Me" onclick="alert(value)">
If it is a form input element, the scope will also include access to the form element's entry, for example:
<form method="post">
<input type="text" name="username" value="">
<input type="button" value="Echo username" onclick="alert(username.value)">
</form>
Disadvantages: ① There is a timing issue; triggering the event before parsing the function will cause an error ② The extended scope chain of the handler may yield different results in different browsers ③ It leads to tight coupling between HTML and JavaScript code.
- DOM Level 0 event handlers
// Binding event handler
var btn = document.getElementById('myButton');
btn.onclick = function () {
console.log(this.id); // myButton
}
// Removing event handler
btn.onclick = null;
Event handlers added this way will be processed during the event flow's bubbling phase.
- DOM Level 2 event handlers
addEventListener() and removeEventListener()
Three parameters: the name of the event to handle, the function as the event handler, and whether to call the function during the capturing phase (true) or the bubbling phase (false, default).
The advantage is that multiple event handlers can be added; event handlers added using addEventListener can only be removed using removeEventListener, and anonymous functions cannot be removed.
- IE event handlers
attachEvent() and detachEvent()
var btn = document.getElementById('myButton');
btn.attachEvent('onclick', function () {
console.log(this === window); // myButton
});
Event handlers added this way will be processed during the event flow's bubbling phase.
13.3 Event Object#
-
When a certain event is triggered on a DOM element, an event object is created, which contains all information related to the event. The event object only exists during the execution of the event handler; once the event handler completes execution, the event object is destroyed.
-
Properties/Methods:
currentTarget: the element currently handling the event
target: the target of the event
type: the event type
cancelable: whether the default behavior of the specific event can be prevented
preventDefault(): prevents the default behavior of the specific event
stopPropagation(): stops the propagation of the event in the DOM hierarchy, i.e., cancels further event capturing or bubbling
eventPhase: the phase of the event in the event flow, with capturing phase as 1, target object as 2, and bubbling phase as 3
13.4 Event Types#
- UI events, focus events, mouse events, wheel events, text events, keyboard events, synthetic events, mutation events.
...
Chapter 21 Ajax and Comet#
21.1 XMLHttpRequest Object#
- Usage
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) {
console.log(xhr.responseText);
}
else {
console.log('Request was unsuccessful: ' + xhr.status);
}
}
};
xhr.open('get', 'example.php', true);
xhr.send(null);
-
Creating an XHR object: new XMLHttpRequest();
-
open(): initializes a request to be sent; 3 parameters: request type, request URL, whether to send the request asynchronously (synchronous must wait for the server response before continuing execution); does not actually send the request.
-
send(): sends the request; 1 parameter: the data to send; if no data needs to be sent, null must be passed.
-
Properties of the XHR object:
-
responseText returns the text returned
-
status the HTTP status of the response.
- HTTP status codes:
-
2xx Success
-
3xx Redirection, 304 Not Modified indicates that the requested resource has not been modified and can use the cached version in the browser, 302 Found indicates that the requested resource is now temporarily responding from a different URI.
-
4xx Client error, 403 Forbidden, 404 Not Found
-
5xx Server error, 500 Internal Server Error, 503 Service Unavailable.
- The readyState property of the XHR:
-
0: uninitialized
-
1: loading, open() has been called
-
2: sent, send() has been called
-
3: receiving partial response data
-
4: receiving all response data
- The readystatechange event: the value of the readystate property changes from one value to another, triggering the readystatechange event.
21.4 Cross-Origin Resource Sharing#
-
CORS: uses custom HTTP headers to communicate between the browser and the server, determining whether the request or response should succeed or fail. In IE, the XDR object must be used; other browsers natively support the XHR object.
-
Image Ping: can only send GET requests; cannot access the server's response text.
var img = new Image();
img.onload = img.onerror = function () {
console.log('Done!');
};
img.src = 'http://api.hitokoto.us/rand?encode=jsc';
- JSONP: consists of two parts: the callback function and the data.
function myCallBack (data) {
console.log(data.hitokoto); // Like you usually do, create miracles-
}
var script = document.createElement('script');
script.src = 'http://api.hitokoto.us/rand?encode=jsc&fun=myCallBack'; // Returns JSON wrapped in a function call, invoking the myCallBack function: myCallBack({"hitokoto":"...","author":"...",....});
document.body.insertBefore(script, document.body.firstChild);
Disadvantages: unreliable security; difficult to determine request failures.
To Be Continued...