javascript this的简单理解

什么是this

“this” 指 引用不同的执行上下文中的不同对象,在大多数的情况下,this 其值取决于函数的调用方式。
一旦你弄清楚了this指向的对象,你就可以直接将它改成对象名。 否则,使用bind,call,apply函数也可以解决由于 this 关键字很混乱问题。

情况1:全局环境&简单函数调用

var x = 1
console.log(this.x)    //1
console.log(this === window)   //true

function f1(){
    return this;
}
console.log(f1() === window);   //true

//在严格模式下,this将保持他进入执行环境时的值,所以下面的this将会默认为undefined。
function f2(){
  "use strict"; // 这里是严格模式
  return this;
}

console.log(f2() === undefined); // true

情况2:作为对象方法的调用
当函数作为对象里的方法被调用时,它们的 this 是调用该函数的对象。

var name = "David"
var prop ={
    name:"Leo",
    method:function(){
        return this.name;
    }
}
console.log(prop.method());  //   Leo

// this 的绑定只受最靠近的成员引用的影响, 
var prop = {
    name:"Leo",
    method:method,
    firstname:{
        method:method,name:"Ye"
    }
}
function method() {
  return this.name;
}
console.log(prop.method());    // Leo   函数中的this 指向 prop
console.log(prop.firstname.method());  // Ye  函数中的this指向 prop.firstname

如果要想把 this的值从一个环境传到另一个,就要用 call或者apply方法。

var obj = {a:"Leo"}
var a = "David"
function Name(arg){
    console.log(this.a);
}
Name();     // Leo
Name.call(obj);  //David
Name.apply(obj); //David

//call 和 apply 的区别在于,call 的第二个及后续参数是一个参数列表,apply 的第二个参数是数组
function add(c, d) {
  return this.a + this.b + c + d;
}
var o = {a: 1, b: 3};

// 第一个参数是作为‘this’使用的对象
add.call(o, 5, 7); // 1 + 3 + 5 + 7 = 16
add.apply(o, [10, 20]); // 1 + 3 + 10 + 20 = 34

//使用 call 和 apply 函数的时候要注意,如果传递给 this 的值不是一个对象,JavaScript 会尝试使用内部 ToObject 操作将其转换为对象

情况3:bind方法
调用f.bind(someObject)会创建一个与f具有相同函数体和作用域的函数,但是在这个新函数中,this将永久地被绑定到了bind的第一个参数,无论这个函数是如何被调用的

function f(){
  return this.a;
}

var g = f.bind({a:"azerty"});
console.log(g()); // azerty

var h = g.bind({a:'yoo'}); // bind只生效一次!
console.log(h()); // azerty

var o = {a:37, f:f, g:g, h:h};
console.log(o.f(), o.g(), o.h()); // 37, azerty, azerty

情况4:作为构造函数
当一个函数用作构造函数时(使用new关键字),它的this被绑定到正在构造的新对象。

function method(){
    this.name = "Leo";
}

var Name = new method();
console.log(Name.name);   //Leo
// 手动的设置了返回对象,与this绑定的默认对象被丢弃了
function method2(){
    this.name = "Leo";
    this.dd = "dd";
    return {name:"David"}
}

var Name2 = new method2();
console.log(Name2.name);   //David
console.log(Name2.dd);   //undefined

情况5:箭头函数
在箭头函数中,this与封闭词法环境的this保持一致。
箭头函数中使用的this,其实是直接包含它的那个函数或函数表达式中的this。

var globalObject = this;
var foo = (() => this);
console.log(globalObject);  //window
console.log(foo() === globalObject); // true
var obj = {foo: foo};
console.log(obj.foo() === globalObject); // true
console.log(foo.call(obj) === globalObject); // true

var obj = {
    bar: function() {
      var x = () => {
        console.log(this === obj);   // true
        console.log(this);           //  {bar: ƒ} 
      }
      x();
    }
  };
obj.bar();

其他情况:
作为一个DOM事件处理函数,当函数被用作件处理函数时,它的this指向触发事件的元素

function bluify(e){
  console.log(this === e.currentTarget); // 总是 true
  console.log(this === e.target);       //true  
}
// 获取文档中的所有元素的列表
var elements = document.getElementsByTagName('*');
for(var i=0 ; i

作为一个内联事件处理函数
当代码被内联on-event 处理函数调用时,它的this指向监听器所在的DOM元素:



//在下面这种情况下,没有设置内部函数的this,所以它指向 global/window 对象

网上大佬的流程图:


image.png

参考网页:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/this
https://zhuanlan.zhihu.com/p/71490991
https://segmentfault.com/a/1190000019379599

你可能感兴趣的:(javascript this的简单理解)