美文网首页
深入浅出this

深入浅出this

作者: zy懒人漫游 | 来源:发表于2018-02-09 06:48 被阅读0次

What's this?

由于运行期绑定的特性,JavaScript 中的 this 含义非常多,它可以是全局对象、当前对象或者任意对象,这完全取决于函数的调用方式
随着函数使用场合的不同,this的值会发生变化。但是有一个总的原则,那就是this指的是,调用函数的那个对象

作为函数调用

在函数被直接调用时this绑定到全局对象。在浏览器中,window 就是该全局对象

console.log(this);//window
function fn1(){
    console.log(this);
}
fn1();//window   因为在fn的作用域里找不到,就会像上找,这样就会找到window

还有,函数里this不是代表函数本身,这个很重要,很多新人都会犯这个错误,包括我之前也老是觉得,函数里的this,代表的就是这个函数,这是错误的,下面我们来看这个例子

var a = 100
function fn(){
  var a = 1
  console.log(this.a);
}
fn()//100

很多新手一看就觉得,咦!怎么打印的不是1,而是全局下的a呢?因为在函数里找不到this,那么就会去外面找,上面说了,外面的this代表window,所以console.log(this.a);实际上就是console.log(window.a);,所以打印出的值是100。

内部函数

函数嵌套产生的内部函数的this不是其父函数,仍然是全局变量

function parent(){
  function children(){
    console.log(this);
  }
  children()
}
parent()//window

首先会再函数内部找this,发现子函数里找不到this,那就去父函数找,还是找不到,最后就去父函数的外面也就是全局下找this,所以打印出的是window

setTimeout、setInterval

这两个方法执行的函数this也是全局对象

document.addEventListener('click', function(e){
    console.log(this);
    setTimeout(function(){
        console.log(this);
    }, 200);
}, false);

第一个this是绑定事件的这个元素,第二个this代表的全局对象window,如下图所示


image.png

如果在函数里申明了var self=this,那么第二个this就变掉了,相当于把第一个this代表的元素保存起来了,我们直接来看代码。如果看的有点绕的话,可以这么想,我可以不用_this,可以用me、self来代替,效果一样

image.png
document.addEventListener('click', function(e){
    console.log(this);
    var me = this
    setTimeout(function(){
        console.log(me);
    }, 200);
}, false)

作为构造函数调用

所谓构造函数,就是通过这个函数生成一个新对象(object)。这时,this就指这个新对象

new 运算符接受一个函数 F 及其参数:new F(arguments...)。这一过程分为三步:

  • 创建类的实例。这步是把一个空的对象的 __proto__ 属性设置为 F.prototype 。
  • 初始化实例。函数 F 被传入参数并调用,关键字 this 被设定为该实例。
  • 返回实例。
function Person(name){
    this.name = name;
}
Person.prototype.printName = function(){
    console.log(this.name);
};

var p1 = new Person('Byron');
var p2 = new Person('Casper');
var p3 = new Person('Vincent');

p1.printName();
p2.printName();
p3.printName();

p1.printName();这句话执行的时候,先执行p1 = new Person('Byron'),然后在new的时候,做了三件事,
1、创建新的空对象
2、然后是把这个空的对象的 __proto__ 属性设置为 Person.prototype 
3、执行函数Person,遇到this,就认为this是刚才创建的对象,给它添加一个属性name,而这个属性的值就是函数Person的name
执行完成之后,把新对象return出来赋值给p1
这样就可以通过p1的方式去用了

作为对象方法调用

在 JavaScript 中,函数也是对象,因此函数可以作为一个对象的属性,此时该函数被称为该对象的方法,在使用这种调用方式时,this 被自然绑定到该对象,简单的来说,就是谁调用这个函数,这个函数指的就是谁(这个this就代表谁)。

如:Object1.fn(),this指的就是Object1,
假如:Object1.Object2.Object3.fn(),this指的就是Object3,
this指向最后一次调用者

var obj1 = {
    name: 'Byron',
    fn : function(){
        console.log(this);
    }
};
obj1.fn();//{name: "Byron", fn: ƒ}

var fn2 = obj1.fn;
fn2();//window 因为fn是全局变量,等同于执行winow.fn2()

相关文章

网友评论

      本文标题:深入浅出this

      本文链接:https://www.haomeiwen.com/subject/enaxtftx.html