Javascript学习之this
![this图解](https://i-blog.csdnimg.cn/blog_migrate/ff1e016fd46cf761f1fd9c6728d5f4d7.jpeg)
第一次写博客,如有疏漏不足之处请谅解指正,一个最简单的例子
function sayHello(){
console.log(this);
}
sayHello()//window
上面是很简单的例子,在全局环境下声明了一个函数并调用,我对this简单的理解,谁调用this的this就指向谁,this只有在调用的时候才能确定是谁(箭头函数例外),this 既不指向函数自身,也不指函数的词法作用域。它实际是在函数被调用时才发生的绑定,也就是说this具体指向什么,取决于你是怎么调用的函数。这里实在全局环境下调用的,因此this指向全局即window,让我们来看第二个简单的例子
var obj = {
sayHello: function () {
console.log(this);
}
}
obj.sayHello(); //obj
var fn = obj.sayHello;
fn() //window
这里我申明一个对象,对象里有个方法叫sayHello,第一次我们是通过obj打点的方式调用的,所以this指向obj,第二次我们把obj.sayHello这个函数赋给了fn,由于我们是在全局环境下赋值的,所以fn的调用者就是window,继续往下拓展点
var a = 'outer'
var obj = {
a: 'inner',
sayHello: () => {
console.log(this.a);
}
}
obj.sayHello(); //outer
var fn = obj.sayHello;
fn() //outer
这次我们把sayHello函数改成了es6中的箭头函数,记住箭头函数中this默认是绑定外层的this,也就是说会和外层的this保持一致,即obj这层的this即window,在window下我们声明了a为‘outer’,对obj进行小小的改变来验证这种说法
var a = 'outer';
var obj = {
a:'inner',
sayHello: function() {
console.log(this.a)
setTimeout(() => {
console.log(this.a)
}, 1000)
}
}
obj.sayHello(); //inner inner
var fn = obj.sayHello;
fn() //outer outer
第一次用obj打点的方式调用,在sayHello函数内部,第一次输出的this指向的就是obj,在setTimeout函数内部我们声明了一个箭头函数,上文说过箭头函数的this是外层绑定的this,这个外层应该是sayHello,sayHello这层的this指向的是obj,所以两次都打印inner,而通过fn()这种方式就不在赘述了,可以参考上文,那如果箭头函数外面嵌套好几层了?
var a = 'outer'
var obj = {
a: 'inner',
b: {
a:'innerinner',
sayHello: () => {
console.log(this.a);
}
}
}
obj.b.sayHello(); //outer
var fn = obj.b.sayHello;
fn() //outer
是不是很意外,多层对象嵌套里箭头函数里this是和最最外层保持一致的,在这里即和obj的this保持一致
function Test() {
this.x = 1;
this.sayHello = function(){
console.log(this.x)}
}
var obj = new Test();
obj.sayHello()//1
在这里我们声明了一个构造函数,所谓构造函数,就是通过这个函数,可以生成一个新对象。这时,this就指这个新对象
function Person(name,age){
this.name = name;
this.age = age;
this.sayName=function(){
console.log(this.name)
}
}
var person=new Person("xu",18);
person.sayName();//xu
var obj = {}
Person.call(obj,"liu",20)
//Person.apply(obj,[liu','20'])
obj.sayName();//liu
call,apply都可以改变this指向,不同的是call传递的是一个个参数,而apply传递的是一个数组,这里用apply写的话就是Person.apply(obj,[‘liu’,‘20’]),结果也是一样的