JavaScript系列之this

前言

在JavaScript语言中存在一个this关键词,这个关键词指的是函数运行时所在的环境。因为函数能够在不一样的运行环境执行,因此须要有一种机制,可以在函数体内部得到当前的运行环境(context)。因此,this就出现了,它的设计目的就是在函数体内部,指代函数当前的运行环境。bash

前一个系列的做用域讲过,做用域运用的是词法做用域,意味着是编写时肯定的,但this与其工做原理彻底不一样,它的指向并非编写时肯定的,而是运行时肯定。markdown

仅仅是“规则”

以前在阅读 You Don't Know JS系列的: this & Object Prototypes中,将this的指向总结了几条规则:数据结构

函数调用方式与内部this指针关系:app

  1. 直接调用:函数内部this指向全局对象window
  2. 经过对象使用点来调用:函数内部this指向调用对象
  3. 触发事件调用函数:函数内部的this指向触发事件的对象
  4. 经过call的方法来间接调用方法:函数内部this指向call方法的第一参数对象,咱们能够建立结构相同,但内容不一样的对象
  5. new的方式来调用:函数内部this指向本次函数执行时对应的一个匿名对象(以new的方式建立的函数,函数名的首字母通常以大写字母开始)
  6. 箭头函数的this,指向取决于函数外的上下文。箭头函数没法被new关键词调用,经过applycall方法不会改变内部的this指向

不单单是“规则”

参考了上面的规则发现,this的指向不管如何都逃脱不了上面的5大原则,那它们以前是否存在必定的规律呢,或者说是什么来决定this的指向的。函数

一般咱们会对一下例子的结果无法准确的肯定this指向:oop

var name = 'zhou';
var obj = {
    name: 'shaw',
    say: function () {
        console.log(this.name);
    }
}
obj.say();  

var say = obj.say;
say();
复制代码

上面的输出结果会是什么呢:this

obj.say(); // 输出shaw
say();  // 输出zhou
复制代码

为何这里obj.saysay的输出结果会不一致呢?下面咱们来一探究竟。spa

this的指向与数据在内存里的数据结构有关:设计

上面案例里的obj对象是如何在内存中存储的呢指针

obj.say-> {
    [[value]]: say函数地址
    [[write]]: true,
    [[readable]]: true
}
复制代码

实际上say函数并无存储在obj对象中,它只存储了say函数的地址。

咱们直接经过obj.say来调用函数,与obj.say赋值给say变量调用彻底不一样,由于obj中存储的是say函数的地址,咱们进行赋值操做时直接将say函数地址直接赋值过去了,而不是咱们想象的将obj.say引用赋值过去。

相关文章
相关标签/搜索