Event bubbling and event delegation & prototype and prototype chain & Inheritance

Event bubbling and capture

When the event occurs, the event will start to spread (from inside to outside or from outside to inside).

Why should it be spread? Because the event source itself (possibly) does not have the ability to process events, that is, the function (method) that processes events is not bound to the event source.

For example, when we click a button, a click event will be generated, but the button itself may not be able to handle the event. The event must be propagated from the button to the code that can handle the event (for example, we assign a function name to the onclick attribute of the button, which is to let the function handle the click event of the button)

document.getElementById("d1").onclick = function(e){ 
       console.log("d1");
}

Event delegation

Event delegation, in common terms, is to delegate the function of one element in response to an event (click, keydown...) to another element;

Generally speaking, events of one or a group of elements will be delegated to its parent or outermost element. The outer element is the one that really binds events. When an event responds to the element that needs to be bound, it will trigger the binding event of its outer element through the event bubble mechanism, and then execute functions on the outer element.

For example, if students in a dormitory arrive at the same time by express delivery, one way is for them to pick it up one by one. Another way is to entrust the matter to the head of the dormitory, let one person go out to pick up all the express deliveries, and then distribute them to each dormitory student one by one according to the recipients;

Here, picking up express delivery is an event. Each student refers to the DOM element that needs to respond to the event, and the dormitory head who goes out to collect express delivery is the agent element. Therefore, it is this element that really binds the event. The process of distributing express delivery according to the recipient is in the event execution. It is necessary to judge which or which of the proxied elements the current response event should match.

Examples:

1. Go to collect one by one foolishly

var list = document.getElementById("list");
     var li = list.getElementsByTagName("li");
     for(var i=0; i<li.length; i++) {
       li[i].onclick = function(){  
         this.style.color = 'red';
       }
     }

2. Delegate to bind the event to the parent node, click the child node to bubble to the parent through the event and process

var list = document.getElementById("list");
     list.onclick = function(e){
       if (e.target.nodeName === 'LI') {
         e.target.style.color = 'red';
       }
     }

Similarities and differences between functional programming and object oriented programming

Functional programming

window.onload = function(){
   var testA = document.querySelector(".testA");
   testA.onmousemove = function(){   
       //Move in processing
   };
   testA.onmouseout= function(){
 //Removal processing
   };
}

Object oriented programming

var web = {
 bind:function(){
       this.testA = document.querySelector(".testA");
       this.testA.onmousemove = function(){   
           //Move in processing
       };
       this.testA.onmouseout= function(){
           //Removal processing
       };
   }
}
window.onload = function(){
   web.bind();
}

Prototype

definition

The prototype instance is used to point to the class that created the object, and to share the prototype's properties and methods with the class that created the new object.

A prototype is an object through which other objects can implement property inheritance

There are two types of JS objects:

Common object and function object

prototype is an attribute of a function

__ proto__ Is a property that every object has

Difference between ordinary object and function object

All objects created by new Function are function objects, and others are ordinary objects (usually created by Object). You can judge by typeof.

function f1(){};
typeof f1 //"function"
var o1 = new f1(); //Function instance
typeof o1 //"object"
var o2 = {};
typeof o2 //"object"

1. Each function object has a prototype attribute, but ordinary objects do not; There is also a constructor under the prototype, which points to this function.

2. Each object has a name__ proto__ Refers to the prototype object of its corresponding constructor. The prototype chain is based on__ proto__;

Prototype writing

function Person(){}; //Define a function object
Person.prototype.name="fangfang"; //Add attribute to prototype object
Person.prototype.phone = "18040505058";
var p1 = new Person(); //instantiation 
var p2 = new Person();

Exploded view of prototype

Why use prototype in function? Why inherit

Requirement: generate multiple instances

var cat1 = {};//Create an empty object
cat1.name="Daming";
cat1.color ="yellow";
var cat2 = {};//Create an empty object
cat2.name="Xiao Ming";
cat2.color ="white";
//Disadvantages: if there are dozens of instances, it is troublesome to write, and the instances are not associated with the prototype

Encapsulate a function

function cat(name,color){   
   return {
       name:name,
       color:color
 }
};
var cat1 = cat("Daming","yellow"); 
var cat2 = cat("Xiao Ming","white");

Constructor

function Cat(name,color){   //Constructor
 this.name = name;
 this.color = color;
};
var cat1 = new Cat("Daming","yellow");
var cat2 = new Cat("Xiao Ming","white");

If the eat() method and type attribute are added to the current cat function

function Cat(name,color){  
 this.name = name;
 this.color = color;
 this.type='animal';
 this.eat = function(){console.log("Eat mice")};
};

There is a problem of wasting memory, that is, for each instance object, the type attribute and the eat() method have the same content, which is neither environmentally friendly nor efficient

Solution:

