一、前言

我们每天都在书写着有关于this的javascript代码,似懂非懂地在用着。前阵子在看了《你不知道的JavaScript上卷》之后,也算是被扫盲了一边关于this绑定的四种方式。

二、绑定规则

关于this应用的是哪条规则,得先找到调用的位置,再判断应用了哪条规则。

1、默认绑定

先上代码:

var a = 2;

function foo() {
console.log(this.a);
} foo(); // 结果:2

先来分析下上面的代码声明,

首先我们在全局作用域中定义了一个变量a,而在全局作用域声明的变量,就相当于为window对象声明了同名属性a并赋值为2,接着又在全局作用域下声明了foo函数,最后我们在调用foo函数时,是直接不带任何修饰下调用foo函数,此时的this的绑定规则为默认绑定,this指向window对象,所以结果输入为2。

如果此时使用了严格模式,即在代码中加了"use strict",this指向undefined,调用的结果就会出错而不是输出2。

2、隐式绑定

var a = 2;

function foo() {
console.log(this.a);
} var obj = {
a: 4,
foo:foo
}; foo(); // 结果:2
obj.foo(); // 结果4

代码还是差不多的代码,只是加了一个obj对象,对象有一个a属性和一个foo属性引用了foo函数。对于foo();输出结果2,在上一节已经说明,因为是没用带任何修饰的情况下调用,应用了默认绑定。而在obj.foo()的调用中,foo函数的调用上下文是obj对象,obj包含了foo函数,此时this的绑定就发生了隐式绑定,this指向obj,this.a相当于obj.a,所以结果自然而然也输入4。

对于这种方式,我在代码中也经常用到。把可以归类的方法、变量都写成一个对象的形式,就形成了一个模块,也相当于一种设计模式,模块模式。

3、显式绑定

var a = 2;

function foo() {
console.log(this.a);
} var obj = {
a: 4
}; foo.call(obj); // 结果:4
foo.apply(obj); // 结果:4
foo.bind(obj)(); // 结果:4

对于call、apply、bind的这三种调用方式都是属于显式绑定,作用是通过显示传入一个对象,改变this的上下文为此对象。call和apply是直接改变上下文对象直接调用,而bind是返回一个已经显示绑定的上下文的函数。

call和apply两个都是显示改变上下文并执行,唯一不同的就是传参方式,call是对象后面可以跟着多个参数,而apply传递参数,需要传递一个数组,即:

foo.call(obj, arg1, arg2, arg3, ...);
foo.apply(obj, [arg1, arg2, arg3, ...])

4、new绑定

学过后端语言的人都知道,通过构造函数,可以new一个对象实例,而在JavaScript中,对象也是通过new构造函数生成的,但,却和面向对象语言的new方式是不一样。下面来看看new操作符到底做了什么。

function foo() {
console.log(this.a);
} var obj = new foo();

当使用new来调用函数时,发生了以下步骤:

a、创建了一个全新的对象,如:var obj = {};

b、连接全新对象与调用函数之间的[[Prototype]],让函数的prototype指向全新对象,如obj.__proto__ = foo.prototype;

c、新对象会绑定到函数调用的this,如:foo.call(obj);

d、返回对象。如果函数没有返回其他对象,那么new操作会自动返回这个新对象。

三、优先级

一般情况下:new绑定 > 显式绑定 > 隐式绑定 > 默认绑定

四、总结

还有其他的一些细节知识点,推荐还是看《你不知道的JavaScript上卷》这本书,真心不错。

