Wiking some concepts in javascript based on my understanding.
- TypedArray, ArrayBuffer and View
- for...in vs for...of
- Array.from vs Spread syntax
- Temporal Dead Zone with let, const
- Functions
- Rest parameters
- Rest parameters(...) vs Spread syntax(...)
- "this" in ES6 Arrow functions
- Iterable in Javascript
- Prototype Chaining
- Property access/use declared with/in function
- Default Parameters
- "this" in Javascript
- Destructuring Assignment
- Bookmarklet
- DOMContentLoaded vs load
- "href" attribute in <a>
- function*: Generator function
- HTML tags vs HTML elements
- HTML Node object vs HTML Element object
- parentNode vs parentElement
- About DOM
- innerText vs textContent
- The problem of document.write()
- About Window.getComputedStyle() and element's style property
- beforeunload event
- keypress vs keydown
- event.target and this
- Event Propagation:Bubbling vs Capturing
- DocumentFragment
- jQuery .val(value): when the type of value is array
- offsetWidth vs clientWidth
- Function.length vs arguments.length
TypedArray consists of buffer(ArrayBuffer) + view.
Arraybuffer is an actual strorage for the bytes which is used for binary data transfers between server and client.
You need View to access the content of Arraybuffer.
More Information
for...in only iterates enumerable properties including prototype chain.
for...of only works with iterable objects such as Array, String.
for...of will loop over DOM collections like NodeList objects correctly:
var list = document.querySelectorAll( 'input[type=checkbox]' );
for (var item of list) {
item.checked = true;
}
Array.from can be used with iterable objects or Array-like objects which don't implement the iterable protocol.
Spread syntax(...) (other than in the case of spread properties) can be only used with iterable objects.
In ECMAScript 2015, let bindings are not subject to Variable Hoisting, which means that let declarations do not move to the top of the current execution context. Referencing the variable in the block before the initialization results in a ReferenceError (contrary to a variable declared with var, which will just have the undefined value). The variable is in a "temporal dead zone" from the start of the block until the initialization is processed.
More info: http://exploringjs.com/es6/ch_variables.html#sec_temporal-dead-zone
In JavaScript, functions are first-class objects, because they can have properties and methods just like any other object. What distinguishes them from other objects is that functions can be called. In brief, they are Function objects.
function f(a, b, ...theArgs) {}
If the last named argument of a function is prefixed with ..., it becomes an array whose elements from 0 (inclusive) to theArgs.length (exclusive) are supplied by the actual arguments passed to the function.
Rest syntax is the opposite of Spread syntax: Spread 'expands' an array into its elements, while Rest collects multiple elements and 'condenses' them into a single element.
The "this" value (internally) is not actually bound to the arrow function. Normal functions in JavaScript bind their own "this" value, however the "this" value used in arrow functions is actually fetched lexically from the scope it sits inside. It has no "this", so when you use this you’re talking to the outer scope. MOST IMPORTANTLY, "this" in arrow functions only sets once, which means it's pretty static and it never changes.
An object is iterable if it defines its iteration behavior, such as what values are looped over in a for...of construct. Some built-in types, such as Array or Map, have a default iteration behavior, while other types (such as Object) do not.
In order to be iterable, an object must implement the @@iterator method, meaning that the object (or one of the objects up its prototype chain) must have a property with a Symbol.iterator key.
What happens if you call a method on person1, which is actually defined on Object?
person1.valueOf()
The browser initially checks to see if the person1 object has a valueOf() method available on it. It doesn't, so the browser then checks to see if the person1 object's prototype object(Person function/class prototype object) has a valueOf() method available on it. It doesn't either, so the browser then checks to see if the Person function/class prototype object's prototype object(Object prototype object) has a valueOf() method available on it. It does, so it is called.
function A() {
var aVar = function() { console.log("local variable"); };
this.aVar = function() { console.log("member property"); };
}
A.prototype.aVariable = function() { console.log("prototype property"); };
A.aVar = function() { console.log("static property"); };
var a = new A();
a.aVar(); // log: member property
a.aVariable(); // log: prototype property
A.aVar(); // log: static property
// There is no way to access/use the local variable aVar outside of the function A.
Default function parameters allow formal parameters to be initialized with default values if no value or undefined is passed.
function multiply(a, b = 1) {
return a * b;
}
multiply(5, 2); // 10
multiply(5); // 5
"this" is the current execution context of a function. It varies under the below circumstances:
- function invocation: global object(window object or undefined in strict-mode)
- method invocation: the object which contains the method
- constructor invocation: the newly created object
- indirect invocation(call, apply, bind): the first argument
The destructuring assignment syntax is a JavaScript expression that makes it possible to unpack values from arrays, or properties from objects, into distinct variables.
[a, b, ...rest] = [10, 20, 30, 40, 50];
console.log(a); // 10
console.log(b); // 20
console.log(rest); // [30, 40, 50]
var a = 1;
var b = 3;
[a, b] = [b, a];
console.log(a); // 3
console.log(b); // 1
A variable can be assigned a default, in the case that the value unpacked from the object is undefined.
var {a = 10, b = 5} = {a: 3};
console.log(a); // 3
console.log(b); // 5
Setting a function parameter's default value
function drawES2015Chart({size = 'big', cords = {x: 0, y: 0}, radius = 25} = {}) {
console.log(size, cords, radius); // big {x: 18, y: 30} 30
}
drawES2015Chart({
cords: {x: 18, y: 30},
radius: 30
});
Entering "javascript:" in the url bar executes javascript and it enables us to manipulate the current page.
DOMContentLoaded awaits only for HTML and scripts to be loaded, which means it's fired when the elements in the document are ready to be accessed by the script. The load event is fired when the page is fully loaded with all dependent resources including images and styles.
This attribute may be omitted(as of HTML5) to create a placeholder link. A placeholder link resembles a traditional hyperlink, but does not lead anywhere.
The function* declaration defines a generator function. Generators are functions which can be exited and later re-entered. Calling a generator function does not execute its body immediately; an iterator object for the function is returned instead. When the iterator's next() method is called, the generator function's body is executed until the first yield expression. The next() method returns an object with a value property containing the yielded value and a done property which indicates whether the generator has yielded its last value as a boolean. Calling the next() method with an argument will resume the generator function execution, replacing the yield statement where execution was paused with the argument from next(). A return statement in a generator, when executed, will make the generator done. If a value is returned, it will be passed back as the value. A generator which has returned will not yield any more values.
function* idMaker() {
var index = 0;
while (index < 3)
yield index++;
}
var gen = idMaker();
console.log(gen.next().value); // 0
console.log(gen.next().value); // 1
console.log(gen.next().value); // 2
console.log(gen.next().value); // undefined
HTML tag is just opening or closing entity. <p> is an opening tag and </p> is a closing tag. HTML element encompasses opening tag, closing tag and content. <p>This is the content</p>: This complete thing is called a HTML element.
Node is the generic name for any type of object in DOM hierarchy. Element is one specific type of Node. DOM consists of a various type of nodes (text nodes, comment nodes etc). So nodeList is simply an array-like list of nodes. HTML5 defines HTMLCollection which is a list of HTML Elements(not any node, only Elements). While it is very similar in interface to nodeList, a distinction is now made in that it only contains Elements, not any type of node.
In most cases, they are same. The only difference comes when a node's parentNode is not an element. If so, parentElement is null.
document.body.parentNode; // the <html> element
document.body.parentElement; // the <html> element
document.documentElement.parentNode; // the document node
document.documentElement.parentElement; // null
Since the element(document.documentElement) doesn't have a parent that is an element, parentElement is null.
DOM(Document Object Model) represents the document as nodes and objects. That way, programming languages can connect to the page.
textContent is the raw textual content inside of the node. innerText is the text which would be presented to the user.
<div id="t">
<div>lions,tigers</div>
<div style="visibility:hidden">and bears</div>
</div>
innerText: "lions, tigers", textContent: "lions, tigers and bears"
document.write() can be called during the page load, while the browser is parsing the page. Once the page has parsed/loaded, calling this function will also call document.open(), which wipes the page and starts from scratch.
The returned object of getComputedStyle is the same type as the object returned from the element's style property; however, the two objects have different purposes. The object returned from getComputedStyle is read-only and can be used to inspect the element's style. The element.style object should be used to set styles on a specific element. Plus, as you may assume, getComputedStyle returns the absolute/computed values while element's style property returns the relative values such as percentage.
The beforeunload event is fired when the user is about to leave the page. Only if a string is assigned to the returnValue of the event object, a dialog appears asking the user for confirmation. Since Chrome 51.0, the custom text support is removed.
keypress event is fired only when a key that produces a character value is pressed down. keydown event is fired when a key is pressed down no matter whether it produces a character value or not.
A handler on a parent element always get the details about where the event actually comes from. The most deeply nested element that caused the event is referred as a target element, accessible as event.target.
Note the differences from this(=event.currentTarget)
- event.target is the "target" element that initiated the event. It doesn't change through the bubbling process.
- this(event.currentTarget) is the "current" element which the handler is actually handling at that moment.
Sidenote: this doesn't indicate the the current target in the arrow function syntax.
With bubbling, the event is first captured and handled by the innermost element and then propagated to outer elements. With capturing, the event is first captured by the outermost element and propagated to the inner elements. We can use addEventListener(type, listener, useCapture) to register event handlers for in either bubbling(default) or capturing mode. To use the capturing, pass the third argument as true.
DocumentFragments are DOM Nodes but never part of the main DOM tree. Since they only exist in memory, not part of the main DOM tree, appending children to it does not cause page reflow. The usual use case is to create the document fragment, append elements to the document fragment and then append the document fragment to the DOM tree. In the DOM tree, the document fragment is replaced by all its children.
val() allows you to pass an array of element values. This is useful when working on a jQuery object containing elements like <input type="checkbox">, <input type="radio">, and <option>s inside of a <select>. In this case, the inputs and the options having a value that maches one of the elements of the array will be checked or selected while those having a value that doesn't match one of the elements of the array will be unchecked or unselected, depending on the type. Setting values using this method(or using the native value property) doesn't cause the dispatch of the change event. If you want to execute them, you should call .trigger("change") after setting the value.
offsetWidth is a read-only property which returns the layout width of an element. It includes the element borders, horizontal padding and the element css width. clientWidth is zero for elements with no CSS or inline layout boxes, otherwise it's the inner width of an element in pixels. It includes padding but not border.
Function.length indicates how many arguments the function expects. By contrast, arguments.length provides the number of the arguments actually passed to the function.