一 , this的默认绑定

当一个函数没有明确的调用对象的时候,也就是单纯作为独立函数调用的时候,将对函数的this使用默认绑定:绑定到全局的window对象.

一个例子

  1. function fire () {
  2. // 我是被定义在函数内部的函数哦!
  3. function innerFire() {
  4. console.log(this === window)
  5. }
  6. innerFire(); // 独立函数调用
  7. }
  8. fire(); // 输出true
  9. //即使函数innerFire是包含在函数fire里面的,但是由于函数innerFire是独立调用,所以函数innerFire内的this还是指向window.

二 , this的隐式绑定

当函数被一个对象“包含”的时候,我们称函数的this被隐式绑定到这个对象里面了,这时候,通过this可以直接访问所绑定的对象里面的其他属性

第一个例子

  1. var obj = {
  2. a: 1,
  3. fire: function () {
  4. console.log(this.a)
  5. }
  6. }
  7. obj.fire(); // 输出1
  8. //函数fire包含在对象obj里,所以this就隐式绑定到对象obj.this就可以访问obj的属性.

第二个例子

  1. // 我是第一段代码
  2. function fire () {
  3. console.log(this.a)
  4. }
  5. var obj = {
  6. a: 1,
  7. fire: fire
  8. }
  9. obj.fire(); // 输出1
  10. // 我是第二段代码
  11. var obj = {
  12. a: 1,
  13. fire: function () {
  14. console.log(this.a)
  15. }
  16. }
  17. obj.fire(); // 输出1
  18. //这个例子说明了函数被定义在对象内部和外部没有任何区别.也说明了this绑定是动态的(在运行时绑定而不是书写时)

隐式绑定丢失的问题

一个例子

  1. var obj = {
  2. a: 1, // a是定义在对象obj中的属性 1
  3. fire: function () {
  4. console.log(this.a)
  5. }
  6. }
  7. var a = 2; // a是定义在全局环境中的变量 2
  8. var fireInGrobal = obj.fire;
  9. fireInGrobal(); // 输出 2

可以这么理解,函数在成为对象的属性的时候,是具有独立性的.打个比方就像当初波兰加入了华约,波兰是华约的一份子,但他并不是华约缔造的.后来苏联解体,华约的一部分势力范围,不是全部(俄罗斯就不是)变成了北约的势力范围了.于是波兰加入了北约,和新的大哥混了.回到这个函数,对象obj就是华约,函数fire就是波兰,属性a:1就是俄罗斯.现在,曾经的华约势力范围obj.fire变成了以世界警察fireInGrobal为首的北约的地盘,于是波兰加入北约,听候大哥fireInGrobal的差遣.大哥问,谁才是老大?fireInGrobal(),波兰高呼Americana = 2.

其实多数情况下,是不会发生this绑定丢失的,只有一种情况下会丢失,函数没有执行,当做值传递了。不管是赋值操作,还是当做回调函数的参数传递。


三 , this的显示绑定

在上一个例子中,fireInGrobal()obj.fire调用的结果是不同的,在赋值过程中,this绑定丢失了.call就是为了解决这个问题的.

call的基本使用方式: fn.call(object)

fn : 上一例子中的 fireInGrobal

**object : 上一例子中的 obj **

作用 : 大哥问谁是老大,波兰说是俄罗斯(重新把this绑定回obj)

一个例子

  1. var obj = {
  2. a: 1, // a是定义在对象obj中的属性
  3. fire: function () {
  4. console.log(this.a)
  5. }
  6. }
  7. var a = 2; // a是定义在全局环境中的变量
  8. var fireInGrobal = obj.fire;
  9. fireInGrobal(); // 输出2
  10. fireInGrobal.call(obj); // 输出1

每次执行都要加入call吗?很麻烦.我们可以这样改一下

  1. var obj = {
  2. a: 1, // a是定义在对象obj中的属性
  3. fire: function () {
  4. console.log(this.a)
  5. }
  6. }
  7. var a = 2; // a是定义在全局环境中的变量
  8. var fn = obj.fire;
  9. var fireInGrobal = function () {
  10. fn.call(obj) //硬绑定
  11. }
  12. fireInGrobal(); // 输出1

如果使用bind,会更简单

  1. //上一个例子中的代码
  2. var fireInGrobal = function () {
  3. fn.call(obj) //硬绑定
  4. }
  5. //可以简化为
  6. var fireInGrobal = fn.bind(obj);

call和bind的区别是:在绑定this到对象参数的同时:

1.call将立即执行该函数

2.bind不执行函数,只返回一个可供执行的函数

3.当然还有apply,他们的区别是这样的:

  1. 他们的作用一模一样,区别在于传入参数形式不同.
  2. apply接受两个参数,第一个指定this对象的指向,第二个参数为一个带下标的集合,这个集合可以为数组,也可以为类数组,apply把这个集合中的元素作为参数传递给被调用的函数.
  1. var func = function( a, b, c ){
  2. alert([a,b,c]); //输出[1,2,3]
  3. };
  4. func.apply( null, [ 1, 2, 3 ] );
  1. call传入的参数不固定,与apply相同的是,第一个参数也是代表函数体内的this指向,从第二个参数开始往后,每个参数被依次传入函数.
  1. var func = function( a, b, c ){
  2. alert([a,b,c]); //输出[1,2,3]
  3. };
  4. func.call( null, 1, 2, 3 );
  1. 当使用call或apply的时候,如果第一个参数是null,this会指向默认宿主对象,在浏览器中就是window.

四 , new绑定

执行new操作的时候,将创建一个新的对象,并且将构造函数的this指向所创建的新对象.

