Affichage des articles dont le libellé est this. Afficher tous les articles
Affichage des articles dont le libellé est this. Afficher tous les articles

this ?

 Voici un article sur this?

filter : thisarg

 

  1. function majeur( {born, sex} ) {

  2.   return (born < this.born  && sex == this.sex) }


  3. let f = {

  4.   sex : "f",

  5.   born : 2002,

  6. }


  7. let h = {

  8.   sex : "h",

  9.   born : 2000,

  10. }


  11. let hommesMajeur = tabPers.filter(majeur,h),

  12.      femmesMajeur = tabPers.filter(majeur,f);




code


this et la fonction flechée

function normalise(){
let normaliseT = this.valeurs.map(function(v){
return v / this.nb;
});
console.log(`valeurs normalisées ${normaliseT}`);
}


const obj = {valeurs:[3,6,12], nb:3};
normalise.call(obj);

Solution à ce problème classique :

function normalise(){
    let normaliseT = this.valeurs.map(function(v){
        return v / this.nb;
    }.bind(this));
    console.log(`valeurs normalisées ${normaliseT}`);
}

const obj = {valeurs:[3,6,12], nb:3};
normalise.call(obj);


Avec une fonction fléchée : 


function normalise(){
    let normaliseT = this.valeurs.map(v => v / this.nb);
    console.log(`valeurs normalisées ${normaliseT}`);
}

const obj = {valeurs:[3,6,12], nb:3};
normalise.call(obj);


En action

Class en action


HTML : 

<article class="td">
   <section> ...</section>
   <section> ... </section>
</article>


CSS



.hide {
   overflow : hidden;
   opacity:0;
   max-height : 0px;
   transition:all 2s ease;
   padding : 10px;
}

article>section+section {
   max-height : 300px;
   overflow : hidden;
   opacity:1;
   background-color : black;
   color : white;
   padding : 10px;
   transition:all 2s ease;
}

JS

class tdHandler {

     constructor(el) { // el = article
          this.el= el;
     }

    init() {
      this.el.addEventListener("click", () => this.action(), false);
      return this;
     }
    
    action( ) {
       this.el.lastElementChild.classList.toggle('hide');
       return this;
    } 
};

Array.from(document.querySelectorAll('.td'), (el) =>{
  let h = new tdHandler(el).init().action();
});

test fonction fléchée (pas de fonction flechée dans class)

En action


Nous allons étudier différents codes ! Coller les différentes version de js




HTML

<img src="http://www.exisoftware.com/thumbnail_generator/sample-galleries/basic-web-photo-gallery/thumbs/tn_IMG_0001.jpg" data-larger="http://www.exisoftware.com/thumbnail_generator/sample-galleries/basic-web-photo-gallery/images/IMG_0001.JPG"

alt="jolie" />


CSS


body, html
{
width: 100%; height: 100%;
  overflow : hidden;
}

img{
   padding: 10px;
   width : 100px;
}

.overlay{
    opacity : 0.8;
    color : red;
    position: fixed;
    width: 100%;
    height: 100%;
    top: 0;
    bottom: 0px;
    left: 0px;
    right: 0px;
    padding: 0 8px;
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
    background-color: #000;
    overflow: hidden;

}
.overlayimg
{
    width: 60%;
    margin: auto;
    text-align: center;
    position: fixed;
    z-index: 3;
    top: 0;
    bottom: 0px;
    left: 0px;
    right: 0px;
    padding: 0px 10px 10px;

}

JS

class imgHandler {

     constructor(el) { // like array img
          this.el= el;
     }

     init = () => {
          for(let img of this.el) {
             img.addEventListener('click',() => this._action(img));
          }
     }

     _action = (photo) => {

            let overlay = document.createElement("div");
            overlay.setAttribute("id","overlay");
            overlay.classList.add("overlay");

            document.body.appendChild(overlay);

            let img = document.createElement("img");

            img.setAttribute("id","img");
 // el
             img.src = photo.dataset.larger;

             img.classList.add("overlayimg");

             img.addEventListener('click',this._restore);
             document.body.appendChild(img);
  
           

    }

    _restore = () => {
         console.log("stop");
         document.body.removeChild(document.getElementById("overlay"));
         document.body.removeChild(document.getElementById("img"));
    }

};


var imgs = new imgHandler(document.querySelectorAll('img'));

