Analyser JavaScript - mot-clé this

Cet article a participé à l'événement "Newcomer Creation Ceremony" pour commencer la route vers la création d'or.

En javascript, le mot clé this a attiré beaucoup d'attention et a un statut élevé. En tant que protagoniste d'aujourd'hui - ceci, cet article analysera cela en profondeur à partir de (1) les règles contraignantes de ceci ; (2) le pointage de ceci ; (3) changer le pointage de ceci. Si les débutants ne comprennent pas pour l'instant, autant venir au Japon pour longtemps, et écrire soi-même un article peut-être plus approfondi~.

Des astuces

  • c'est un mot-clé qui donne accès à l'environnement d'exécution pendant l'exécution de la fonction.
  • this est un objet, un objet interne généré lors de l'exécution d'une fonction, le pointage de this n'est lié qu'à l'environnement d'exécution de la fonction, pas à l'environnement de déclaration de la fonction.
  • ceci est une variable de pointeur, il n'y a pas de concept de pointeur en JavaScript, mais cela pointe en fait vers l'objet appelant actuel.
  • c'est dynamique, pointant dynamiquement vers l'environnement d'exécution de la fonction actuelle. Lors de l'appel de la même fonction dans différents environnements, le pointage de this peut également changer.

1. Les règles contraignantes de ce

1. Liaison par défaut

--Appel de fonction indépendant

-Où est la portée lexicale où cela est valide, où est cette limite

- En mode strict, l'objet global dans l'environnement du navigateur est Global Window, dans l'environnement Node.js, la portée globale ne peut pas être liée par défaut, donc cela ne peut être lié que undefinedsur

  // 默认绑定

   function A(){
     console.log(this.a);
   }
   var a=2;
   A();//浏览器:2;node:undefined
复制代码
2. Liaison implicite

- Lorsqu'il 函数引用existe un objet de contexte (non appelant !), les règles de liaison implicite le lient dans l'appel de fonction à cet objet de contexte.

function foo(){
    console.log(this.a);
  }

  var obj={
    a:2,
    foo:foo//函数引用
  }

  console.log(obj.foo());//2 obj就是这个上下文对象
复制代码
3. Perte implicite

- Lorsque la fonction liée implicitement perd l'objet lié, la liaison par défaut est référencée

- La chaîne de référence de propriété d'objet 只有上一层或者说最后一层fonctionne dans l'emplacement de l'appel

 function foo(){
    console.log(this.a);
  }

  var obj={
    a:2,
    foo:foo //隐式绑定的函数
  }

  var obj1={
    a:4,
    obj:obj
  }

  // console.log(obj.foo());//2 显示绑定
  obj1.obj.foo();//2  绑定对象是obj,而不是obj1
复制代码
4. Liaison explicite

--call(thisArg, [argsArray])

--apply(thisArg,arguments)

--Vous bind(thisArg,arguments)pouvez forcer ce point de la fonction à changer

  obj1.obj.foo();//2

  function Fn(){
    console.log(this.a);
  }

  var o1={
   a:2
  }

  Fn.call(o1);//2 call()
  Fn.apply(o1);//2 apply()
  var bar=Fn.bind(o1)//2 bind()
  bar();
复制代码

Deuxièmement, la direction de ce

1, l'appel ordinaire de la fonction

- Lorsqu'une fonction 直接调用, cela pointe vers l'objet qui l'a appelée, généralement en utilisant la liaison par défaut

function A(){
    let a="function name"
    console.log(this.a);
}

var a="window name";
A();//调用A(),当前运行环境是window,this指向window对象
//浏览器:window name;node端:undefined
复制代码
2. Constructeur

- le this du constructeur pointe toujours vers实例化对象

-严格模式下,如果构造函数不加new调用, this 指向的是undefined 如果给他赋值,则会报错.

var Func=function(){
    this.a="我是构造函数的属性";
    this.fun=function(){
        console.log(this);
    }
}
let myFunc=new Func();
myFunc.fun();//Func { a: '我是构造函数的属性', fun: [Function (anonymous)] }
复制代码

-通过构造函数的内部原理,可以将以上代码通过以下三个步骤理解并更写为:

1、在函数体内部最前面隐式的创建一个this={}

2、执行函数中的代码(往this身上挂载属性)

3、隐式的返回这个this(构造函数中只有显式的return 引用类型,才会干扰隐式return值)

var Func=function(){
    // this.a="我是构造函数的属性";
    // this.fun=function(){
    //     console.log(this);
    // }
    let this={
        a:"我是构造函数的属性",
        fun:function(){
            console.log(this);
        }
    }
    return this;
}
let myFunc=new Func();
myFunc.fun();//Func { a: '我是构造函数的属性', fun: [Function (anonymous)] }
复制代码
3、箭头函数

-箭头函数不会创建自己的this,所以它没有自己的this,它只会从自己的作用域链的上一层继承this

-如果外部函数是普通函数,this的指向取决于外部函数的绑定类型,外部函数!=定义箭头函数的外部对象

function foo(){
    var a="function"
    setInterval(()=>{
        console.log(this.a);
    },1000)
}
var a="window"
foo();//箭头函数外部函数是foo;foo没有任何绑定,则使用默认绑定
//浏览器每个1秒打印window;node.js每隔一秒打印undefined
复制代码

三、改变this的指向

1、使用 ES6 的箭头函数

-箭头函数的 this 始终指向函数定义时的 this,而非执行时.

-箭头函数中没有 this 绑定,必须通过查找作用域链来决定其值,如果箭头函数被非箭头函数包含,则 this 绑定的是最近一层非箭头函数的 this;否则,this 为 undefined.

var name = "window";
var obj = {
    name : "object",
    func1: function () {
        console.log(this.name)     
    },
    func2: function () {
        setTimeout( () => {
            this.func1()
        },1000);
        // setTimeout(function(){
        //     this.func1()
        // },1000);//定时器里面的回调函数如果不是箭头函数,将会报错
    }
};
obj.func2() //object
复制代码
2、在函数内部使用 _this = this

-var _this = this可防止定时器 被 window 调用,而导致的在 定时器 中的 this 为 window

-定时器会干扰this指向

var name = "window";
var obj = {
    name : "object",
    func1: function () {
        console.log(this.name)     
    },
    func2: function () {
        var _this = this;//这里的 this 是调用 func2 的对象 obj
        setTimeout( () => {
            _this.func1()
        },1000);
    }
};
obj.func2() //object
复制代码
3、使用 apply()、call()、bind()

注意:这三种方法使用的区别,apply()和call()区别在于,两个参数时,后者参数用数组封装;bind()与前两者的区别在于,bind()必须有返回值

bind()方法创建一个新的函数, 当被调用时,将其this关键字设置为提供的值,在调用新函数时,在任何提供之前提供一个给定的参数序列。需要手动调用

var person = {
    fullName: function() {
        return this.name;
    }
}
var person1 = {
    name:"ducky"
}
var person2 = {
    name:"lucky"
}
console.log(person.fullName.call(person1));// ducky
console.log(person.fullName.apply(person2));// ducky
//注意bind()的绑定方式,与call()和apply()不同
var person3=person.bind(person1);
person3();//ducky

复制代码
4、new 实例化一个对象

构造函数的this永远指向通过new运算符创建的实例化对象

var Student=function(sex){
    this.sex=sex;
}
var student=new Student("girl");
console.log(student.sex);//girl
复制代码

Je suppose que tu aimes

Origine juejin.im/post/7119455352378097701
conseillé
Classement