前端 js 之 this 的绑定规则 04

编程入门 行业动态 更新时间:2024-10-11 15:14:06

前端 js 之 this 的<a href=https://www.elefans.com/category/jswz/34/1769902.html style=绑定规则 04"/>

前端 js 之 this 的绑定规则 04

嘿,加油😍

文章目录

  • 一、this?
  • 二、this 的指向
  • 三、默认绑定(独立函数调用)
  • 四、隐式绑定
  • 五、显式绑定 (apply call bind)
  • 六、new绑定 (后面会详细再补充)
  • 七、apply call bind 区别
  • 八、内置函数的绑定思考
  • 九、规则优先级
  • 十、说明
  • 十一、this 规则之外
    • 1. 忽略显示绑定
    • 2. ES6箭头函数


一、this?

        在其他面向对象编程中,this 一般会出现在类的方法里,但是在js中,this更灵活,无论是它出现的位置还是它代表的含义。首先this在全局里指向window, 但是,开发中很少直接在全局作用于下去使用this,通常都是在函数中使用,在之前文章里说过,当我们函数调用时,会创建一个执行上下文,这个上下文记录着函数的调用栈,AO对象,还有其他,当然还记录着一个很重要的东西,this

二、this 的指向

function foo() {console.log(this);}// 1.调用方式一:直接调用;foo(); //window// 2.调用方式二:将foo放到一个对象中,再调用var obj = { name: "why", foo2: foo };obj.foo2(); //obj对象// 3.调用方式三:通过ca1l/apply调用foo.call("abc"); // String {"abc"子对象}

根据这个案例,我们可以发现

  1. 函数在调用时,JavaScript会默认给this绑定一个值; windows
  2. this的绑定和定义的位置(编写的位置)没有关系,和调用方式以及调用的位置有关系
  3. this是在运行时被绑定的

那么this到底是怎么样的绑定规则呢?

  1. 绑定一:默认绑定;
  2. 绑定二:隐式绑定;
  3. 绑定三:显示绑定;
  4. 绑定四:new绑定

三、默认绑定(独立函数调用)


当独立函数调用时,JavaScript会默认给this绑定一个值: windows

独立的函数调用我们可以理解成 函数没有被绑定到某个对象上进行调用

四、隐式绑定

另外一种比较常见的调用方式是通过某个对象进行调用,也就是它的调用位置中,是通过某个对象发起的函数调用。

五、显式绑定 (apply call bind)


隐式绑定有一个前提条件:

  1. 必须在调用的对象内部有一个对函数的引用(比如一个属性);
  2. 如果没有这样的引用,在进行调用时,会报找不到该函数的错误;
  3. 正是通过这个引用,间接的将this绑定到了这个对象上;

如果我们不希望在 对象内部 包含这个函数的引用,同时又希望在这个对象上进行强制调用,该怎么做呢?

  1. JavaScript所有的函数都可以使用call和apply方法(这个和Prototype有关)。

  2. 这两个函数的第一个参数都要求是一个对象,这个对象的作用是什么呢?就是给this准备的

  3. 在调用这个函数时,会将this绑定到这个传入的对象上。

  4. 因为上面的过程,我们明确的绑定了this指向的对象,所以称之为 显示绑定。

六、new绑定 (后面会详细再补充)


JavaScript中的函数可以当做一个类的构造函数来使用,也就是使用new关键字。

使用new关键字来调用函数是,会执行如下的操作:

  1. 首先他会创建一个全新的对象;
  2. 这个新对象会被执行prototype连接;
  3. 这个新对象会绑定到函数调用的this上(this的绑定在这个步骤完成);
  4. 如果函数没有返回其他对象,表达式会返回这个新对象;

我们通过一个new关键字调用一个函数时(构造器),这个时候this是再调用这个构造器时创建出来的对象,this=创建出来的对象,这个绑定过程也称为new绑定

七、apply call bind 区别