imgs.init();


version ES6


class imgHandler {



     constructor(el) { // array like

          this.el= el;

     }

    init = () => {

      Array.from(this.el, (img) => img.addEventListener('click',() => this._action(img))); //es6 array like
      
     }
    
    _action = (el) => {

            let overlay = document.createElement("div");
            overlay.setAttribute("id","overlay");
            overlay.classList.add("overlay");
  
            document.body.appendChild(overlay);
  
            let img = document.createElement("img");

            img.setAttribute("id","img");
  
         // console.log(el)
             img.src = el.dataset.larger;
  
             img.classList.add("overlayimg");

             img.addEventListener('click',this._restore(img));
             document.body.appendChild(img);

         
           
    }

    _restore = (photo) => {
      return function(){
         console.log("stop");
         document.body.removeChild(document.getElementById("overlay"));
         document.body.removeChild(document.getElementById("img"));
      }
    }

};


var imgs = new imgHandler(document.querySelectorAll('img'));

imgs.init();


version : For of

class imgHandler {

     constructor(el) { // like array img
          this.el= el;
     }

     init = () => {
          let self = this; // this=self=objet imgHandler
          for(let img of this.el) {
                img.addEventListener('click', () => {
                    console.log(self === this); // oui
                    self._action(img);
                })
          }
     }
 
     _action = (el) => {
     
           let overlay = document.createElement("div");
            overlay.setAttribute("id","overlay");
            overlay.classList.add("overlay");

            document.body.appendChild(overlay);

            let img = document.createElement("img");

            img.setAttribute("id","img");
 // el
             img.src = el.dataset.larger;

             img.classList.add("overlayimg");

             img.addEventListener('click',this._restore);
             document.body.appendChild(img);

    }

    _restore = () => {
         console.log("stop");
         document.body.removeChild(document.getElementById("overlay"));
         document.body.removeChild(document.getElementById("img"));
    }

};


var imgs = new imgHandler(document.querySelectorAll('img'));

imgs.init();


Autre version :



class imgHandler {



     constructor(el) { // array like

          this.el= el;

     }



    init = () => {


      Array.from(this.el, (img) => img.addEventListener('click',this._action(img))); //es6 array like
      
     }
    
    _action = (el) => {
            self = this;
            return function(){
                let overlay = document.createElement("div");
            overlay.setAttribute("id","overlay");
            overlay.classList.add("overlay");
  
            document.body.appendChild(overlay);
  
            let img = document.createElement("img");

            img.setAttribute("id","img");
  
         // console.log(el)
             img.src = el.dataset.larger;
  
             img.classList.add("overlayimg");

             img.addEventListener('click',self._restore(img));
             document.body.appendChild(img);

            }
         
           
    }

    _restore = (photo) => {
      return function(){
         console.log("stop");
         document.body.removeChild(document.getElementById("overlay"));
         document.body.removeChild(document.getElementById("img"));
      }
    }

};


var imgs = new imgHandler(document.querySelectorAll('img'));

imgs.init();

Autre version

class imgHandler {

     constructor(el) { // pas de fx arrow
          this.el= el;
     }

    init = () => {
          let self = this;
          for(let img of this.el) {
                img.addEventListener('click', function(){
                    console.log(self === this); //false
                    self._action(img);
                    //self._action(this);
//self = Object imghandler et this = img courante
                })
          }
     }
    
    _action = (el) => {
           console.log("click");
           let overlay = document.createElement("div");
            overlay.setAttribute("id","overlay");
            overlay.classList.add("overlay");
  
            document.body.appendChild(overlay);
  
            let img = document.createElement("img");

            img.setAttribute("id","img");
  
         // console.log(el)
             img.src = el.dataset.larger;
  
             img.classList.add("overlayimg");

             img.addEventListener('click',this._restore(img));
             document.body.appendChild(img);

    }

    _restore = (photo) => {
      return function(){
         console.log("stop");
         document.body.removeChild(document.getElementById("overlay"));
         document.body.removeChild(document.getElementById("img"));
      }
    }

};


var imgs = new imgHandler(document.querySelectorAll('img'));

imgs.init();


autre version : closure

class imgHandler {

     constructor(el) { // pas de fx arrow
          this.el= el;
     }

    init = () => {

      for(let i=0; i<this.el.length ; i++) {
       this.el[i].addEventListener('click',this._action(this.el[i]))
      }

      
     }
    
