• 通俗易懂------this指向


    因为JavaScript 中this 是在运行期进行绑定的,因此JavaScript 中this 关键字具备多重含义。

    具体在实际应用中,this的指向大致可以分为下面4种。

    1. 作为对象的方法调用   obj.a()
    2. 作为普通函数调用    a()
    3. 构造函数调用        var b = new a(); 
    4. function.prototype.call或function.prototype.apply调用

    作为对象的方法调用 和 作为普通函数调用

     1 window.a = 2;
     2 var obj = {
     3     a:1,
     4     getA:function(){
     5         console.log(this.a);
     6     }
     7 }
     8 obj.getA();       //输出1,作为对象的方法调用,this指向当前对象
     9 var x = obj.getA;
    10 x();   //输出2,作为普通函数调用,this全部指向window对象。 

    注意,不管x之前是obj.getA,还是其他某个对象的属性,只要最后是以x(),fun()这种方式调用的,均视为普通函数调用,此时this指向window对象

    但是,在ECMAScript5的strict模式下,作为函数调用的 this被规定不会指向全局对象

     1 window.a = 2;
     2 var obj = {
     3     a:1,
     4     getA:function(){
     5         "use strict"
     6         console.log(this.a);
     7     }
     8 }
     9 var x = obj.getA;
    10 x();   //underfined

    作为构造函数调用

    通常情况下,构造函数里的this指向返回的这个对象,但是如果构造器显示地返回了一个object类型的对象,则this指向这个返回的object对象
     1 var Myclass = function(){
     2     this.name = 'beidan';
     3 }
     4 var obj = new Myclass();  
     5 console.log(obj.name);//beidan
     6  
     7 var Myclass = function(){
     8     this.name = 'beidan';
     9     return{         //显示的返回一个对象,注意!既要是显示,即有return,也要是对象{}
    10         name:'test'
    11     }
    12 }
    13 var obj = new Myclass();
    14 console.log(obj.name);//test

    作为function.prototype.call或function.prototype.apply调用

    • 理解call,apply

    call,apply都是为了改变函数体内部 this 的指向。例如,fun1.call()或者fun1.apply() 都是为了改变fun1函数内部的this指向。

    二者的作用完全一样,只是接受参数的方式不太一样。

    func1.call(this, arg1, arg2);        //参数列表arg1,arg2
    func1.apply(this, [arg1, arg2]);   //参数数组 [arg1,arg2]
     
    第一个参数指定那个了函数体内this对象的指向,他可以任何一个 JavaScript 对象(JavaScript 中一切皆对象),如果为null,则函数体内的this会指向默认的宿主对象,在浏览器中则是window。
     
    第二个参数,call 需要把参数按顺序传递进去,而 apply 则是把参数放在数组里。
    当你的参数不确定数量时用 apply ,然后把参数 push 进数组传递进去。或者也可以通过 arguments来获取所有的参数。这样看来,apply的使用率更高。
     
    • call,apply的用途
    1.修正this的指向
    比如,在实际开发中,会出现以下这种问题
    1 document.getElementById('div1').onclick = function(){
    2     console.log(this.id);   //div1
    3     var func = function(){
    4         console.log(this.id);    
    5     }
    6     func();   //通过普通函数调用,this指向window,输出undefined
    7 }
    这时我们可以用call来修正func 函数内this的指向。
    1 document.getElementById('div1').onclick = function(){
    2     console.log(this.id);   //div1
    3     var func = function(){
    4         console.log(this.id);
    5     }
    6     func.call(this);   //使用call,使func函数内部的this指向当前的函数对象,输出div1
    7 }

    2.模拟继承(借用其他对象的方法)

    • 例子一:其他对象(banana)借用apple中的say方法
    1 function fruits() {}
    2 fruits.prototype = {
    3     color: "red",
    4     say: function() {
    5         console.log("My color is "+ this.color);
    6     }
    7 }
    8 var apple = new fruits;
    9 apple.say();    //My color is red
    但是,如果我们还有其它 2个对象 banana= {color : "yellow"} ,orange = {color:‘orange’},想使用say方法,但是又不想对它们重新定义say方法。
    那么,我们可以用apply或者call 借用 fruit里面的say方法
    1 banana = {
    2     color: "yellow"
    3 };
    4 orange = {color:‘orange’};
    5 apple.say.call(banana);     //My color is yellow
    6 apple.say.apply(orange );    //My color is orange
    也就是说,当一个 object 没有某个方法(本例子中banana没有say方法),但是其他的有(本例子中apple有say方法),我们可以借助call或apply用其它对象的方法来操作。
    再看几个例子巩固记忆
    • 例子二:获取数组中的最大值和最小值
    1 var numbers = [5, 458 , 120 , -215 ];
    2 var maxInNumbers = Math.max.apply(Math, numbers),   //458
    3     maxNumbers = Math.max.call(Math,5, 458 , 120 , -215, 666); //666
    number 本身没有 max 方法,但是 Math 有,我们就可以借助 call 或者 apply 使用其方法。

    以上就是this在JavaScript中不同情况下的指向。

    如果这篇文章对你有帮助,就给我一点赞赏吧~~~

  • 相关阅读:
    http-proxy-middleware与express.json()的bug
    20+前端常用的vscode插件(总结推荐)
    图解翻转单向链表,超详细(python语言实现)
    pytest + allure2.x 踩坑-报告无数据
    Pycharm+pytest+allure打造高逼格的测试报告
    Appium Appium Python API 中文版
    appium模拟键盘事件
    AppiumDesktop控制手机和安卓模拟器
    Appium环境搭建超详细教程
    Fiddler抓包工具总结
  • 原文地址:https://www.cnblogs.com/beidan/p/5371275.html
Copyright © 2020-2023  润新知