上一章我们排除了一些对this的错误认识和知道了this是在调用函数时被绑定的,完全取决于函数的调用位置。先介绍两个概念:调用位置和调用栈。

调用栈:就是为了到达当前执行位置所调用的所有函数。

调用位置:在当前正在执行的函数的前一个调用中。即函数在代码中的调用位置而不是声明的位置。

function baz() {
//当前调用栈是baz
//因此,当前调用位置是全局作用域
bar(); //bar的调用位置
}
function bar() {
//当前调用栈是baz->bar
//因此,当前的调用位置是baz中
foo(); //foo的调用位置
}
function foo() {
//当前的调用栈是baz->bar->foo
//因此,当前的调用位置是bar中
}
baz(); //baz的调用位置

绑定规则:

1.默认绑定:

对于独立调用的 函数,会进行默认绑定。看下面的代码:

 function foo() {
console.log(this.a);
}
var a =2;
foo(); //2

非严格模式下,独立调用的 函数,会进行默认绑定,this指向全局对象。上面的代码foo()的调用位置是全局,在全局对象中定义了一个属性a,因此this.a 为2。

2.隐式绑定

调用位置是否有上下文对象,或者说是否被某个对象包含或者拥有

    function foo2() {
console.log(this.a);
}
var obj = {
a:3,
foo3:foo2
};
obj.foo3(); //

调用位置使用obj上下文引用函数,即函数被调用时被obj对象拥有或包含。

当函数引用上下文对象时,隐式绑定会把函数调用中的this绑定到这个上下文对象。

对象属性引用链中只有最后一层在调用位置中起作用。看下面代码:

    function foo() {
console.log(this.a);
}
var obj2 = {
a:23,
foo:foo
}
var obj1 = {
a:98,
obj2:obj2
}
obj1.obj2.foo(); //

3.显示绑定

因为隐式绑定时,我们必须在对象内部包含一个指向函数的属性,并通过属性指引这个函数,从而把this间接(隐式)的绑定到这个对象上。如果想在对象上强制调用函数,可以通过call(...)和apply(...)方法。这个两个方法的第一个参数是一个对象,是给this准备的,函数调用将this绑定在该对象上。这两个方法的原理相同只是里面的参数不同。

    function foo() {
console.log(this.a);
}
var obj ={
a:89
}
foo.call(obj); //

4.new绑定

js也有一个new操作符,使用方法看起来和那些面向类语言一样,其实js中的new操作符的机制实际上和面向类语言完全不同。js中,构造函数只是使用new操作符调用的函数。

使用new来调用函数,或者说发生构造函数调用时,会自动执行下面的操作

1.创建(或者说构造)一个新的对象。

2.这个新对象会被执行[[prototype]]链接。

3.这个新对象会被绑定到函数调用的this.

4.如果函数没有返回其他对象,那么new表达式的函数调用会自动返回到这个新对象。

    function Foo(a) {
this.a = a;
}
var bar = new Foo(2);
console.log(bar.a); //2

判 断this

根据优先级来判断函数在某个调用位置应运的是那条规则

1.函数是否在new中调用(new绑定)?如果是的话this绑定的是新创建的对象。

var bar = new Foo();

2.函数是否通过apply,call显示绑定,如果是的话,this绑定的就是指定的对象。

var bar= foo.call(obj);

3.函数是否在某个上下文中调用(隐式调用)?如果是的话,this绑定就是那个上下文对象。

var bar = obj.foo();

4.如果都不是的话,使用默认绑定。严格模式下,就绑定到undefined,否则就是全局对象

var bar =  foo()