    _action = (el) => {
       let self = this;
       return function(){
       
           console.log( this); // img
           console.log(self); // imgHandler

           let overlay = document.createElement("div");
            overlay.setAttribute("id","overlay");
            overlay.classList.add("overlay");
  
            document.body.appendChild(overlay);
  
            let img = document.createElement("img");

            img.setAttribute("id","img");
  
         // console.log(el)
             img.src = el.dataset.larger;
  
             img.classList.add("overlayimg");

             img.addEventListener('click',self._restore(img));
             document.body.appendChild(img);

       }
           
    }

    _restore = (photo) => {
      return function(){
         console.log("stop");
         document.body.removeChild(document.getElementById("overlay"));
         document.body.removeChild(document.getElementById("img"));
      }
    }

};


var imgs = new imgHandler(document.querySelectorAll('img'));

imgs.init();


version ! 


class imgHandler {

     constructor(el) { // pas de fx arrow
          this.el= el;
     }

    init = () => {

      for(let i=0; i<this.el.length ; i++) {
       this.el[i].addEventListener('click',this._action())
      }

   
     }
 
    _action = () => {
   
       let self = this;
   
       return function(){
         
           console.log(this); // img
           console.log(self); // imgHandler
       
           let overlay = document.createElement("div");
            overlay.setAttribute("id","overlay");
            overlay.classList.add("overlay");

            document.body.appendChild(overlay);

            let img = document.createElement("img");

            img.setAttribute("id","img");

         // console.log(this)
             img.src = this.dataset.larger;

             img.classList.add("overlayimg");

             img.addEventListener('click',self._restore(img));
             document.body.appendChild(img);

       }
         
    }

    _restore = (photo) => {
      return function(){
         console.log("stop");
         document.body.removeChild(document.getElementById("overlay"));
         document.body.removeChild(document.getElementById("img"));
      }
    }

};


var imgs = new imgHandler(document.querySelectorAll('img'));

imgs.init();



Création d'un objet

class elHandler {

     constructor(el) { // pas de fx arrow
          this.el= el;
          
          this.init();
     }

    init = () => {
      this.el.addEventListener("click",
                event => this._action(event.type,this.el), false);
      return this;
     }
    
    _action = (type,el) => {
       console.log(` Handling + ${type} for ${el.id} `);
       el.classList.toggle("red");
       return this;
    }

};


let objDiv = new elHandler(document.getElementById("para1"));




Remarque :

Examiner le code pour

class elHandler { constructor(el) { // pas de fx arrow this.el= el; this.init(); } init(){ this.el.addEventListener("click", event => this._action(event.type,this.el), false); return this; } _action = (type,el) => { console.log(` Handling + ${type} for ${el.id} `); el.classList.toggle("red"); return this; } }; var objDiv = new elHandler(document.getElementById("para1")); Et finalement

class elHandler { constructor(el) { // pas de fx arrow this.el = el; this.init(); } init() { this.el.addEventListener("click", function(event) { document.body.insertAdjacentHTML('beforeend', `<div id="two">this.ed = ${this.el}</div>`); this._action(event.type, this.el) }, false); return this; } _action = (type, el) => { el.classList.toggle("red"); return this; } };

Plus de perte du this au passage d'argument : fonction flèchées

Lire article

En Javascript, quand on passe une méthode en argument, on perd le contexte. 


  1. class Person{
  2.   constructor(age){
  3.     this.age = age;
  4.   }

  5.   birthday(){
  6.     this.age++;
  7.   }
  8. }

  9. let denis = new Person(50);
  10. console.log(denis.age);

  11. // passage fonction en argument 

  12. let test = (methode) =>  methode();

  13. test(denis.birthday.bind(denis));

Adieu perte du this : fonction fléchée

Voici un exemple montrant la perte de la référence du this dans les objets.

function P() {

  this.age = 0;

  setInterval(function () {
    this.age++; // this ref sur global et non l'objet
  }, 1000);
}
var pPerte = new P();


En voici une version corrigée ! Les fonctions fléchées capturent la valeur this de leur contexte.

function Personne() {
  this.age = 0;

  setInterval(() => this.age++, 1000);
}

var p = new Personne();

setInterval(() => console.log(p.age), 3000);


JS Bin on jsbin.com Une autre solution fût l'utilisation de bind