例子

  1. function foo (a) {
  2. this.a = a;
  3. }
  4. var a1 = new foo (1);
  5. var a2 = new foo (2);
  6. var a3 = new foo (3);
  7. var a4 = new foo (4);
  8. console.log(a1.a); // 输出1
  9. console.log(a2.a); // 输出2
  10. console.log(a3.a); // 输出3
  11. console.log(a4.a); // 输出4

如果构造函数显式使用return返回一个对象,那么调用表达式的值就是这个对象

  1. var obj = {a:1};
  2. function fn(){
  3. this.a = 2;
  4. return obj;
  5. }
  6. var test = new fn();
  7. console.log(test);//{a:1}

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

  1. 【javascript】函数中的this的四种绑定形式

    目录 this的默认绑定 this的隐式绑定 隐式绑定下,作为对象属性的函数,对于对象来说是独立的 在一串对象属性链中,this绑定的是最内层的对象 this的显式绑定:(call和bind方法) n ...

  2. 【javascript】函数中的this的四种绑定形式 — 大家准备好瓜子,我要讲故事啦~~

       javascript中的this和函数息息相关,所以今天,我就给大家详细地讲述一番:javascript函数中的this   一谈到this,很多让人晕晕乎乎的抽象概念就跑出来了,这里我就只说最 ...

  3. 函数中的this的四种绑定形式

    目录 this的默认绑定 this的隐式绑定 隐式绑定下,作为对象属性的函数,对于对象来说是独立的 在一串对象属性链中,this绑定的是最内层的对象 this的显式绑定:(call和bind方法) n ...

  4. JavaScript函数中的this四种绑定形式

    this的默认绑定.隐式绑定.显示绑定.new绑定 <script> //全局变量obj_value ; //1.window调用 console.log(`*************** ...

  5. javascript——四种函数调用形式

    此文的目的是分析函数的四种调用形式,弄清楚函数中this的意义,明确构造函对象的过程,学会使用上下文调用函数. 在JavaScript中,函数是一等公民,函数在JavaScript中是一个数据类型,而 ...

  6. JavaScript高级之函数的四种调用形式

    主要内容 分析函数的四种调用形式 弄清楚函数中this的意义 明确构造函对象的过程 学会使用上下文调用函数 了解函数的调用过程有助于深入学习与分析JavaScript代码. 本文是JavaScript ...

  7. Tensorflow 损失函数及学习率的四种改变形式

    Reference: https://blog.csdn.net/marsjhao/article/details/72630147 分类问题损失函数-交叉熵(crossentropy) 交叉熵描述的 ...

  8. this的四种绑定规则总结

    一.默认绑定 1.全局环境中,this默认绑定到window 2.函数独立调用时,this默认绑定到window console.log(this === window);//true functio ...

  9. Android颜色值(RGB)所支持的四种常见形式

    Android中颜色值是通过红(Red).绿(Green).蓝(Blue)三原色,以及一个透明度(Alpha)值来表示的,颜色值总是以井号(#)开头,接下来就是Alpha-Red-Green-Blue ...

随机推荐

  1. innerHTML innerText的使用和区别

    document对象中有innerHTML.innerText这两个属性,都是获取document对象文本内容,但使用起来还是有区别的: 1) innerHTML设置或获取标签所包含的HTML+文本信 ...

  2. [js高手之路]HTML标签解释成DOM节点

    最近在封装一个开源框架,已经写了500行, 已经具备jquery的大多数常用功能.跟jquery的使用方法完全一样,jquery的选择器,几乎都能支持,为什么说这事,跟这篇文章的主题有毛关系呢?因为这 ...

  3. python调用C函数

    python 与 c可以相互调用,在做后台服务时底层服务用C/C++编写,通过python调用C库可以极大的提高开发效率. 下面对几种调用方式举例说明 1 python通过指针传递浮点型数组给C函数 ...

  4. 002-Apache Maven 构建生命周期

    Maven - 构建生命周期 什么是构建生命周期 构建生命周期是一组阶段的序列(sequence of phases),每个阶段定义了目标被执行的顺序.这里的阶段是生命周期的一部分. 举例说明,一个典 ...

  5. 关于sys.argv

    sys.argv[]用来获取命令行参数,sys.argv[0]表示代码本身的文件路径.比如在命令行输入‘python test.py -version',sys.argv[0]的值即为test.py, ...

  6. angular2 官方demo heroApp

    最近学习angular2,于是从官网的hero例子开始学习.经过几番周折终于完成了这个例子.收益匪浅.个人建议在开始学习例子前可以先了解一些概念,模块,组件,装饰器.....,有助于写代码时候的逻辑. ...

  7. EIGRP系统复习【转载】

    EIGRP理论 简介 EIGRP是Cisco私有协议,它是由距离矢量和链路状态两种路由协议混合而成的一种协议.即像距离矢量协议那样,EIGRP从它的相邻路由器那里得到更新信息:也像链路状态协议那样,保 ...

  8. 自制MPLS解决路由黑洞实验

    利用mpls解决BGP路由黑洞配置命令全解析 --By Jim 什么是BGP路由黑洞? BGP规定无论路由器是否启动bgp都要无条件地转发BGP消息和更新包(凌驾于IGP之上),违背了IGP" ...

  9. [转载]Linux shell中的竖线(|)——管道符号

    原文地址:Linux shell中的竖线(|)--管道符号作者:潇潇 管道符号,是unix一个很强大的功能,符号为一条竖线:"|". 用法: command 1 | command ...

  10. 如何使用phpstudy本地搭建多站点(每个站点对应不同的端口)

    到http://phpstudy.net/a.php/208.html下载phpstudy 1.装完phpstudy后,(假设安装在D盘,安装后开启服务) 在D:\phpStudy\WWW\路径下创建 ...