JS this指向问题

首先, 明确一点, 没有嵌套时, 函数中的this指向它的调用者.
嵌套函数, 内部的函数的this指向它的调用者=>window(不是外层函数)

var a = {
  f: function (params) {
	console.log(this);
	function fn() {
	  console.log(this);
	}
	fn();
  }
};

a.f();

{f: ƒ}
Window {window: Window, self: Window, document: document, name: '', location: Location, …}

其次, 函数既可以在当前运行环境中( this指向对象 ), 又可以在全局环境中( this指向window )

var obj = {
  foo: function () { console.log(this.bar) },
  bar: 1
};
var foo = obj.foo;
var bar = 2;

obj.foo() // 1
foo() // 2

或者

var foo = function () { console.log(this.bar) };
var bar = 2;
var obj = {
  foo: function () { console.log(this.bar) },
  bar: 1
};

obj.foo() // 1
foo() // 2

原因: JavaScript 语言之所以有this的设计,跟内存里面的数据结构有关系。

var obj = { foo: 5 };
JavaScript 引擎会先在内存里面,生成一个对象{ foo: 5 },然后把这个对象的内存地址赋值给变量obj。
也就是说,变量obj是一个地址(reference)。后面如果要读取obj.foo,引擎先从obj拿到内存地址,然后再从该地址读出原始的对象,返回它的foo属性。
原始的对象以字典结构保存,每一个属性名都对应一个属性描述对象。举例来说,上面例子的foo属性,实际上是以下面的形式保存的。

{
  foo: {
    [[value]]: 5
    [[writable]]: true
    [[enumerable]]: true
    [[configurable]]: true
  }
}

当属性的值是一个函数。
var obj = { foo: function () {} };
这时,引擎会将函数单独保存在内存中,然后再将函数的地址赋值给foo属性的value属性。

{
  foo: {
    [[value]]: 函数的地址
    ...
  }
}

由于函数是一个单独的值,所以它可以在不同的环境(上下文)执行。???

var f = function () {};
var obj = { f: f };

// 单独执行
f()

// obj 环境执行
obj.f()

1 函数形参及内部的this指向: 调用函数者

function a(){
    var user = "追梦子";
    console.log(this.user); //undefined
    console.log(this);  //Window
}
window.a();或a();//this指向window

var o = {
    user:"追梦子",
    fn:function(){
        console.log(this.user);  //追梦子
    }
}
o.fn();//this指向o

var o = {
    a:10,
    b:{
        a:12,
        fn:function(){
            console.log(this.a); //12
        }
    }
}
o.b.fn();////this指向b

2 箭头函数的this=定义时外层对象的this,因为它根本没有自己的this,导致内部的this就是外层代码块的this

var obj = {
  foo() {
    console.log(this);
  },
  bar: () => {
    console.log(this);
  }
}

obj.foo() // {foo: ƒ, bar: ƒ}
obj.bar() // window

注意: 因为是箭头函数,所以他的this是obj的this,即调用obj的=>window

3 构造函数this指向对象

function Fn(){
    this.user = "追梦子";
}
var a = new Fn();  //this指向a
console.log(a.user); //追梦子

定时器中的this,指向的是window. =>嵌套函数

setTimeout(function() {
 alert(this); // this -> window 
},500)

元素绑定事件,执行函数中的this,指向的是当前元素

  let $btn = document.getElementById('btn');
  $btn.onclick = function(){
    alert(this); // this -> $btn
  }

对象(全局)中的this

var age=18
var obj={
	age1:this.age
}
console.log(obj.age1)  //17

只有函数才形成局部作用域,上面的obj的this实际上是全局作用域window
posted @ 2022-03-08 20:28  波吉国王  阅读(28)  评论(0编辑  收藏  举报