分析每种函数调用方式的this指向
- 很显然当函数在全局环境中定义时,this将指向window对象, 在严格模式下将返回 undefined。
function GetName(){
return this
}
console.log(GetName())
- 当函数作为对象方法调用时,函数的执行环境为该对象。对象o会作为隐式的this参数传入函数
function GetName(){
return this.name
}
let o = {
name:"jack"
}
o.getname = GetName
- 当函数作为构造函数调用时,通过new关键字新建空对象,并作为上下文传入构造函数中,this将指该新建对象。
function GetName(name) {
this.name = name;
this.getname = function() {
console.log(this);
};
}
let man = new GetName("jack");
button.onclick = man.getname;
- 有些时候的this指向将由函数所在环境决定,如将对象的方法绑定到button的onclick事件,此时浏览器将this指向了button。
function GetName(name) {
this.name = name;
this.getname = function() {
console.log(this);
};
}
let man = new GetName("jack");
button.onclick = man.getname;
很显然这不是我们想要的,所以我们需要修正this指向,使用什么方式呢?
下面有请apply、call、bind登场!
apply、call是所有函数都拥有的方法,apply将接收我们想指向的this(也就是上面的man对象)以及参数数组(我们没有所以为null)并执行该函数,与apply不同call的参数由参数列表传入。
let man = new GetName("jack");
button.onclick = function{
man.getname.apply(man,null);
}
有时候我们仅仅想为某函数绑定this,不立即执行,可以使用bind绑定。
使用箭头函数绕过函数上下文
调用箭头函数时,不会隐式传入this 参数,而是从定义时的函数继承上下文!
function Button(){
this.clicked = false;
this.click = () => {
this.clicked = true;
};
}
var button = new Button();
var elem = document.getElementById("test");
elem.addEventListener("click", button.click);
所以在创建实例时,箭头函数被创建,其中的this 指向了新创建的对象(button)。
如果使用字面量定义呢?
var button = {
clicked: false,
click: () => {
this.clicked = true;
}
}
由于click 箭头函数是作为对象字面量的属性定义的,对象字面量在全局代码中定义,因此,箭头函数内部this值与全局代码的this 值相同(指向window对象)。