js中的this指向

普通函数

普通函数中的this:
1.this总是代表它的直接调用者(js的this是执行上下文), 例如 obj.func ,那么func中的this就是obj
2.在默认情况(非严格模式下,未使用 ‘use strict’),没找到直接调用者,则this指的是 window
3.在严格模式下,没有直接调用者的函数中的this是 undefined
4.使用call,apply,bind(ES5新增)绑定的,this指的是 绑定的对象

是谁调用的,this就指向谁
由运行时的执行环境来决定

var obj = {
  name : "zhar",
  say : function(){
    console.log(this.name);
  }
}
obj.say(); //zhar

//对比
//1.
var name = 'tom';
var obj = {
  name : "zhar",
  say : function(){
    console.log(this.name);
  }
}
var fun = obj.say;
fun();//输出 tom
//fun定义在全局环境下,即window.fun()
//再次说明了this的指向是由运行时的执行环境来决定的

//2.
var name = 'tom';
var obj = {
  name : "zhar",
  say : function(){
    return function(){
      console.log(this.name);
    }
  }
}
obj.say()();
// tom

构造函数环境

构造函数中的this 会指向创建出来的实例对象。
使用new 调用构造函数时,会先创建出一个空对象,然后用call函数把构造函数中的this指针修改为指向这个空对象。执行完环境后,空对象也就有了相关的属性,然后将对象返回出去。

事件对象

在 DOM 事件中使用 this,this 指向了触发事件的 DOM 元素本身

立即执行函数

立即执行函数的this指向是window(非严格模式下),因为作为一个匿名函数,在被调用的时候,我们往往就是直接调用,因此它的this是非常确定的

var tes = 2;
function a() {
    var tes  = 1;
    (function(){
        console.log(tes);
        console.log('this:', this);
    })()
}
a();
// 1
// window对象

箭头函数

没有自己的this,从自己的作用域链的上一层继承this(跟随上一层的this变而变)。
简单来说:箭头函数的this指向,通过定义箭头函数的地方向上寻找,找到第一个嵌套该箭头函数的普通函数

该普通函数在执行的过程中会形成自己的执行上下文,其中包含三个重要的属性:变量对象,作用域链,this

箭头函数的this就是继承该普通函数的this;如果一直找到全局环境,那么箭头函数的this就是指向全局对象。

由于箭头函数不绑定this, 它会捕获其所在(即定义的位置)上下文的this值, 作为自己的this值,所以箭头函数的this一经捕获就不再发生变化,
call() / apply() / bind() 方法对于箭头函数来说只是传入参数,对它的 this 毫无影响。

function Person() {
        this.name = '11'
        this.age = 23
        setTimeout(function (){
            console.log(this);  // window
            console.log(this.name + " + " + this.age);  //undefined
        }, 2000)
    }
let p = new Person();

function Person2() {
        this.name = '11'
        this.age = 23
        setTimeout(() => {
            console.log(this);   // Person2
            console.log(this.name + ' + ' + this.age) // 11 + 23
        }, 2000)
}
let p2 = new Person2();

 function Person3() {
        this.name = '11'
        this.age = 23
        var _this = this
        setTimeout(function () {
            console.log(_this);  // Person3
            console.log(this);  // window
            console.log(_this.name + " + " + _this.age);  // 11 + 23
        }, 2000)
}

let p3 = new Person3();

------------------------------------------------------------------------------------------------------------
var obj = {
        i: 10,
        b: () => console.log(this.i, this), // this捕获的是obj所在的上下文环境 此处为window
        c: function () {
            console.log(this.i, this);
        }
}
// b函数为箭头函数,定义时所在的上层执行上下文为全局环境,所以this执行window
obj.b();  // undefined window
obj.c();  // 10 {i:10,b:f,c:f}



let p = {
    a: function () {
        var i = 22;
        
        var obj = {
            i: 10,
           
            b: () => {
                console.log(this.i, this)
            },
            c: function () {
                console.log(this.i, this)
            }
        };
        obj.b();
        obj.c();
    },
    tes: 1111
}
// p.a();
/*
 p.a()执行,由于p是a的直接调用者,所以a的this指向p
 执行a的函数体,obj.b(), obj.c()

 obj.b()
 b函数为箭头函数 定义时所在的上层执行上下文为a函数,所以会继承a函数的this 
 打印 p.i 和 p对象的定义 即undefined 和 { a: [Function: a], tes: 1111 }

 obj.c()
 c函数为普通函数,所以c函数中的this指向obj,
 所以打印10 和 obj对象的定义 { i: 10, b: [Function: b], c: [Function: c] }
*/
let windowCall = p.a;
windowCall();
/*
 将windowCall指向p.a,执行windowCall,由于无直接调用者,所以a的this指向window
 执行a的函数体,obj.b(), obj.c()

 obj.b()
 b函数为箭头函数 定义时所在的上层执行上下文为a函数,所以会继承a函数的this 
 打印 window.i 和 window对象的定义

 obj.c()不变
 c函数为普通函数,所以c函数中的this指向obj,
 所以打印10 和 obj对象的定义 { i: 10, b: [Function: b], c: [Function: c] }
*/
  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值