首页,js默认的对象是Window,调用一个函数是,如果不去改变它的调用对象的话,this基本上都会指向Window。
es6的箭头函数本身是没有this的。普通的函数也没有自己的this,但普通函数的this会在你调用的时候重新设置要指向的对象。
- 普通函数的this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象,当有多层调用时,this的指向为它的上一级。
- 箭头函数的this根据他的父级的this的指向的变化而变化。
- 严格模式下,全局的函数的this指向会变成undefined。用babel编译js文件时,使用的是严格模式,如果this是指向全局的会被编译成undefined。
普通函数的this的几种指向情况
例子1:
function fn() {
var testfn = 2;
console.log(this); // Window
console.log(this.testfn); // undefined
}
fn();
这里的fn的实际的调用是 window.fn()
,所以this的指向是Window,又因为testfn是再fn里面的,所以this.testfn的值为undefined。
例子2:
var methods = {
num: '111',
init: function () {
console.log(this.name); // '111'
}
};
methods.init();
这里的this指向的是methods,init的实际调用是window.methods.init();
例子3:
var methods = {
num: '111',
b: {
name: 222,
init: function () {
console.log(this.name); // 222
}
}
};
methods.b.init();
例子4:
var methods = {
num: '111',
b: {
name: 222,
init: function () {
console.log(this); // Window
console.log(this.name); // undefined
}
}
};
var fn = methods.b.init;
fn();
这里的this的指向为什么会变Window呢?
首先init这个函数被赋值给fn,现在fn这个函数就有了init函数里面的内容(也就是两个console),这时,init这个函数并没有执行;第二步,调用fn(),这时fn是直接调用,也就是它的实际的写法是window.fn();
所以它的this的指向是Window,而name这个属性是在methods对象中的,所以this.name的值为undefined。
总结:
- 如果函数的调用是直接调用,没有上一级也就是它的前面没有“.”,则它的this指向是Window,例:fn();
- 如果函数的调用前面有一个或多个“.”(不算window的情况下),则它的this指向是它的上一级,例:
methods.init();
它的this指向的是methods;methods.b.init();
它的this指向的是b。
构造函数中的this
例1:正常情况下
function fn() {
console.log(this); // fn();
}
var f = new fn();
console.log(f);
正常情况下的构造函数中的this会指向本身,也就是你new的这个函数。
例2:有return的(接下来的几种情况)
返回一个对象
function fn() {
console.log(this); // {}
return {};
}
var f = new fn();
console.log(f);
返回一个函数
function fn() {
console.log(this); //function(){}
return function(){};
}
var f = new fn();
console.log(f);
返回一个数值
function fn() {
console.log(this); // fn()
return 1;
}
var f = new fn();
console.log(f);
返回undefined和null
function fn() {
console.log(this); // fn()
return undefined;
}
var f = new fn();
console.log(f);
function fn() {
console.log(this); // fn()
return null;
}
var f = new fn();
console.log(f);
总结:如果返回值是一个对象(null虽然也是对象,但它在这个情况下比较特殊),那么this指向的就是那个返回的对象,如果返回值不是一个对象那么this还是指向函数的实例。
es6 this的指向
例1:
methods = {
num: '111',
init: () => {
console.log(this); // Window
console.log(this.num); // undefined
}
};
methods.init();
这里的init里面的this为什么指向的不是methods这个对象呢?前面说到,箭头函数this的指向是根据父级的this的变化而变化的。这里的methods他的this指向的是window,所以init里面this也是指向window,无论init里面嵌多少层箭头函数,它的指向还是会指向window。
例2:
methods = {
num: '111',
init: function() {
console.log(this.num); // '111'
var fn = () => {
console.log(this.num); // '111'
};
fn();
}
};
methods.init();
这个函数结合前面的知识点看,init现在使用的是普通函数,所以这里它的this指向的是methods。而fn的父级是init,init的this已经不是指向window了,所以fn里面的this也会跟着改变。
网友评论