• this指向问题


    1.this显示绑定

     含义:当一个函数没有明确的调用对象的时候,也就是单纯作为独立函数调用的时候,将对函数的this使用默认绑定(绑定到全局window对象)

    在显示绑定下(函数将取得在“包含对象”里的永久居住权),一直都会“住在这里”

     1.1全局函数

    function fire() {
        console.log(this === window); //fire此时是全局的方法,this指向window
    }
    fire(); // 输出true

    1.2函数内嵌套函数

    function fire() {
        // 我是被定义在函数内部的函数哦!
        function innerFire() {
            console.log(this === window); //未明确调用对象,this指向window
        }
        innerFire(); // 独立函数调用
    }
    fire(); // 输出true
    innerFire();

    示例:

    var a = 1;
    console.log(this.a); //1 因为此时this指向了window,因而调用1
    function fire() {
        var a = 2;
        console.log(this.a); //1 因为此时this指向了window,因而调用1
    
        function innerFire() {
            var a = 3;
            console.log(this.a); //1 因为此时this指向了window,因而调用1
        }
        innerFire();
    }
    fire(); //输出1

    与作用域的区别: 全局作用域和局部作用域, 去掉this可发现区别

    var a = 1;
    console.log(a); //1 a在全局作用域
    function fire() {
        var a = 2;
        console.log(a); // 2 fire函数作用域
        function innerFire() {
            var a = 3;
            console.log(a); //3 此时打印输出a,a在innerFIre作用域。从自身作用域查找变量,未找到才网上查找
        }
        innerFire();
    }
    fire();

    1.3对象内层函数内部函数

    var obj = {
        fire: function () { //此时的fire函数其实用到了隐式绑定
            function innerFire() {
                console.log(this === window); //未明确调用对象,this指向window
            }
            innerFire();
        }
    }
    obj.fire(); //输出 true

    示例:

    var a = 1;
    console.log(this.a); //1 this指向全局变量window
    var obj = {
        a: 2,
        fire: function () {
            var a = 3;
            console.log(this.a); //2 因为是obj.fire(),调用了fire函数,因为this指向了obj,输出了obj下的a=2
            function innerFire() {
                var a = 4;
                console.log(this.a); //1 未明确调用对象,this指向window
            }
            innerFire(); //没有明确调用的对象
            console.log(this.a); //2 this指向obj
        }
    }
    obj.fire();

    2.this隐式绑定

    2.1隐式绑定

    当函数被一个对象“包含”的时候,我们称函数的this被隐式绑定到这个对象里面,这时候,通过this可以直接访问所绑定的对象里面的其他属性

    特别注意:在隐式绑定下函数只是暂时住在“包含对象”的旅馆里面,可能过几天就又到另一家旅馆住了

    var obj = {
        a: 1,
        fire: function () { //此时函数的this被隐式绑定到了对象obj
            console.log(this == obj); // obj中有fire函数,因而默认this指向obj
            console.log(this.a); // 1 this.a 相当于obj.a =1
        }
    }
    obj.fire(); // 输出1 

    2.2动态绑定

     this是在代码运行期绑定而不是在书写期

    var obj = {
        a: 1, // a是定义在对象obj中的属性 1
        fire: function () {
            console.log(this.a)
        }
    }
    var a = 2; // a是定义在全局环境中的变量 2
    obj.fire(); //1  此时fire的指向时obj
    var fireInGrobal = obj.fire; //因为fireInGrobal是全局变量,this对于obj的绑定丢失,绑定到了全局window
    fireInGrobal(); // 输出 2 输出全局变量啊
    var a = 2;
    var obj = {
        a: 1, // a是定义在对象obj中的属性
        fire: function () {
            console.log(this.a)
        }
    }
    
    function otherFire(fn) { //全局函数,this绑定window
        fn();
    }
    otherFire(obj.fire); // 输出2   this对于obj的绑定丢失,绑定到了全局this上面
    var obj = {
        a: 1,
        obj2: {
            a: 2,
            obj3: {
                a: 3,
                getA: function () { //obj3.getA()   this绑定到了obj3当中
                    console.log(this.a)
                }
            }
        }
    }
    obj.obj2.obj3.getA(); // 输出3

    3.this指向

    this的指向不是由定义this决定的,而是随脚本解析自动赋值的。

    3.1全局环境作用于:this在全局环境始终指向window

    变量形式

    console.log(this === window) // true
    console.log(window.alert === this.alert) // true
    console.log(this.parseInt("021", 10)) // 21
    var fruit = "banana"; // 定义一个全局变量,等同于window.fruit = "banana"

    3.2.函数环境作用域:函数有谁调用,this就指向谁

    3.3.非严格模式

    function fn() {
        console.log(this); //window
    }
    fn() === window; // true;window.fn(),此处默认省略window

    3.4.严格模式

    3.4.1.全局环境下,this指向window

    "use strict";
    this.b = "MDN";
    console.log(this == window) // "MDN"
    console.log(b) // "MDN"

    3.4.2.函数环境下,this为undefined

    function fn() {
        "use strict"; // 这里是严格模式
        console.log(this); //window
    }
    fn() === undefined //true

    3.5.对象的方法函数调用:指向该方法所属的对象

    3.5.1.隐式调用

    var obj = {
        a: 1,
        fn: function () {
            return this;
        }
    }
    console.log(obj.fn() == obj); //true  函数被obj调用,指向obj

    3.5.2.this动态绑定

    var obj = {
        a: 1,
        fn: function () {
            return this;
        }
    }
    console.log(obj.fn()); //1  函数被obj调用,指向obj,输出obj的a=1
    var a = 2;
    var newfun = obj.fn; //此时更改this指向为全局变量newfun
    newfun(); //2 ,this访问全局变量a=2

    4.在构造函数中:this始终指向新对象

     

    function Person(age, name) {
        this.age = age;
        this.name = name
        console.log(this) // 此处 this 分别指向 Person 的实例对象 p1 p2
    }
    var p1 = new Person(18, 'zs')
    var p2 = new Person(18, 'ww')

    5.通过事件绑定的方法:this指向绑定事件的对象

    oBtn.onclick = function () {
            console.log(this); // btn
        }
    
        <button id = "btn" > hh < /button>

    6.定时器函数:因为是异步操作,this指向window

    延时函数内部的回调函数的this指向全局对象window(当然我们可以通过bind方法改变其内部函数的this指向)

    我们常见的window属性和方法有alter,document,parselnt,setTimeout,setTimeout,setInterval,location等等,

    这些默认的情况下是省略window前缀的

    6.1普通定时器

    setInterval(function () {
        console.log(this); // window
    }, 1000);

    6.2定时器嵌套

    function Person() {
        this.age = 0;
        setTimeout(function () {
            console.log(this);
        }, 3000);
    }
    
    var p = new Person(); //3秒后返回 window 对象

    6.3可以改变this指向(3方法)

    function Person() {
        this.age = 0;
        setTimeout((function () {
            console.log(this);
        }).bind(this), 3000);
    }
    var p = new Person(); //3秒后返回构造函数新生成的对象 Person{...}

    7.自执行函数(匿名函数):指向全局变量window

    (function inner() {
        console.log(this); //this ==> window
    })();

    8.箭头函数

    要点;

    a.箭头函数的this是在定义函数时绑定的,不是在执行过程中绑定的

    b.箭头函数中的this始终指向父级对象

    c.所有call,apply,bind方法对于箭头函数来说只是传入参数,对它的this毫无影响

  • 相关阅读:
    有关敏捷(1)
    有关创业的想法
    2010必须做到的事
    技术搜索还是谷歌强
    错误处理的一些想法
    定期自动删除数据
    ip
    asp.ent Repeter实现分页
    QQ客服在线聊天
    几种文件上传的方法
  • 原文地址:https://www.cnblogs.com/0428mm/p/15398571.html
Copyright © 2020-2023  润新知