关于this绑定的四种方式的更多相关文章

  1. ASP.NET MVC之下拉框绑定四种方式(十)

    前言 上两节我们讲了文件上传的问题,关于这个上传的问题还未结束,我也在花时间做做分割大文件处理以及显示进度的问题,到时完成的话再发表,为了不耽误学习MVC其他内容的计划,我们今天开始好好讲讲关于MVC ...

  2. Webform中Repeater控件--绑定嵌入C#代码四种方式

    网页里面嵌入C#代码用的是<% %>,嵌入php代码<?php ?> 绑定数据的四种方式: 1.直接绑定 <%#Eval("Code") %> ...

  3. React组件绑定this的四种方式

    题图 By HymChu From lnstagram 用react进行开发组件时,我们需要关注一下组件内部方法this的指向,react定义组件的方式有两种,一种为函数组件,一种为类组件,类组件内部 ...

  4. jQuery绑定事件的四种方式:bind、live、delegate、on

    1.jQuery操作DOM元素的绑定事件的四种方式 jQuery中提供了四种事件监听方式,分别是bind.live.delegate.on,对应的解除监听的函数分别是unbind.die.undele ...

  5. 函数调用的四种方式 和 相关的 --- this指向

    this:表示被调用函数的上下文对象. arguments:表示函数调用过程中传递的所有参数. 这两个参数都是隐式的函数参数.会静默传递给函数,并且和函数体内显式声明的参数一样可正常访问. argum ...

  6. android点击事件的四种方式

    android点击事件的四种方式 第一种方式:创建内部类实现点击事件 代码如下: package com.example.dail; import android.text.TextUtils; im ...

  7. js 复制文本的四种方式

    js 复制文本的四种方式 一.总结 一句话总结:js文本复制主流方法:document的execCommand方法 二.js 复制文本的四种方式 纯 转载复制,非原创 原地址:http://www.c ...

  8. C#批量插入数据到Sqlserver中的四种方式

    我的新书ASP.NET MVC企业级实战预计明年2月份出版,感谢大家关注! 本篇,我将来讲解一下在Sqlserver中批量插入数据. 先创建一个用来测试的数据库和表,为了让插入数据更快,表中主键采用的 ...

  9. 【Java EE 学习 80 下】【调用WebService服务的四种方式】【WebService中的注解】

    不考虑第三方框架,如果只使用JDK提供的API,那么可以使用三种方式调用WebService服务:另外还可以使用Ajax调用WebService服务. 预备工作:开启WebService服务,使用jd ...

随机推荐

  1. Core官方DI剖析(1)--ServiceProvider类和ServiceCollection类

    前段时间看了蒋老师的Core文章,对于DI那一块感觉挺有意思,然后就看了一下Core官方DI的源码,这也算是第一个看得懂大部分源码的框架,虽然官方DI相对来说特别简单, 官方DI相对于其它框架(例如 ...

  2. [解读REST] 2.REST用来干什么的?

    衔接上文[解读REST] 1.REST的起源,介绍了REST的诞生背景.每当笔者遇到一个新事物的想去了解的时候,总是会问上自己第一个问题,这个新事物是干什么用的?在解释我所理解的REST这个过程中也不 ...

  3. Eclipse中快捷键Ctrl + Alt + 向上箭头 或者 Ctrl + Alt + 向下箭头与Windows冲突

    原文地址:https://blog.csdn.net/buaaroid/article/details/50804608 clipse中按ctrl + alt + 向上箭头没有任何反应,按ctrl + ...

  4. Python Threading问题:TypeError in Threading. function takes 1 positional argument but 100 were given

    在使用python多线程module Threading时: import threading t = threading.Thread(target=getTemperature, args = ( ...

  5. Neutron vxlan network--L2 Population

    L2 Population 是用来提高 VXLAN 网络 Scalability 的.   通常我们说某个系统的 Scalability 好,其意思是: 当系统的规模变大时,仍然能够高效地工作. L2 ...

  6. 菜鸟学IT之第一次作业

    作业的要求来自于:https://www.cnblogs.com/greyzeng/p/9581624.html 反思· 为何要来上课并且认真参与? 在大学中的师生关系? 自我简述题目 心得· 学习态 ...

  7. (八)jdk8学习心得之Optional类

    八.Optional 类 1. 作用:可以存放空指针null,主要用于解决空指针问题. 2. 使用方法 1) 创建对象(2种方法) Optional optional = Optional.of(非n ...

  8. ansible 模块

    1. #vim /etc/ansible/yaml/back.yml - hosts: siyi tasks: - name: "yum rsync" yum: name=rsyn ...

  9. 什么是CAS机制?(转)

    围绕下面四个点展开叙述: 一:什么是CAS机制? 二:Java当中CAS的底层实现 三:CAS的ABA问题和解决方法 四:java8对CAS的优化 一:什么是CAS机制? 我们先看一段代码: 启动两个 ...

  10. Django-5 模板层

    Django 模板层 在之前的例子中,我们采用了硬编码的方式,来返回文本 def current_datetime(request): now = datetime.datetime.now() ht ...