The essence of JavaScript language study notes
grammar
1. Notes
JS provides two comment methods: one is block comment: / commented content /, and the other is line comment: // commented content.
It is not safe to use block comments, for example, with regular expressions:
// /* var test = /test*/; // */
2. Numbers
var isNaN = isNaN(number); // Use the isNaN method to determine whether it is a number, if it is not a number, return true, otherwise, return false
3. Strings are immutable
'A' === '\u0041'; // true 'c' + 'a' + 't' === 'cat'; // true 'cat'.toUpperCase() === 'CAT'; // true
4. Statement
Conditional judgments will be treated as false values: false,null,undefined,'',0,NaN, and all other values are treated as true.
5. Operators
The values produced by the typeof operator are: 'number','string','boolean','undefined','function','object'.
The conversion rules for the '+' plus sign give priority to string concatenation. If one of the operands is a string or an object converted to a string, the other operand will be converted to a string, and the addition will perform a string concatenation operation. If both operands are not string-like, then arithmetic addition will be performed.
1 + 2 // 3 1 + '2' // '12' '1' + '2' // '12' 1 + {} // '1[object Object]' 1 + [] // '1' 1 + [1] // '11' true + true // 2 2 + null // 2 2 + undefined // NaN
The '/' operator may produce a non-integer result even if both operands are integers.
The '&&' operator usage technique: when the value of the first operand of && is false, take the value of the first operand, otherwise, take the value of the second.
0 && 1; // 0 false && true; // false true && false; // false 1 && 2; // 2
|| Operator usage skills: When the value of the first operand is true, take the value of the first operand, otherwise, take the value of the second. This technique is generally used to set default values.
undefined || 0; //0 null || {}; // {} 0 || []; // [] 1 || true; // 1
The above technique uses the short-circuit principle of && and ||. When the value on the left of the && operator is false, the value on the right is no longer executed. When the value on the left of the || operator is true, the value on the right is no longer executed.
object
1. Use literals to create objects
Object property values can use any value other than undefined
var obj = {}; obj.name = 'Better'; obj.age = 24; obj['first-name'] = 'liao'; //Since first-name is not a legal identifier, [] must be used instead of . obj.last_name = 'longdong'; // last_name is a legal identifier
2. Quote
Objects are passed by reference
var a = {}, b ={}, c = {}; //a,b,c belong to different objects because their references are different a == b; // false a.name = 'Better'; b.name = 24; console.log(a); // {name: 'Better'} console.log(b); // {name: 24} var a = b = c = {}; // a,b,c belong to the same object because their references (addresses) are the same a === b; // true a.name = 'Better'; b.age = 24; console.log(a); // {name: 'Better', age: 24} console.log(b); // {name: 'Better', age: 24}
3. Prototype
Each object has a prototype object. The so-called prototype chain is to find the properties and methods of the object. First, check whether the object itself has the property or method. If not, search along the prototype object until Object.prototype, Returns undefined if none.
// Simulate the Object.create() method to create a new object if( typeof Object.create === 'function'){ Object.create = function (obj) { var F = function(){}; F.prototype = obj; return new F(); } } obj.hasOwnProperty('name'); // This method is used to detect whether the object itself has this attribute, and will not look for attributes and methods in the prototype chain
4. Global variables
There are two main ways to reduce global variables: first, use namespaces, and second, use closures
// use namespace var mynamespace = {}; mynamespace.module1 = { name : 'xiaoxin', age: 24 }; mynamespace.module2 = { name: 'xiaowu', age: 22 }; // Using a closure, create a unique ID var create = function(){ var num = 0; return function(){ return num ++; } } var uId = create(); uId(); // 0 uId(); // 1 uId(); // 2
function
Functions are objects in JavaScript. The object produced by the object literal is connected to Object.prototype, and the function object is connected to Function.prototype (the prototype object itself is connected to Object.prototype).
Each function is created with two additional hidden attributes: the function's context and the code that implements the function's behavior. Each function object also has a prototype attribute when it is created, and its value is a constructor attribute, which points to the function object.
var f = function(){}; f.prototype.constructor === f; // true
1. Function literals (function expressions)
The difference between a function expression and a function declaration:
// function expression console.log(fun1); // undefined var fun1 = function(){ console.log(123); }; console.log(fun1); // function(){console.log(123)}; // function declaration console.log(fun2); // function fun2(){console.log(456)}; function fun2(){ console.log(456); }; console.log(fun2); // function fun2(){console.log(456)}; var fun3 = function(){ console.log(666); }; function fun3(){ console.log(888); }; console.log(fun3()); // 666 //Conclusion: 1. Both function expressions and function declarations will carry out variable promotion. Function expressions only promote the declared variables, not the function body, while function declarations will promote the function name and function body; 2. Function expressions will overwrite functions with the same name statement
2. Function call
There are four function calling modes in JavaScript: method calling mode, function calling mode, constructor calling mode and apply calling mode.
- method call pattern
When the function is used as a method (property) of an object, this points to the object.
var myObj = {}; // create an object myObj.name = 'Better'; myObj.method = function(){ // Add method to object console.log(this.name); }; myObj.method(); // 'Better'
- function call pattern
When a function does not have a method (property) as an object, this points to the global object (window object)
// global function function add(a, b){ return a + b; }; add(1, 2); // 3 myObj.value = 2; myObj.double = function(){ console.log(this); var that = this; // Store the this pointer pointing to the myObj object in the that variable var helper = function(){ console.log(this); // Here this points to the window object that.value = add(that.value, that.value); }; helper(); // Call the helper function as a function }; myObj.double(); // Call the double function as a method myObj.value; // 4
- Constructor call pattern
If the function is called with new in front, then this points to the new object. Calling the function with new will also change the behavior of the return statement. If the return is an object, the object will be returned, otherwise, the newly created object will be returned (this).
// Create a constructor, and agree that the constructor starts with an uppercase function Fun(string){ this.status = string; }; // Add a public method to the constructor Fun.prototype.getStatus = function(){ return this.status; }; // create instance var fun = new Fun('Better'); fun.getStatus(); // 'Better' // This method is not recommended
- apply calling mode
The apply method has two parameters, the first parameter thisObj, which is the execution context of binding this, and the second parameter argArr, the parameter array.
// Create a constructor, and agree that the constructor starts with an uppercase function Fun(string){ this.status = string; }; // Add a public method to the constructor Fun.prototype.getStatus = function(){ return this.status; }; // create instance var fun = new Fun('Better'); fun.getStatus(); // 'Better' // this points to the global object function add(a, b){ return a + b; }; var arr = [3, 4]; var sum = add.apply(null, arr); // 7 // this points to the obj object var obj = {}; obj.status = 24; Fun.prototype.getStatus.apply(obj); // 24 fun.getStatus.apply(obj); // 24 fun.getStatus.apply(this); // When the first parameter of the apply method is null or undefined, this points to the global object (in non-strict mode) function test(){ console.log(this); }; test.apply(null); // this points to the global object (window object) test.apply(undefined); // this points to the global object (window object) test.apply(this); // this points to the global object (window object) test.apply(1); // this points to the Number object test.apply('string'); // this points to the String object test.apply(true); // this points to the Boolean object // Conclusion: In layman's terms, it is to execute a method under the scope of the first parameter (thisObj) of the apply method.
3. arguments class array parameter object
The arguments object is an array-like object with only the length property and no array-related methods. It can get the parameter list when the function is called. This object can only be used inside the function.
var sum = function(){ var sum = 0; for(var i = 0, len = arguments.length; i < len; i ++){ sum += arguments[i]; } return sum; }; console.log(sum(1, 2, 3, 4, 5)); // 15
4. Abnormal
JavaScript provides a set of exception handling mechanism.
var add = function(a, b){ if(typeof a !== 'number' || typeof b !== 'number'){ throw { name: 'TypeError', message: 'add needs numbers' }; } return a + b; }; add(1, 2); // 3 add(1, '2'); // report error add(); // report error // try_catch code block var try_it = function(){ try{ add('one'); }catch(e){ console.log(e.name + ' : ' + e.message); } }; try_id(); // TypeError : add needs numbers
5. Add methods to types
Make the method available to all objects by adding the method to Object.prototype.
Make the method available to all functions by adding the method to Function.prototype.
// Add methods to Function.prototype Function.prototype.method = function(name, func){ if(!this.prototype[name]){ this.prototype[name] = func; } }; // Add an integer method to the Number object Number.method('integer', function(){ var funName = this < 0 ? 'ceil' : 'floor'; return Math[funName](this); }); (10/4).integer(); // 2 (-10/4).integer(); // -2 // Add a method to the String object to remove both ends of the string String.method('trim', function(){ return this.replace(/^\s+|\s+$/, ''); }); ' Better '.trim(); // 'Better'
6. Recursion
A recursive function calls one of its own functions, directly or indirectly. In general, a recursive function calls itself to solve its subproblems.
Recursion can be very efficient for manipulating tree structures, such as the Document Object Model (DOM) on the browser side. Process a small segment of the given tree on each recursive call.
// walk_the_DOM calls itself to process each child node var walk_the_DOM = function walk(node, func){ func(node); node = node.firstChild; while(node){ walk(node, func); node = node.nextSibling; } }; // Create a function that looks up a node by attribute var getElementByAttribute = function(attr, value){ var results = []; walk_the_DOM(document.body, function(node){ var actual = node.nodeType === 1 && node.getAttribute(attr); if(typeof actual === 'string' && (actual === value || typeof value !== 'string')){ results.push(node); } }); return results; }; // Calculate the factorial of a number using recursion var factorial = function factorial(i, a){ a = a || 1; if(i < 2){ return a; } return factorial(i - 1, a * i); }; factorial(3); // 6 factorial(3, 2); // 12 factorial(3, 3); // 18 // Using arguments.callee() in anonymous functions is deprecated // Disallow the use of arguments.callee() when giving a function expression a name or when using a function declaration that must call itself // arguments.callee() is disallowed in ES5 strict mode function create(){ return function(num){ if(num < 2){ return 1; }else{ return num * arguments.callee(num - 1); } } }; var result = create()(3); // 6
7. Scope
Scope controls the visibility and lifetime of variables and parameters.
JavaScript has function scope, but not block-level scope. The best practice is to declare all variables that may be used in the function at the top of the function body.
// The variables in the function will be variable promoted, so run the cxt() function, the first two console.log(c); no error is reported function cxt(){ var a = 1, b = 2; console.log(c); // undefined function innerFun(){ var a = 6, b =7, c = 8; console.log(a, b, c); // 6 7 } innerFun(); console.log(c); // undefined if(a == 1){ // false var c = 3; }; console.log(c); // 3 }
8. Closure
A closure is a function that has access to variables in the scope of another function. The most common way to create a closure is to create another function within a function and access the local variables of this function through another function.
var myObject = function(){ var value = 0; return { increment: function(inc){ value += typeof inc === 'number' ? inc : 1; }, getValue: function(){ return value; } }; }(); // Create a constructor called quo var quo = function(status){ return { getStatus: function(){ return status; } }; }; // Construct a quo instance var myQuo = quo('crazy'); console.log(myQuo.getStatus()); // 'crazy' // This constructor is designed to be used without adding new, so the name is not capitalized // Define a function that sets a DOM node to yellow and then fades it to white var fade = function(node){ var level = 1; var step = function(){ var hex = level.toString(16); // Convert to hexadecimal console.log(hex); node.style.backgroundColor = '#FFFF' + hex + hex; if(level < 15){ level += 1; setTimeout(step, 100); } }; setTimeout(step, 100); }; fade(document.body);
9. Callback
Callback functions can make discrete event handling easier.
// This synchronous request blocks the process request = prepare_the+request(); response = send_request_synchronously(request); display(response); // A better way to use asynchronous callback requests request = prepare_the_request(); send_request_asynchronously(request, function(response){ display(response); });
10. Module
Modules can be constructed using functions and closures.
A module is a function or object that provides an interface but hides state and implementation.
The general form of the module pattern: a function that defines private variables and functions; use closures to create privileged functions that can access private variables and functions; finally return this privileged function, or save them to an accessible place.
// Add this method to all functions Function.prototype.method = function(name, func){ if(!this.prototype[name]){ this.prototype[name] = func; } } String.method('deentityify', function(){ // character entity table var entity = { quot: '""', lt: '<', gt: '>' }; // return deentityify method return function(){ // Using the replace method of a string // Find substrings starting with '&' and ending with ';' return this.replace(/&([^&;]+);/g, function(a, b){ console.log(a, b); // a is the first match of the regular expression, b is the second match (the match in the parentheses of the regular expression) var r = entity[b]; return typeof r === 'string' ? r : a; }); } }()); // The immediate execution function is used here console.log('<">'.deentityify()); // <""> // Construct an object used to generate serial numbers var serial_marker = function(){ // Returns an object used to generate unique strings // The unique string consists of two parts: prefix + serial number // This object contains a method to set the prefix, a method to set the serial number and a gensym method to generate a unique string var prefix = ''; var seq = 0; return { set_prefix: function(p){ prefix = String(p); }, set_seq: function(s){ seq = s; }, gensym: function(){ var result = prefix + seq; seq += 1; return result; } }; }; var seqer = serial_marker(); seqer.set_prefix('Q'); seqer.set_seq(1000); var unique = seqer.gensym(); // unique is "Q1000" var unique = seqer.gensym(); // "Q1001"
The module pattern is often used in conjunction with the singleton pattern (Singleton Pattern).
A JavaScript singleton is an object created using object literal notation. The property value of an object can be a value or a function, and the property value will not change during the life cycle of the object.
11. Chain call (cascading)
Method returns this instead of undefined to enable chained calls (cascading), which can produce powerfully expressive interfaces.
getElement('myBoxDiv'). move(100, 200). width(100). height(200). color('red'). on(mouseover, func);
12. Memory
Functions can use objects to remember the results of previous operations, thereby avoiding redundant operations. This optimization is called memoization. JavaScript objects and arrays are very convenient for this optimization.
// Fibonacci sequence, Fibonacci sequence, characteristic, the sum of the previous adjacent two items is equal to the value of the latter item. var fibonacci = function(n){ return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2); }; for(var i =0; i <= 10; i ++){ console.log(i, fibonacci(i)); } // 0 0 // 1 1 // 2 1 // 3 2 // 4 3 // 5 5 // 6 8 // 7 13 // 8 21 // 9 34 // 10 55 // fibonacci was called 453 times, except that we called 11 times, most of the other calls were calculating the values that had already been calculated // The above example does a lot of repetitive work, let’s optimize it var fibonacci = function(){ var memo = [0, 1]; var fib = function(n){ var result = memo[n]; if(typeof result !== 'number'){ // Determine whether the result already exists result = fib(n - 1) + fib(n - 2); memo[n] = result; } return result; }; return fib; }(); for(var i =0; i <= 10; i ++){ console.log(i, fibonacci(i)); } // After this optimization, only 29 calls are made, we call 11 times, and the function itself calls 18 times // Write a function to help us construct functions with memo kinetics, it returns a shell function that manages the memo storage and calls the func function when needed. var memoizer = function(memo, func){ var shell = function(n){ var result = memo[n]; if(typeof result !== 'number'){ result = func(shell, n); memo[n] = result; } return result; }; return shell; }; // Use memoizer to define fibonacci function var fibonacci = memoizer([0, 1], function(shell, n){ return shell(n - 1) + shell(n - 2); }); // Use memoizer to define factoriala function var factorial = memoizer([1, 1], function(shell, n){ return n * shell(n - 1); });
inherit
1. Pseudo class
When a function object is created, the function object generated by the Function constructor will run some code like this:
this.prototype = {constructor: this};
The new function object is given a prototype attribute whose value contains a constructor attribute whose value is the new function object. Every function has a prototype object.
function f(){}; f.prototype.constructor === f; // true
Define a constructor and add methods to the prototype
// father // create constructor var Mammal = function(name){ this.name = name; }; // Add method to prototype Mammal.prototype.getName = function(){ return this.name; }; Mammal.prototype.say = function(){ return this.saying || 'hello'; }; var myMammal = new Mammal('Herb the Mammal'); var name = myMammal.getName(); // 'Herb the Mammal' // Subclass var Cat = function(name){ this.name = name; this.saying = 'meow'; }; // Replace Cat.prototype with a new Mammal instance (inheriting the parent class) Cat.prototype = new Mammal(); // Add methods to the new prototype object Cat.prototype.purr = function(n){ var i, s = ''; for(i = 0; i < n; i += 1){ if(s){ s += '-'; } s += 'r'; } return s; }; Cat.prototype.getName = function(){ return this.say() + ' ' + this.name + ' ' + this.say(); }; var myCat = new Cat('Henrietta'); var say = myCat.say(); // 'meow' var purr = myCat.purr(5); // 'r-r-r-r-r' var name = myCat.getName(); // 'meow Henrietta meow' // Hide the details of the prototype operation. This part of the code needs to use the above Mammal parent class code to run Function.prototype.method = function(name, func){ if(!this.prototype[name]){ this.prototype[name] = func; } return this; }; Function.method('inherits', function(Parent){ this.prototype = new Parent(); return this; }); var Cat = function(name){ this.name = name; this.saying = 'meow'; }. inherits(Mammal). method('purr', function(n){ var i, s = ''; for(i = 0; i < n; i += 1){ if(s){ s += '-'; } s += 'r'; } return s; }). method('getName', function(){ return this.say() + ' ' + this.name + ' ' + this.say(); }); var cat = new Cat('icat'); cat.getName(); // 'icat' cat.purr(5); // r-r-r-r-r // Disadvantages of this approach: no private environment, all properties are public.
2. Prototype
// create a useful object var myMammal = { name: 'Herb the Mammal', getName: function(){ return this.name; }, says: function(){ return this.saying || ''; } }; // Use the Object.create() method to construct more instances to var myCat = Object.create(myMammal); myCat.name = 'Henrietta'; myCat.saying = 'meow'; myCat.purr = function(n){ var i, s = ''; for(i = 0; i < n; i ++){ if(s){ s += '-'; } s += 'r'; } return s; }; myCat.getName = function(){ return this.says() + ' ' + this.name + ' ' + this.says(); }; // This is a type of "differentiated inheritance", where by formulating a new object we indicate how it differs from the base object on which it is based.
3. Functionalization
The name attribute and saying attribute in the previous example are completely public. The following example makes the name attribute and saying attribute private variables:
// Application of the module pattern var mammal = function(spec){ var that = {}; that.getName = function(){ return spac.name; }; that.says = function(){ return spec.saying || ''; }; return that; }; var myMammal = mammal({name: 'Herb'}); var cat = function(spec){ spec.saying = spec.saying || 'meow'; var that = mammal(spec); that.purr = function(n){ var i, s = ''; for(i = 0; n < i; i ++){ if(s){ s += '-'; } s += 'r'; } return s; }; that.getName = function(){ return that.says() + ' ' + spec.name + ' ' + that.says(); }; return that; }; var myCat = cat({name: 'Henrietta'}); // The functional pattern gives us a way to deal with parent classes Function.prototype.method = function(name, func){ if(!this.prototype[name]){ this.prototype[name] = func; } return this; }; Object.method('superior', function(name){ var that = this; method = that[name]; return function(){ return method.apply(that, arguments); } }); var coolcat = function(spec){ var that = cat(spec); var superGetName = that.superior('getName'); that.getName = function(){ return 'like ' + superGetName() + ' baby'; }; return that; }; var myCoolCat = coolcat({name: 'Bix'}); var name = myCoolCat.getName(); // 'like meow Bix meow baby'
4. Parts
var eventuality = function(that){ var registry = {}; that.fire = function(event){ var array, func, handler, i, type = typeof event === 'string' ? event : event.type; // If there is a set of event handlers for this event, then traverse them and execute them in order if(registry.hasOwnProperty(type)){ array = registry[type]; for(i = 0; i < array.length; i ++){ handler = array[i]; // Each handler consists of a method and an optional set of parameters // If the method is a string name, then find the function func = handler.method; if(typeof func === 'string'){ func = this[func]; } func.apply(this, handler.parameters || [event]); } } return this; }; that.on = function(type, method, parameters){ // Registers an event, constructs a handler entry, inserts it into the handlers array, and constructs one if an event of this type does not already exist var handler = { method: method, parameters: parameters }; if(registry.hasOwnProperty(type)){ registry[type].push(handler); }else{ registry[type] = [handler]; } return this; }; return that; }; // In this way, a constructor can assemble objects from a set of parts
array
An array is a linearly allocated piece of memory that uses integers to calculate offsets and access its elements. Arrays can be very fast data structures. However, JavaScript does not have a data structure like this array.
JavaScript provides an object with some array-like characteristics, which converts the subscript of the array into a string and uses it as an attribute. Its performance is significantly slower than real arrays, but it can be more convenient to use.
1. Array literals
The first value of the array will get the property name '0', the second will get the property name '1', and so on:
// array literal var empty = []; var numbers = ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine']; console.log(empty[1]); // undefined console.log(numbers[1]); // 'one' console.log(numbers['1']); // 'one' console.log(empty.length); // 0 console.log(numbers.length); // 10 // object literal var numbers_object = { '0': 'zero', '1': 'one', '2': 'two', '3': 'three', '4': 'four', '5': 'five', '6': 'six', '7': 'seven', '8': 'eight', '9': 'nine' }; // In most languages, all elements of an array are required to be of the same type. However, JavaScript allows arrays to contain values of arbitrary mixed types var misc = ['steing', 66, true, null, undefined, [1, 2, 3], NaN, {name: 'Better'}];
The difference between numbers and numbers_object:
- numbers inherits from Array.prototype, and numbers_object inherits from Object.prototype
- numbers inherits a large number of methods for manipulating arrays
- numbers have a length attribute, but numbers_object does not
2. Length
The length attribute of a JS array has no upper limit. If you use a number equal to or greater than the current length as a subscript to save an element, the length will increase to accommodate the new element, and no array out-of-bounds error will occur.
// The value of the length attribute is the largest integer attribute name of the array plus 1, which is not necessarily equal to the number of attributes in the array var myArray = []; console.log(myArray.length); // 0 // myArray[10000] = true; myArray['10000'] = true; console.log(myArray.length); // 10001 // You can directly set the value of the length attribute of the array. Setting a larger length will not allocate more space to the array. // And setting the length to a small value will cause all attributes equal to or greater than the new length to be deleted var numArr = [0, 1, 2, 3, 4, 5]; numArr.length = 3; console.log(numArr); // [0, 1, 2] // Add a new element to the end of the array numArr[numArr.length] = 3; console.log(numArr); // [0, 1, 2, 3] // Add new elements to the end of the array, using the push method numArr.push(4); console.log(numArr); // [0, 1, 2, 3, 4]
3. Delete
Since JavaScript arrays are actually objects, you can use the delete operator to remove elements in the array, but a hole will be left in the array.
var numArr = [0, 1, 2, 3, 4, 5]; delete numArr[2]; console.log(numArr); // [0, 1, undefined, 3, 4, 5] // Using the splice() method on an array var numArr = [0, 1, 2, 3, 4, 5]; // Starting from the position where the array subscript is 2, delete 1 array element, // And insert 66 elements at this position, and return the deleted element array [2] numArr.splice(2, 1, 66); // [2] console.log(numArr); // [0, 1, 66, 3, 4, 5]
4. Enumeration
Because arrays in JS are also objects, you can use the for in statement to traverse all properties of the array.
However, using the for in statement does not guarantee the order of the properties, and there is a possibility of getting unexpected properties from the prototype chain
// Use for in to traverse the properties of the array (not recommended) var nums = ['zero', 'one', 'two', 'three']; for(var num in nums){ console.log(num, nums[num]); } // It is recommended to use a for loop to traverse the array for(var i = 0, len = nums.length; i < len; i ++){ console.log(i, nums[i]); }
5. Judging arrays (including other types)
// The method used in this book (the length in the array is not enumerable, can the length be traversed through for in?) var arr = []; var obj = {}; var is_array = function(value){ return value && // Check if the value is true typeof value === 'object' && // Is it an object typeof value.length === 'number' && // Whether there is a length attribute and the value is a number type typeof value.splice === 'function' && // Is there a splice method !(value.propertyIsEnumerable('length')); // Is the length property enumerable }; console.log(is_array(arr)); // true console.log(is_array(obj)); // false // Determine whether a value is an array (the most common method) function isArray(value){ return Object.prototype.toString.call(value) === '[object Array]'; } var arr = []; var num = 1; var bool = true; var str = 'string'; var obj = {}; var func = function(){}; console.log(isArray(arr)); // true console.log(Object.prototype.toString.call(num)); // '[object Number]' console.log(Object.prototype.toString.call(bool)); // '[object Boolean]' console.log(Object.prototype.toString.call(str)); // '[object String]' console.log(Object.prototype.toString.call(obj)); // '[object Object]' console.log(Object.prototype.toString.call(func)); // '[object Function]' console.log(Object.prototype.toString.call(null)); // '[object Null]' console.log(Object.prototype.toString.call(undefined)); // '[object Undefined]' // PS: The premise of using this method is that the toString() method of the Object object has not been overridden
6. Method
JS provides a set of methods for manipulating arrays, which are stored in Array.prototype, and we can extend array methods by adding methods in Array.prototype
// Extend a method, each array will inherit this method Array.prototype.reduce1 = function(func, value){ for(var i =0, len = this.length; i < len; i ++){ value = func(this[i], value); } return value; }; var arr = [1, 2, 3, 4, 5]; var add = function(a, b){ return a + b; }; var mult = function(a, b){ return a * b; }; var sum = arr.reduce1(add, 0); // 15 var product = arr.reduce1(mult, 1); // 120 // Because arrays are also objects, you can add methods to arrays separately arr.total = function(){ return this.reduce1(add, 0); }; total = arr.total(); // 15
7. Dimension
// Define a method to initialize an array Array.dim = function(dimension, initial){ var a = [], i; for(i = 0; i < dimension; i ++){ a[i] = initial; } return a; } // Create an array of 6 6's var myArray = Array.dim(6, 6); // [6, 6, 6, 6, 6, 6] // Multidimensional Arrays var matrix = [ [0, 1, 2], [3, 4, 5], [6, 7, 8] ]; matrix[2][0]; // 6 // array matrix Array.matrix = function(m, n, initValue){ var i, j, a, mat = []; for(i = 0; i < m; i ++){ a = []; for(j = 0; j < n; j ++){ a[j] = initValue; } mat[i] = a; } return mat; } // Create a 4x4 matrix filled with 6 var myMatrix = Array.matrix(4, 4, 6); console.log(myMatrix[3][3]); // 6 // create an identity matrix Array.identity = function(n){ var i, mat = Array.matrix(n, n, 6); for(i =0; i < n; i ++){ mat[i][i] = 8 } return mat; } var myMatrix1 = Array.identity(4); console.log(myMatrix1[3][2]); // 6 console.log(myMatrix1[3][3]); // 8
regular expression
Regular expression is a grammar specification of a simple language, which is used in the form of methods to search, replace and extract information in strings.
The main methods for processing regular expressions are: regexp.exec, regepx.test, string.match, string.replace, string.search, string.split.
Description of common characters in regular expressions:
- Dot character: . matches all characters except carriage return (\r), newline (\n), line separator (\u2028), and paragraph separator (\u2029).
- Positional characters: ^ indicates the start position of the string, and $ indicates the end position of the string.
- Selection characters: | means "or", such as, a|b, means to match a or b.
- Escape character: \ is used to escape the characters with special meaning in the expression, such as +, -, ?, etc. For example, \+ means to match +.
- caret: 1 Indicates to match any character except a, b, c.
- Hyphen: [0-9] means to match numbers from 0 to 9. [A-Z] means match 26 uppercase letters from A to Z.
- Predefined patterns:
- Repeated category: {n,m} means repeating no less than n times and no more than m times.
- Quantifier character:
1. a? Indicates that matching a occurs 0 or 1 times, which is equivalent to a{0,1}.
2. a* means matching a occurs 0 or more times, which is equivalent to a{0,}.
3. a+ means matching a appears one or more times, which is equivalent to a{1,}. - Greedy mode: By default, it is the maximum possible match, that is, match until the next character does not meet the matching rules. This is called greedy mode.
- Non-greedy mode:
1. *? Indicates that a pattern appears 0 or more times, and a non-greedy pattern is used for matching.
2. +? Indicates that a pattern appears one or more times, and a non-greedy pattern is used for matching. - Modifiers:
1. The g modifier means global matching (global).
2. The i modifier means ignore case (ignorecase).
3. The m modifier means multiline mode (multiline), which will modify the behavior of ^ and $. - Group matching: (abc) means group matching, the brackets of the regular expression means group matching, and the patterns in the brackets can be used to match the content of the group.
- Non-capturing group matching: (?:abc) means non-capturing group matching, non-capturing group matching does not return the matched content of the group, that is, the matching result does not include this bracket (matching group).
- The difference between group matching and non-capturing group matching:
1. When using the exec and match methods, the group matching will be put into the matching array (matching group) returned by the exec and match methods.
2. The non-capturing group matching performance is better than the group matching performance.
1. Examples
// Regular expression to match URL s var parse_url = /^(?:([A-Za-z]+):)?(\/{0,3})([0-9.\-A-Za-z]+)(?::(\d+))?(?:\/([^?#]*))?(?:\?([^#]*))?(?:#(.*))?$/; var url = 'http://www.better.com:8080/goodparts?q#fragment'; // Use the regular expression's exec() method, which returns an array of matches var result_arr = parse_url.exec(url); var names = ['url', 'scheme', 'slash', 'host', 'port', 'path', 'query', 'hash']; var line_end = '\n'; var i; for(i = 0, len = names.length; i < len; i ++){ console.log(names[i] + ' : ' + result_arr[i] + line_end); } // Output result: // url : http://www.better.com:8080/goodparts?q#fragment // scheme : http // slash : / // host : www.better.com // port : 8080 // path : goodparts // query : q // hash : fragment // Regular expression to match numbers var parse_num = /^-?\d+(?:\.\d*)?(?:e[+\-]?\d+)?$/i; var test_num = function(num){ return parse_num.test(num); } console.log(test_num('1')); // true console.log(test_num('-1')); // true console.log(test_num('0.01')); // true console.log(test_num('0.')); // true console.log(test_num('1.2.3')); // false console.log(test_num('123.45e-67')); // true console.log(test_num('123.45E+67')); // true console.log(test_num('123.456D-7')); // false // It is usually a good idea to use non-capturing groupings instead of a small number of unsightly capturing groups // Because capturing has a performance penalty.
2. Structure
Regular expressions can be created in two ways:
// The most common way (literal) var reg = /^\d+$/g; console.log(reg.test(123)); // true console.log(reg.test('123s')); // false // When using the RegExp constructor, the backslash (\) has a different meaning from the literal // Usually need to double write the backslash to escape var reg = new RegExp('^\\d+$', 'g'); console.log(reg.test(123)); // true console.log(reg.test('123s')); // false
method
JavaScript has many built-in objects, such as Array,Date,RegExp,Error,Math, and encapsulation objects of basic data types, Number,Boolean,String, etc. These built-in objects provide many properties and methods for operating this type. These methods store In a built-in object or in the prototype object of a built-in object.
1,Array
// array.concat(item...) method, concatenating arrays var a = [1, 2, 3]; var b = ['a', 'b', 'c']; var c = a.concat(b, true); // [1, 2, 3, "a", "b", "c", true] // array.join(separator) method, which has better performance than the + operator to concatenate strings var a = ['a', 'b', 'c']; var c = a.join(' @ '); // "a @ b @ c" // The array.pop() method removes the last element in the array. If the array is empty, the method returns undefined. // The array.pop() method and the array.push() method can be used in combination to simulate a last-in-first-out queue var a = ['a', 'b', 'c']; var c = a.pop(); // 'c' console.log(a); // ['a', 'b'] // Implement the pop() method Array.prototype.pop = function(){ return this.splice(this.length - 1, 1)[0]; }; // array.push(item...) method, add elements at the end of the array var a = [1, 2, 3]; var b = ['a', 'b', 'c']; var c = a.push(b, true); // 5. Return the length of the new array console.log(a); // [1, 2, 3, ['a', 'b', 'c'], true] // Implement the push() method Array.prototype.push = function(){ // Add the parameters of the push method to the third parameter of the splice method this.splice.apply(this, [this.length, 0].concat(Array.prototype.slice.apply(arguments))); return this.length; }; // The array.reverse() method reverses the order of the elements in the array. var a = [1, 2, 3]; var b = a.reverse(); // [3, 2, 1] // The array.shift() method, removes the first element in the array, if the array is empty, the method returns undefined. // The shift method is usually much slower than the pop method var a = [1, 2, 3]; var b = a.shift(); // 1 console.log(a); // [2, 3] // Implement the shift method Array.prototype.shift = function(){ return this.splice(0, 1)[0]; }; // array.slice(startIndex, endIndex) method, intercept the array var a = [1, 2, 3]; console.log(a.slice(0, 1)); // [0] console.log(a.slice(1)); // [2, 3] console.log(a.slice(1, 3)); // [2, 3] // The array.sort(comparefn) method, sorts the array // If no comparison function is passed, the default comparison function will convert all elements into strings and then compare them var a = [3, 1, 5, 23, 16, 8]; console.log(a.sort()); // [1, 16, 23, 3, 5, 8] // use comparison function var a = [3, 1, 8, 5, '4', 23, 16, 8]; var compareFun = function(a, b){ return a - b; }; console.log(a.sort(compareFun)); // [1, 3, "4", 5, 8, 8, 16, 23] // array.splice(startIndex, delCount, insertItem) var a = [1, 2, 3, 4, 5]; var b = a.splice(2, 1, 6, 6); // [3] , returns an array of removed elements console.log(a); // [1, 2, 6, 6, 4, 5] var a = [1, 2, 3, 4, 5]; var b = a.splice(2, 1, [6, 6]); // [3] , returns an array of removed elements console.log(a); // [1, 2, [6, 6], 4, 5] // array.unshift(item...) method, add elements to the head of the array var a = [1, 2, 3, 4]; var b = a.unshift(0); // 5. Return the length of the new array console.log(a); // [0, 1, 2, 3, 4] // Implement the unshift() method Array.prototype.unshift = function(){ this.splice.apply(this, [0, 0].concat(Array.prototype.slice.apply(arguments))); return this.length; };
Methods for manipulating arrays are stored in the Array.prototype prototype object, including ES5 and ES6 new array methods, such as forEach,reduce,map,entries,every,some and other methods.
2,Function
Function objects have two commonly used methods: apply and call methods. The difference between these two methods is that the parameters of the former are passed in the form of an array, while the latter is passed individually.
func.apply(thisArg, argArray), the first parameter of this method: execute the func method under the scope of thisArg, that is, point the this of the func method to thisArg, the second parameter (optional): to An array of arguments to pass to the func method. func.call(thisArg, arg1, arg2, ...).
// Use the apply method to implement the bind method Function.prototype.bind = function(that){ // Returns a function that is invoked as if it were a method of that object var self = this; console.log('self: ', self); var slice = Array.prototype.slice; console.log('arguments: ', arguments); var args = slice.apply(arguments, [1]); return function(){ return self.apply(that, args.concat(slice.apply(arguments, [0]))); }; }; var test = function(){ return this.value; }.bind({value: 'Better'}); console.log(test()); // 'Better'
3,Number
The Number object provides many methods for manipulating numbers. These properties and methods are stored in the Number object or the Number.prototype prototype object.
// number.toExponential(fractionDigits), this method converts the number into an exponential string. console.log(Math.PI.toExponential()); // 3.141592653589793e+0 console.log(Math.PI.toExponential(0)); // 3e+0 console.log(Math.PI.toExponential(2)); // 3.14e+0 // number.toFixed(fractionDigits), this method converts the number into a string in decimal form. console.log(Math.PI.toFixed()); // 3 console.log(Math.PI.toFixed(0)); // 3 console.log(Math.PI.toFixed(2)); // 3.14 // number.toPrecision(precision), this method converts number into a string in decimal form, precision is the number of valid digits console.log(Math.PI.toPrecision()); // 3.141592653589793 console.log(Math.PI.toPrecision(2)); // 3.1 console.log(Math.PI.toPrecision(4)); // 3.142 // number.toString(radix), this method converts the number into a character, and radix represents the base of the system console.log(Math.PI.toString()); // 3.141592653589793 console.log(Math.PI.toString(2)); // 11.001001000011111101101010100010001000010110100011 console.log(Math.PI.toString(8)); // 3.1103755242102643 console.log(Math.PI.toString(16)); // 3.243f6a8885a3
4,Object
// object.hasOwnProperty(name), this method is used to check whether an object contains a certain property or method, // This method does not detect properties and methods in the prototype chain var obj1 = {member: true}; var obj2 = Object.create(obj1); console.log(obj1.hasOwnProperty('member')); // true console.log(obj2.hasOwnProperty('member')); // false console.log(obj2.member); // true
5,RegExp
- The regexp.exec(string) method is the most powerful (and slowest) method of regular expressions. If it matches successfully, it returns an array. The element with subscript 0 in the array will contain the substring matched by the regular expression regexp. The element with subscript 1 is the text captured by group 1, the element with subscript 2 is the text captured by group 2, and so on. Returns null if the match fails.
- The regexp.test(string) method is the simplest (and fastest) method in regular expressions. If the match is successful, return true, otherwise, return false. Do not use the g flag for this method.
// regexp.exec(string), match mailbox var regexpEmail = /^(\w+)@(\w+\.\w{2,4})$/; var QQEmail = '924902324@qq.com'; var gmail = 'liaolongdong@gmail.com'; console.log(regexpEmail.exec(QQEmail)); // 0: "924902324@qq.com" // 1: "924902324" // 2: "qq.com" // index: 0 // input: "liaolongdong@gmail.com" console.log(regexpEmail.exec(gmail)); // 0: "liaolongdong@gmail.com" // 1: "liaolongdong" // 2: "gmail.com" // index: 0 // input: "liaolongdong@gmail.com" // regexp.test(string) var a = /&.+;/.test('Better & Beans'); // true // Implement the test method RegExp.prototype.test = function(string){ return this.exec(string) !== null; };
6,String
Most of the methods for manipulating strings are stored in the String.prototype prototype object
// string.charAt(pos) method, returns the character at position pos in string var name = 'Better'; console.log(name.charAt(-1)); // '' console.log(name.charAt(1)); // 'e' console.log(name.charAt(8)); // '' // Implement the charAt method String.prototype.charAt = function(pos){ return this.slice(pos, pos + 1); }; // string.charCodeAt(pos) method, returns the character code of the character at position pos in string. var name = 'Better'; console.log(name.charCodeAt(-1)); // NaN console.log(name.charCodeAt(1)); // 101 console.log(name.charCodeAt(name.length)); // NaN // string.concat(string...) method, concatenating strings to construct a new string // This method is less used, because it is more convenient to use the + operator to concatenate strings var str = 'B'.concat('i', 'g'); // 'Big' // string.indexOf(searchString, position), find another string searchString in string // If found, returns the position of the first matching character, otherwise, returns -1 var name = 'Better'; console.log(name.indexOf('t')); // 2 console.log(name.indexOf('t', 3)); // 3 console.log(name.indexOf('Bet')); // 0 console.log(name.indexOf('BB')); // -1 // string.lastIndexOf(searchString, position), this method is similar to the indexOf method // This method starts searching from the end of the string instead of starting from the beginning var name = 'Better'; console.log(name.lastIndexOf('t')); // 3 console.log(name.lastIndexOf('t', 2)); // 2 console.log(name.lastIndexOf('BB')); // -1 // string.localeCompare(that), the method is used to compare two strings. console.log('a'.charCodeAt(0)); // 97 console.log('A'.charCodeAt(0)); // 65 console.log('a'.localeCompare('A')); // -1 console.log('A'.localeCompare('a')); // 1 console.log('a'.localeCompare('a')); // 0 console.log('aa'.localeCompare('a')); // 1 var m = ['AAA', 'A', 'aa', 'a', 'Aa', 'aaa']; m.sort(function(a, b){ return a.localeCompare(b); }); console.log(m); // ["a", "A", "aa", "Aa", "aaa", "AAA"] // string.match(regexp), without the g identifier, has the same result as using regexp.exec(string) // If the regexp has the g identifier, then it returns an array containing all matches except captured groups var text = '<html><body class="center"><p>' + 'This is <b>bold</b>!</p></body></html>'; var tagsReg = /[^<>]+|<(\/?)([A-Za-z]+)([^<>]*)>/g; var a, i; a = text.match(tagsReg); for(i = 0, len = a.length; i < len; i ++){ console.log('[' + i + '] ' + a[i]); } // result: // [0] <html> // [1] <body class="center"> // [2] <p> // [3] This is // [4] <b> // [5] bold // [6] </b> // [7] ! // [8] </p> // [9] </body> // [10] </html> // string.replace(searchValue, replaceValue) //This method performs a find and replace operation on string and returns a new string. // searchValue can be a string or a regular expression, if it is a string, only the first match will be replaced var string = 'fall_in_love_with'; console.log(string.replace('_', '-')); // fall-in_love_with // If searchValue is a regular expression with the g identifier, it will replace all matches // If there is no g identifier, then it only replaces the first matching position. var string = 'fall_in_love_with'; console.log(string.replace(/_/g, '-')); // fall-in-love-with console.log(string.replace(/_/, '-')); // fall-in_love_with var oldareacode = /\((\d{3})\)/g; console.log('(555)666-1212'.replace(oldareacode, '$1-')); // 555-666-1212 // If replaceValue is a function, this method will be called for each match in turn, // And the string returned by the function is used as the replacement text. The first argument passed to this function is the entire text to be matched. // The second parameter is the text captured by group 1, the next parameter is the text captured by group 2, and so on String.prototype.entityify = (function(){ var character = { '<': '<', '>': '>', '&': '&', '"': '"' }; return function(){ return this.replace(/[<>&"]/g, function(c){ return character[c]; }); } }()); // The immediate execution function is used here console.log('<&>'.entityify()); // <&> // string.search(regexp), this method is similar to indexOf, //The difference is that the method can only accept a regular expression as a parameter instead of a string var strSay = 'I fell in love with you at first sight !'; console.log(strSay.search(/love/)); // 10 console.log(strSay.search(/hate/)); // -1 // string.slice(start, end), intercept the string var strSay = 'I fell in love with you at first sight !'; console.log(strSay.slice(2, 23)); // fell in love with you console.log(strSay.slice(24)); // at first sigth console.log(strSay.slice(-7)); // sigth ! // string.split(separator, limit), this method splits the string into an array of strings. // The separator parameter can be a string or a regular expression // The limit parameter is optional, which is used to limit the number of fragments to be divided var digits = '0123456789'; console.log(digits.split('')); // ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"] console.log(digits.split('', 6)); // ["0", "1", "2", "3", "4", "5"] var ip = '192.168.1.0'; var str = '|a|b|c|'; console.log(ip.split('.')); // ["192", "168", "1", "0"] console.log(str.split('|')); // ["", "a", "b", "c", ""] var text = 'first, middle , last'; console.log(text.split(/\s*,\s*/)); // ["first", "middle", "last"] // PS: the text from the grouped capture will be included in the splitted array var text = 'first, middle , last'; console.log(text.split(/\s*(,)\s*/)); // ["first", ",", "middle", ",", "last"] // string.substring(start, end), this method is the same as the slice method, except that it cannot handle negative parameters, we can usually use slice instead // string.toLocaleLowerCase() and string.toLowerCase(), convert the letters of the string to lowercase console.log('ABCabc'.toLocaleLowerCase()); // 'abcabc' console.log('ABCabc'.toLowerCase()); // 'abcabc' // string.toLocaleUpperCase() and string.toUpperCase(), convert the letters of the string to uppercase console.log('ABCabc'.toLocaleUpperCase()); // 'ABCABC' console.log('ABCabc'.toUpperCase()); // 'ABCABC' // String.fromCharCode(char...) console.log(String.fromCharCode(67, 97, 116)); // 'Cat'
JSON
JavaScript Object Notation (JSON for short) is a lightweight data exchange format. It is based on JavaScript's object literal notation.
A JSON object is an unordered collection of name/value pairs. name can be any string. Values can be any type of JSON value.
A JSON array is an ordered sequence of values. Its value can be any type of JSON value, including arrays and objects.
JSON strings should be enclosed within a pair of double quotes.
// Use the JSON.stringify() method to convert an object or array into a JSON string var obj = { name: 'Better' , age: 24, boy: true, hobbyArr: ['movie', 'computer game'], obj1: {}, func: function(){console.log(123);}, null: null, undefined: undefined, weakness: undefined }; var arrObj = [ { name: 'Better', age: 24, boy: true, hobbyArr: ['movie', 'computer game'], obj1: {}, func: function(){console.log(123);}, null: null, undefined: undefined, weakness: undefined }, { name: 'xiaoxin', age: 20, girl: true, hobbyArr: ['movie', 'computer game'], obj1: {}, func: function(){return 123;}, null: null, undefined: undefined, weakness: undefined } ]; console.log(JSON.stringify(obj)); // { // "name": "Better", // "age": 24, // "boy": true, // "hobbyArr": [ // "movie", // "computer game" // ], // "obj1": {}, // "null": null // } console.log(JSON.stringify(arrObj)); // [ // { // "name": "Better", // "age": 24, // "boy": true, // "hobbyArr": [ // "movie", // "computer game" // ], // "obj1": {}, // "null": null // }, // { // "name": "xiaoxin", // "age": 20, // "girl": true, // "hobbyArr": [ // "movie", // "computer game" // ], // "obj1": {}, // "null": null // } // ] // Conclusion: JSON ignores variables whose values are functions and undefined // Use the JSON.parse() method to convert a JSON string into a JS object or array var jsontext = '{"firstname":"Jesper","surname":"Aaberg","phone":["555-0100","555-0120"]}'; var jsonstr = '{"name": "Better","age": 24,"boy": true,"hobbyArr": ["movie","computer game"],"obj1": {},"null": null}'; console.log(JSON.parse(jsontext)); console.log(JSON.parse(jsonstr));
This article is written by mdnice Multi-platform publishing
- abc ↩