什么是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 对象
网上大佬的流程图:
参考网页:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/this
https://zhuanlan.zhihu.com/p/71490991
https://segmentfault.com/a/1190000019379599