function Cat(name,color){   //Constructor
 this.name = name;
 this.color = color;
 //this.type = 'animal';
 //this.eat = function(){console.log("eat mice")};
};
Cat.prototype.type='animal';
Cat.prototype.eat = function(){console.log("Eat mice")};

verification

console.log('name' in p1); //in returns true regardless of its own or prototype
console.log('type' in p1);
console.log(p1.hasOwnProperty('name')); //hasOwnProperty() returns true and the prototype returns
false
console.log(p1.hasOwnProperty('type'));

Understand the difference between constructor and prototype object

function Person(){};  
Person.prototype.name="fangfang";  
Person.prototype.age = 18;     
var p1 = new Person();  
var p2 = new Person();

A constructor is a template for generating objects. A constructor can generate multiple objects, and each object has the same structure. Person is the constructor, and Person.prototype is the prototype object of the constructor.

The properties and methods of the constructor itself cannot be shared, while the properties and methods of the prototype object can be shared by all instance objects.

Prototype chain

function F1(){
 this.name1 = 'f1'
};
F1.prototype.name = 'object';
function F2(){
 this.name2= 'f2'
};
function F3(){
 this.name3 = 'f3'
};
F2.prototype = new F1(); //The prototype of f2 is f1
F3.prototype = new F2(); //The prototype of f3 is f2
var f = new F3();   //Instantiation processing
f.name1;
f.__proto__.__proto__.__proto__.name= '12414';
//modify
//f.__proto__.__proto__.__proto__.name= '12414';
//delete
delete f.__proto__.__proto__.__proto__.name;

In depth understanding of prototype chain

   Understanding of prototype chain
   function Animal(){
       this.type = "animal"
   };
   Animal.prototype.eat = function(){console.log('eat')}; 
   function Cat(name,color){
       this.name = name;
       this.color = color;
   };
   Cat.prototype = new Animal();   
   var c1 = new Cat('tom','white');
   var c2 = new Cat('ben','black');

See the illustration

 

Inherit

Several common methods of inheritance

1. Prototype inheritance

function Animal(){
 this.type = "animal"
};
function Cat(name,color){
 this.name = name;
 this.color = color;
};
Cat.prototype = new Animal();
var c1 = new Cat('x','white');
var c2 = new Cat('t','Decor');
c1.type
// Advantages: the same prototype object
// Disadvantages: prototype objects cannot be modified, which will affect all instances
function Animal(){   //Animal object   
 this.type = 'animal'
};
function Cat(name,color){   //Cat object  
 this.name = name;
 this.color = color;
 this.type='I'm a cat';
};
Cat.prototype = new Animal(); //The prototype object of the cat points to the animal function
var cat1 = new Cat("Daming","yellow");
var cat2 = new Cat("Daming","yellow");
console.log(cat1.type); //Gets the property in the current constructor
console.log(cat2.type); //Gets the property in the current constructor
//Want to get the value of Animal member
console.log(cat1.__proto__.type);
console.log(cat2.__proto__.type);
//When we access the properties of a prototype object__ proto__ It is obtained level by level. When the inheritance relationship is complex and the inheritance is unknown

Inheritance of constructor

function Animal(){  
   this.type = "animal"
};
function Cat(name,color){       
   Animal.apply(this);   //Place members of the Animal object on the Cat object
   this.name = name;
   this.color = color;
};
var cat1 = new Cat("Daming","yellow"); 
var cat2 = new Cat("Xiao Ming","white");
cat1.type = 'I'm a yellow cat';
cat2.__proto__.type = 'I am an animal';
console.log(cat1.type); //'I'm yellow cat' cat1 was modified
console.log(cat2.type); //"Animals"
// Advantages: there are no instances affected by modifying the prototype object, and each has its own independent attributes
// Disadvantages: members of the parent class will be created multiple times, redundant and not the same prototype object
// Only members can be copied through apply/call, and prototype objects will not be copied

Combination inheritance

 

 function Animal(){   
 this.type = 'animal'
 };
Animal.prototype.eat = function(){console.log('eat')};  
function Cat(name,color){  
 this.name = name;
 this.color = color;
 Animal.call(this); 
};
Cat.prototype = new Animal();  
var cat1 = new Cat("Daming","yellow");
var cat2 = new Cat("Xiao Ming","white");
cat1.type = 'I'm a yellow cat'; //Modify the properties in the current constructor
cat2.__proto__.type = 'I am an animal';//The value of the prototype object is modified, but it does not affect the values of CAT1 and cat2
console.log(cat1.type); //'I am a yellow cat' / / the value of the prototype object changes without affecting the constructor value
console.log(cat2.type); //'animals'
console.log(cat2.__proto__.type); //'I'm an animal
cat1.eat(); //You can also call the eat() method in the prototype object

 

Tags: Javascript Front-end

Posted by Denness on Sun, 04 Sep 2022 22:40:34 +0530