//比如夏夏有个充电宝,它可以使用charge这个充电宝给自己的手机电池phoneBattery任意充电const xiaxia={name:'xiaxia',phoneBattery:70,charge:function (level){this.phoneBattery=level}},xiaxia.charge(100)//但是haha手机没电了,也不想买充电宝,但是它可以借xiaxia的const haha={name:'haha',phoneBattery:40,},xiaxia.charge.call(haha,100)//方便演示apply 的用法,假设充电宝必须冲两次const xiaxia={name:'xiaxia',phoneBattery:70,charge:function (level,newlevel){this.phoneBattery=level+newlevel}}// 如果使用 call 方式xiaxia.charge.call(haha,20,50)// 如果使用 apply 方式xiaxia.charge.apply(haha,[20,50])// bind 方式,其实是借了充电宝,但不是立即使用,而是过一会使用const hahaMethods=xiaxia.charge.apply(haha)haha.hahaMethods(20,50)

八、内置函数的绑定思考

有些时候,我们会调用一些JavaScript的内置函数,或者一些第三方库中的内置函数。这些内置函数会要求我们传入另外一个函数; 我们自己并不会显示的调用这些函数,而且JavaScript内部或者第三方库内部会帮助我们执行;这些函数中的this又是如何绑定的呢?




可以通过上图发现,对于内置函数,他们的this情况,比如对于setTimeout ,他是一个独立执行,默认绑定;看第四张图,它有提示thisArg ,其实是说我们可以自己更改他的this指向,比如第三张图,如果我们传入第二个参数为obj,就把他的this执行为obj了

九、规则优先级

学习了四条规则,接下来开发中我们只需要去查找函数的调用应用了哪条规则即可,但是如果一个函数调用位置应用了多条规则,优先级谁更高呢?

  1. 默认规则的优先级最低
    毫无疑问,默认规则的优先级是最低的,因为存在其他规则时,就会通过其他规则的方式来绑定this
  2. 显示绑定优先级高于隐式绑定 (案例一) (案例二 )
  3. new绑定优先级高于隐式绑定 (案例三)
  4. new绑定优先级高于bind ( 因为new关键字是不能和apply/call 一起使用的)
    new绑定和call、apply是不允许同时使用的,所以不存在谁的优先级更高
    new绑定可以和bind一起使用,new绑定优先级更高
	var obj={name:'obj'foo:function(){console.log(this)}}// 当这个有显示绑定(call)和隐式绑定(obj)时,发现他的this指向为 abc // 说明显示绑定优先级高于隐式绑定obj.foo.call('abc') 
	var obj={name:'obj'foo:function(){console.log(this)}}// 虽然这个指向指向的是 abc,但是并不能体现 显示绑定优先级高于隐式绑定// 因为现在执行的是 obj 的返回的函数,绑定到abc上// 当foo2执行时 与obj其实是没关系的,只是执行的时候引用了而已var foo2 = obj.foo.bind('abc') foo2()function foo(){console.log(this)}var obj={name:'obj'foo:foo.bind('aaa')}obj.foo()  //这样会更明显   指向的是aaa
var obj={name:'obj'foo:function(){console.log(this)}}var f = new obj.foo()  //指向的是foo  说明new的高于隐式

十、说明

不管函数在什么位置声明,在内存中都是在堆内存中单独分配的空间,得到该函数地址的变量都可以对函数进行调用,所以函数中的this指向与调用位置无关,也就是谁调用就指向谁

十一、this 规则之外

1. 忽略显示绑定

apply / call /bind : 当传入 null / undefined 时, 那么这个显示绑定会被忽略,使用默认规则

function foo(){console.log(this)}foo.apply('abc')foo.apply({})foo.apply(null)foo.apply(undefined)

2. ES6箭头函数

箭头函数并不绑定this对象,那么this引用就会从上层作用于中找到对应的this

更多推荐

前端 js 之 this 的绑定规则 04

本文发布于:2023-12-07 06:49:19,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1670452.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:绑定   规则   js

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!