一、前言

我们每天都在书写着有关于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. HTML HTML5 新特性

    一.语义化标签 语义化标签 为页面提供了更好的页面结构. 描述 属性 <header></header>  定义文档的头部区域 <footer></foote ...

  2. Java导出压缩包工具类

    /** * @Title: exportZip * @Description:TODO(导出建压缩文件) * @param delAdviceinfo 为项目实体类 * @date 2018年4月4日 ...

  3. Springboot的static和templates区别

    static和templates部分参考博客:https://blog.csdn.net/wangb_java/article/details/71775637 热部署参考博客:https://www ...

  4. 【MySQL 读书笔记】当我们在使用索引的时候我们在做什么

    我记得之前博客我也写过关于索引使用的文章,但是并不全面,这次尽量针对重点铺全面一点. 因为索引是数据引擎层的结构我们只针对最常见使用的 Innodb 使用的 B+Tree 搜索树结构进行介绍. 每一个 ...

  5. Vue.js 2.x笔记:组件(5)

    1. 组件简介 组件(Component)是 Vue.js 最强大的功能之一,组件可以扩展 HTML 元素,封装可重用的代码. 组件:为了拆分Vue实例的代码量,以不同的组件来划分不同的功能模块,需要 ...

  6. 浅拷贝(Shallow Copy) VS 深拷贝(Deep Copy)

    首先,深拷贝和浅拷贝针对的是对象类型(对象,数组,函数) 浅拷贝指的是只是拷贝了对象的引用地址,彼此之间高耦合,一个改变,另一个可能也随之改变: 深拷贝是指只是完整的将变量的值拷贝过来,是一个新的对象 ...

  7. apache+php项目部署

    先安装apache和php然后进行如下操作(以63服务器的安装路径为例) 1.查看php项目运行的报错信息 路径:  cd  /var/log/httpd/error_log 如果错误如下: 可以尝试 ...

  8. bugku web web3

    flag就在这里快来找找吧http://123.206.87.240:8002/web3/ 点进去这个页面可以看到不断地有提示 flag就在这里 来找找吧 那就找一找哇 在source中可以找到一行注 ...

  9. Glide和Picasso的区别

    首先简单的介绍下两个库的出身: Picasso是Square公司出品的一款非常优秀的开源图片加载库Glide是由Google开发,基于 Picasso,依然有保存了Picasso的简洁风格,但是在此做 ...

  10. django xadmin(1)

    filter_horizontal 从‘多选框’的形式改变为‘过滤器’的方式,水平排列过滤器,必须是一个 ManyToManyField类型,且不能用于 ForeignKey字段,默认地,管理工具使用 ...