JavaScript中的 this全面解析的更多相关文章

  1. JavaScript中依赖注入详细解析

    计算机编程的世界其实就是一个将简单的部分不断抽象,并将这些抽象组织起来的过程.JavaScript也不例外,在我们使用JavaScript编写应用时,我们是不是都会使用到别人编写的代码,例如一些著名的 ...

  2. javascript中 json数据的解析与序列化

    首先明确一下概念: json格式数据本质上就是字符串: js对象:JavaScript 中的几乎所有事务都是对象:字符串.数字.数组.日期.函数,等等. json数据的解析: 就是把后端传来的json ...

  3. javaScript中的this关键字解析

    this是JavaScript中的关键字之一,在编写程序的时候经常会用到,正确的理解和使用关键字this尤为重要.接下来,笔者就从作用域的角度粗谈下自己对this关键字的理解,希望能给到大家一些启示, ...

  4. javascript中有关this的解析题

    1.作用域链 作用域:浏览器给js一个生存环境(栈)内存 作用域链:js中的关键字var function 都可以提前声明和定义,提前声明和定义,放在我们的内存地址(堆)内存中,然后js从上到下逐行执 ...

  5. JavaScript中使用eval()方法解析json串

    最近在js用到了eval()方法,在这里做个笔记 当时是这么用的:data = eval("("+data+")"); data为后台向前台传送的一个json串 ...

  6. 前端开发:Javascript中的数组,常用方法解析

    前端开发:Javascript中的数组,常用方法解析 前言 Array是Javascript构成的一个重要的部分,它可以用来存储字符串.对象.函数.Number,它是非常强大的.因此深入了解Array ...

  7. 深入解析Javascript中this关键字的使用

    深入解析Javascript中面向对象编程中的this关键字 在Javascript中this关键字代表函数运行时,自动生成的一个内部对象,只能在函数内部使用.比如: function TestFun ...

  8. [JavaScript] JS中对Base64的解析

    JS中对Base64的解析 <script type="text/javascript"> /** * UTF16和UTF8转换对照表 * U+00000000 – U ...

  9. 解析JavaScript中apply和call以及bind

    函数调用方法 在谈论JavaScript中apply.call和bind这三兄弟之前,我想先说下,函数的调用方式有哪些: 作为函数 作为方法 作为构造函数 通过它们的call()和apply()方法间 ...

随机推荐

  1. 看到blackarch 字体不错 记录下来

    terminus-font

  2. 深入JVM之类的加载过程

    类的加载—连接—初始化 加载:查找并加载类的字节码文件,从硬盘到内存. 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.la ...

  3. 小强学渲染之OpenGL状态机理解

    状态机是理论上的一种机器,呃这个说法非常非常的抽象.通俗一点理解,状态机描述了一个对象在其生命周期内所经历的各种状态,状态间的转变,发生转变的动因,条件及转变中所执行的活动.或者说,状态机是一种行为, ...

  4. C#之SByte

    int8 C#中,byte为无符号8位整数,而Sbyte为有符号8位整数,对应java中的byte类型. 方法一将 byte 转为 sbyte.原理很简单,就是当 byte 小于 128 时其值保持不 ...

  5. Python类继承(转发)

    目录 一.概述 二.类的继承 2.1 继承的定义 2.2 构造函数的继承 2.3 子类对父类方法的重写 三.类继承的事例 回到顶部 一.概述 面向对象编程 (OOP) 语言的一个主要功能就是“继承”. ...

  6. vue获取后台图片验证码,并点击刷新验证码

    <--url为需要访问的接口地址--> <span style="display: inline-block;width: 130px;height: 53px;borde ...

  7. kubernetes 基础

    官网 kubernetes.io 有中文 中文网站  http://docs.kubernetes.org.cn kubectl 详细情况 https://kubernetes.io/docs/ref ...

  8. java命令分析线程死锁以及内存泄漏

    一.介绍 jstack是java虚拟机自带的一种堆栈跟踪工具.jstack用于打印出给定的java进程ID或core file或远程调试服务的Java堆栈信息,如果是在64位机器上,需要指定选项&qu ...

  9. 正则RegExp的懒惰性和贪婪性; 分组捕获;

    1.正则的懒惰性??? 每次在它的方法exec中捕获的时候,只捕获第一次匹配的内容,而不往下捕获,我们把这种情况称为正则的懒惰性 且每一次捕获的位置都是从索引0开始 正则的实例对象上有一个lastin ...

  10. c#NPOI读取excel 比interop和Microsoft.Jet.OLEDB.4.0 之类 的好的多

    今天下午开始整理excel这块, 微软弄的那些库简直是个坑, 什么com注册之类的净是些报错. 在网上搜资料偶然碰见npoi ,好东西,值得使用 NPOI是指构建在POI 3.x版本之上的一个程序,N ...