JavaScript Knowledge extension
scope
Scope scope:
1. Definition: the scope within which variable functions or members can be accessed in the entire program;
2. Can also be used for information hiding
Block scope: {… } contains code that is a block scope, JS has no block scope;
Dynamic scope: Whether members of a function can be accessed is determined only at run time
function f(){ alert(x); } function f1(){ var x = 1; f(); } function f2(){ var x = 2; f(); } f1(); // error: x is not defined, indicating that JS has no dynamic scope f2();Copy the code
JS has only static scope lexical scope, also known as lexical scope or closure, which determines the relevant scope at the lexical creation stage. Closure: A function that references a free variable.
function f(){
var x = 100;
function g(){
...
}
g();
}
f();
Copy the code
Function f(){// when f() is created, [[scope]] == window //f.[[scope]] == window //f() creates its own lexical context f.le, f.le ->f.[[scope]] F () is just called), f() {x = undefined, g(){... }}, g.[[scope]] == f. F.le {x = 100, g(){... }} function g(){g.[[scope]] == f.le... } g(); / / g () at run time, creates own lexical environment, g.l e - > g. [[scope]] / / in conclusion formed a chain / / g.l e - > g. [[scope]] = = f.l e - > f. window} [[scope]] = = f ();Copy the code
The way that JS creates functions
There are three:
1. Function declaration
function f() {… }
2. Function expressions
var f = function () {… }
Function constructor
Var f = new Function(” parameter “, “Function body”)// Scope created this way always refers to the global, not its parent
closure
, short for lexical closure, is a function that references a free variable. The referenced free variable will exist with the function, even if it has left the environment in which it was created. So, there is another way to say that closures are entities composed of functions and their associated reference environments.
function f1() { var a = 10; var b = 20; Function f2() {// the f2() function is the closure console.log(a); } f2(); } f1();Copy the code
Benefits of closures
1. Reduce global variables
// each time the function add() is called, a increments by 1
function add(){ var a = 0; a++; alert(a); } add(); add(); // Each call to a starts at 0Copy the code
Var a = 0; function add() { a++; alert(a); } add(); add(); // But doing so increases the global variableCopy the code
Function f(){var a = 0; return function(){ a++; alert(a); } } var result = f(); result(); result();Copy the code
2. Reduce the number of arguments passed to the function
// Implement, for example, cardinality 2, maximum number 3, return value 2+ 1+2+3 value
// It can be done this way
function add(base,max){… }
Function calFactory(base){return function(Max){var total = 0; for(var i = 1, i <= max, i++ ){ total +=i; } return total + base; } } var adder = calFactory(2); adder(3); //8//2+1+2+3 adder(4); / / 12 / / 2 + 1 + 2 + 3 + 4Copy the code
3. Play the role of encapsulation
(function(){ var m = 0; Function getM(){return m; } function setM(){// m = val; } window.g = getM; // Interface window.s = setM; }) (); // Immediately called anonymous function s(12); alert(g());Copy the code
Closure considerations:
1. Captured variables are drinkable, not copied
function f(){ var num = 1; function g(){ alert(num); // reference parent num} num++; g(); / / 2}Copy the code
2. A different closure is generated each time the parent function is called
function f(){ var num = 1; return function(){ num++; alert(num); } } var result1 = f(); // A new lexical environment is created each time a function is called result1(); //2 result1(); //3 var result2 = f(); // Create a new lexical environment result2(); //2 result2(); / / 3Copy the code
3. Problems in the loop
The < body > < div id = "1" > 1 < / div > < div id = "2" > 2 < / div > < div id = "3" > 3 < / div > for (var I = 1; i <=3; I ++){var ele = document.getelementbyid (" I "); ele.onclick = function(){ alert(i); }} </body> // Click 1, 2, and 3 to pop up 4, because there is no block-level scope, so I equals the global variable // solution, Can use the closure < body > < div id = "1" > 1 < / div > < div id = "2" > 2 < / div > < div id = "3" > 3 < / div > (for (var I = 1; i <=3; I ++){var ele = document.getelementbyid (" I "); ele.onclick = (function(id){ return function(){ alert(id); } })(i); } </body> </body> </body> </body> </body>Copy the code
pseudo-classes
The _ _ proto _ _ object has nothing to do with the function and points directly to the function’s prototype
// Functions have prototype attributes. Objects have _ _ proto _ _. Functions are also objects, so functions have prototype attributes
function Person(){ var age = 30; this.age = 22; This. Name = "nice"; } Person.prototype.headCount = 1; var p = new Person(); Person() has age and name attributes inside p. P can also refer to // person.protpType via __proto__. P has nothing to do with Person(). Person. The prototype = {xx: xx "} "; // Rewrite Person's prototype completely from console.log(p.x); //undefined// now p can't fetch the new Person. Prototype console.log(p.hadcount); //1// But the Person. Prototype to which the original p.__proto__ refers still existsCopy the code
this
This always refers to an object
This can be written directly inside the global object and always refers to the window object; This can also be written inside a function, where there are three situations:
The first case:
Var ele = document. GetElementById (" id "); Ele. AddElementListener (" click ", the function {the console. The log (this); // In this case this always refers to the object that raised the event ele})Copy the code
The second case:
// This refers to a run-time decision, not a code-time decision
// This refers to whoever the runtime function is called by
Var o = {name: "nice"; print:function(){ console.log(this.name); } } o.print(); //cj// the function is called by o var ff = o.print; ff(); //undefined// this is equivalent to window.ff(), which is called by windowCopy the code
The third case:
Function f(){this.name = "nice"; }Copy the code
The second case above changes the pointing of this, and you can also change the pointing of this using call or apply or bind, which are all things that function objects have
The difference between call and apply:
Call passes arguments as a list of arguments, one by one, while Apply passes arguments as an array
Var o = {name: "nice"; print:function(){ console.log(this.name); } } var ff = o.print; ff(); / / undefined enclosing name = "global"; this.age = 22; ff(); //global function log(a,b){ console.log(this[a]); console.log(this[b]); } the log (" name ", "age"); / / global 22 the call (o, "name"); / / nice / / change this point, the equivalent of o.l og (" name ") the call (o, "name", "age"); Log. apply(o,[' name ', 'age'])//nice undefined//undefined because there is no age variable in the o object log.apply(o,[' name ', 'age'])//nice undefinedCopy the code
New Custom implementation
function Person(name, age){ this.name = name; this.age = age; } var p1 = new Person(" cj ", 22); console.log(p1.name); / / "cj" console. The log (p1) age); / / 22Copy the code
The implementation writes a new as in the previous example
Function New(f){return function(){New Person() var o = {" __proto__ ":f.prototype}; f.apply(o,arguments); return o; }} var p2 = New(Person)(" xx ",33); console.log(p2.name); / / "xx" console. The log (p2) age); //33 console.log(p2 instanceof Person); / / true Person. Prototype. Xx = "aaaa"; console.log(p2.xx); / / "aaaa"Copy the code
encapsulation
function Person (){ var age = 100; Function PM (){// Console.log (" private method "); } this.name = name; This.text = function(){console.log(" public method "); }}Copy the code
// The code above does not make sense. It should be written in the following way
function Person (){ var age = 100; function pm(){ console.log(this.name); } this.name = name; This.text = function(){console.log(" public method "); pm(); }} var p1 = new Person(" cj "); console.log(p1.text()); //public method undefined // Call PM () in window because PM () has no prefix. // Change code PM () to pm.call(this)Copy the code
// Or use object factories to handle public and private calls to each other
function Person(pname){ function pm(){ console.log(self.name); } var self = { name:pname; test:function(){ pm(); }}; return self; } var p2 = Person(" cj "); console.log(p2.test()); / / "cj"Copy the code
inheritance
Shallow copy
Var person = {name: "cj"; age:22; } var programmer = {language: "Javascript"; } function extend(p, c){ var c = c||{}; for(var prop in p){ c[prop] = p[prop]; } return c; } extend(person, programmer) {} extend(person, programmer) {} extend(person, programmer) {Copy the code
Var person = {name: "cj"; age:22; Address: {home: "home address"; Office: office "address"; }} var programmer = {language: "Javascript"; } function extend(p, c){ var c = c||{}; for(var prop in p){ c[prop] = p[prop]; } return c; } extend(person, programmer) console.log(programmer. Name);} extend(person, programmer) console.log(programmer. / / programmer. "cj" name = "nice"; console.log(person.name); // "cj" // shallow copy, variable value changes console.log(programmer. Name); / / "nice" programmer. Address. Home = "Shenzhen"; console.log(programmer.address.home); / / "Shenzhen" console. The log (person. Address. Home); // "Shenzhen" // the child changes the parent value, indicating only a shallow copy // the child and the parent reference point to the same location // array and object, can have this problem // array can also be iterated with a for in loopCopy the code
Deep copy
Inheritance of the formal implementation of an object argument
function extendDeeply(p, c){ var c =c||{}; For (var prop in p){if(typrof p[prop] === "object"){c[prop] = (p.[prop]. Constructor === Array)? [] : {}; extendDeeply(p[prop], c[prop]); }else{ c[prop] = p[prop]; }}}Copy the code
Implement inheritance in the form of constructors
Function Parent(){// Parent object this.name = "ABC"; This. The address = {home: "home"}; } function Child(){parent.call (this); // Copy this.language = "js" with call form; } c = new Child(); console.log(c.name); // "ABC" P = new Parent(); C.a. ddress. Home = "Shenzhen" console. The log (p.a ddress. Home); // "home" // Is a deep copyCopy the code
Create implementation inheritance
Var p = {name: "cj"}; / / p. __proto__ pointing to the object. The prototype, the object. The prototype. __proto__ point to null function myCreate (p) {var ins. function F(){}; F.prototype = p; ins = new F(); return ins; } var c = myCreate(p); // The system's own object.create (p); console.log(c.name); / / "cj"Copy the code
The code above has its own object.create ()
Attributes can also be enhanced, for example
var c2 = Object.create(p,{age:{value:20},salary:{value:1000000}}); //p is inherited by the parent class, and console.log(name) is enhanced by the subclass; / / "cj" console. The log (age). / / 20Copy the code
Talk about instanceof
Objects on the left, functions on the right
var f = new F(); console.log(f instanceof F); //true// if f.constructor == F console.log(F instanceof Object); __proto__== object.prototype; // if (prototype == Object) {// if (prototype == Object) {// if (prototype == Object) {// if (prototype == ObjectCopy the code
Class inheritance
// Create a parent class
// Create a subclass
// Build relationships
The first way
Function P(){} C(){} C(){} C(){} C(){} C(){} C(){} C(){} C(){ Constructor is P(), so after inheriting the class method, // restore the prototype-type constructor back to c.protoType = C; var c1 = new C(); console.log(c1 instanceof C); //true console.log(c1 instanceof P); / / true C.p rototype. Xx = "xx"; var p1 = new P(); console.log(p.xx); // "xx" // Do not use this way, because the disadvantage is that the son inherits the father, but the son also exposed to the fatherCopy the code
The second way
Function P(){} function C(){}// subclass c.protoType = new P(); var c1 = new C(); console.log(c1 instanceof C); //true console.log(c1 instanceof P); / / true C.p rototype. Xx = "xx"; var p1 = new P(); console.log(p.xx); // use undefined // advantage: the child will not be exposed to the parent // disadvantage: there is a layer in the middle of the search, and the new P is not useful, just play a bridge between the child and the parentCopy the code
The third form
Function P(){} function C(){}// function F(); F.prototype = P.prototype; var f = new F(); C.prototype = f; C. protoType = object.create (p.prototype); // The advantage is that there is only a new empty function in the middle, which does not have the disadvantages mentioned aboveCopy the code
Class inheritance tetralogy:
1 Create a parent class and add attributes and methods of the parent class
2 Creating subclasses
3 Immediate Inheritance
Inheritance is implemented above, but you should instinctively correct the constructor of a subclass’s prototype back into the subclass’s constructor
4 add the attributes of the subclass,
By reversing 3 and 4, and inheriting with an equal sign, you rewrite your subclass exactly like its parent class
/ / for
Function Person () {} / / create a superclass Person. The prototype. The headCount = 1; Person.prototype.eat = function(){// Add console.log(" eating... ); Prototype = object.create (Person. Prototype); / / to inherit a Programmer. The prototype. The constructor = Programmer; / / to amend the subclass constructor of the prototype back (instinct) a Programmer. Prototype. Language = "Javascript"; / / add a subclass properties Programmer. The prototype. The work = function () {/ / add a subclass methods console. The log (" I am writing code in "+ this. Language); } var js = new Programmer(); console.log(js.eat()); //eating... console.log(js.language); / / js. "Javascript" language = "js"; console.log(js.language); / / "JS" console. The log (JS. The work ()); //i am writing code in JSCopy the code
You can also change the existing code above (with a in the comment) to the code below
createEx(Programmer, Person); . function createEx(Child, Parent){ function F(){}; F.prototype = P.prototype; Child.prototype = new F(); Child.prototype.constructor = Child; }Copy the code
Function Person(name, age){this.name = name; This. Age = age; } Person.prototype.headCount = 1; Person.prototype.eat = function(){// Add console.log(" eating... ); } function Programmer(name, age, title){// Create subclass Person. Apply (this, arguments); Aaaa} createEx(Programmer, Person); Programmer. Prototype. Language = "Javascript"; / / add a subclass properties Programmer. The prototype. The work = function () {/ / add a subclass methods console. The log (" I am writing code in "+ this. Language); } function createEx(Child, Parent){ function F(){}; F.prototype = P.prototype; Child.prototype = new F(); Child.prototype.constructor = Child; } var person = new person (" cj ", 20); console.log(person.name); // "cj" var p = new Programmer(" nice ", 22, "coder"); console.log(p.name); // "nice" person.name = "haha" console.log(" p.name "); // "nice" // no impactCopy the code
Sometimes we’ll call something from the parent inside the child, using super or base
Function Person(name, age){this.name = name; this.age = age; } Person.prototype.headCount = 1; Person.prototype.eat = function(){// Add console.log(" eating... ); } function Programmer(name, age, title){// Create subclass Person. Apply (this, arguments); } createEx(Programmer, Person); Programmer. Prototype. Language = "Javascript"; / / add a subclass properties Programmer. The prototype. The work = function () {/ / add a subclass methods console. The log (" I am writing code in "+ this. Language); Programmer.base.eat(); } function createEx(Child, Parent){function F(){}; F.prototype = P.prototype; Child.prototype = new F(); Child.prototype.constructor = Child; Child.super = Child.base = Parent.prototype; / / * * * * new statements} var csharp = new (" cj ", 22, "the teacher"); console.log(csharp.name); / / "cj" console. The log (csharp. The work ()); //i am writing code in Javascript //eating...Copy the code
polymorphism
have
function F(){}; var f = new F(); The cash-strapped ame = "cj"; The console. The log (f.h asOwnProperty (" name ")); //true// If f.prototype. age = 22; The console. The log (f.h asOwnProperty (" age ")); //false//f Object and prototype Object are two objects that do not have console.log(object.hasownProperty (f, "name")); / / false / / don't use, because is the object level hasOwnPorperty console. The log (F.p rototype. IsPrototypeOf (f)); //true// whether... The prototype of the console. The log (Object. GetPrototypeOf (f)); //F{}//Copy the code
Method overloading
Compile-time polymorphism, typically represented by method overloading, is determined at compile time
Methods with the same name are not allowed in JS; the latter overrides the former
Arguments, the number of arguments to a function
fucntion demo(a, b){ console.log(demo.length); Console. log(arguments.length); // Number of parameters console.log(arguments.length); // The number of arguments}Copy the code
Variable length overloading
function add(){ var total = 0; for(var i = arguments.length - 1; i >= 0; I -) {total + = the arguments [I]; } return total; } console.log(add(1)); //1 console.log(add(1, 2)); / / 3Copy the code
The number of parameters is different
Function fontSize(){var ele = document.getelementbyid (" js "); if(arguments.length == 0){ return ele.style.fontSize; }else{ ele.style.fontSize = arguments[0]; } } fontSize(18); console.log(fontSize()); / / 18Copy the code
Parameter types are different
Function setting(){var ele = document.getelementbyId (" js "); If (typeof arguments[0] === "object"){for(p in arguments[0]){ele. Style [p] = arguments[0][p]; }else{ ele.style.fontSize = arguments[0]; ele.style.backgroundColor = arguments[1]; }} setting (18, "red"); / / setting ({fontSize: 28, backgroundColor: "green"});Copy the code
Methods to rewrite
Runtime polymorphism: overwrite
The following example is one of them
function demo(o){ o.run(); } var o = {run:function(){console.log(" o is running... ); }}; demo(o); //o is running... Var p = {run:function(){console.log(" p is running... ); }}; demo(p); //p is running... // According to the characteristics of the prototype chain, override the same method as the constructor on the instance, using its own methodCopy the code
var f = new F(); F.p rototype. Run = function () {coslole. Log (" FFF "); } f.run(); / / FFF f.r UN = function () {/ / rewrite the console log (" FFF "); } f.run(); F run = function(){console.log(" FFFF "); F.prototype.run(); } f.run(); //ffff //FFFCopy the code
Other situations
Function Parent(){this.run = function(){console.log(" Parent is running "); } } function Child(){ Parent.call(this); Var parentRun = this.run; This.run = function(){// Subclasses override the run method console.log(" child is running "); parentRun(); }} var c = new Child(); c.run(); //child is running //parent is runningCopy the code
Other situations
Function Parent(){} Parent. Prototype. run = function(){console.log(" Parent is running "); } Child.prototype = Object.create(Parent.prototype); // inherit child.super = Parent. Prototype; Function Child(){} child.prototype. run = function(){console.log(" Child is running "); Child.super.run(); } var c = new Child(); c.run(); //child is running //parent is runningCopy the code