• this指针


    this绑定规则有5种

    1、默认绑定

    自然调用,指向window

    1. var foo = 123;
    2. function print(){
    3. this.foo = 234;
    4. console.log(this); // window
    5. console.log(foo); // 234
    6. }
    7. print();

    1、let/const定义的变量存在暂时性死区,而且不会挂载到window对象上,因此print中是无法获取到a和b的。

    2、对象内执行

     foo虽然在objbar函数中,但foo函数仍然是独立运行的,foo中的this依旧指向window对象。

    3、函数内执行

    与2类似

    4、自执行函数

    this指向window

    2、隐式绑定

    函数的调用是在某个对象上触发的,即调用位置存在上下文对象,通俗点说就是**XXX.func()**这种调用模式。

    此时functhis指向XXX,但如果存在链式调用,例如XXX.YYY.ZZZ.func,记住一个原则:this永远指向最后调用它的那个对象

    1. var a = 1;
    2. function foo() {
    3. console.log(this.a);
    4. }
    5. // 对象简写,等同于 {a:2, foo: foo}
    6. var obj = {a: 2, foo}
    7. foo();
    8. obj.foo();

    3、隐式绑定丢失(丢失后会默认绑定)

            1、使用另一个变量作为函数别名

    1. a = 1
    2. var obj = {
    3. a: 2,
    4. foo() {
    5. console.log(this.a)
    6. }
    7. }
    8. var foo = obj.foo;
    9. obj.foo();
    10. foo();
    11. 2
    12. 1

    obj.foo赋值给foo,就是将foo也指向了obj.foo所指向的堆内存,此后再执行foo,相当于直接执行的堆内存的函数,与obj无关 

    只要fn前面什么都没有,肯定不是隐式绑定。 

            2、将函数作为参数传递时会被隐式赋值

    1. function foo() {
    2. console.log(this.a)
    3. }
    4. function doFoo(fn) {
    5. console.log(this)
    6. fn()
    7. }
    8. var obj = { a: 1, foo }
    9. var a = 2
    10. doFoo(obj.foo)
    11. Window {…}
    12. 2

    obj.foo作为实参,在预编译时将其值赋值给形参fn,是将obj.foo指向的地址赋给了fn,此后fn执行不会与obj产生任何关系。fn为默认绑定。 

       3、回调函数使得隐士绑定失效,直接指向this

    1. var name='zcxiaobao';
    2. function introduce(){
    3. console.log('Hello,My name is ', this.name);
    4. }
    5. const Tom = {
    6. name: 'TOM',
    7. introduce: function(){
    8. setTimeout(function(){
    9. console.log(this)
    10. console.log('Hello, My name is ',this.name);
    11. })
    12. }
    13. }
    14. const Mary = {
    15. name: 'Mary',
    16. introduce
    17. }
    18. const Lisa = {
    19. name: 'Lisa',
    20. introduce
    21. }
    22. Tom.introduce();
    23. setTimeout(Mary.introduce, 100);
    24. setTimeout(function(){
    25. Lisa.introduce();
    26. },200);
    27. Window {…}
    28. Hello, My name is zcxiaobao
    29. Hello,My name is zcxiaobao
    30. Hello,My name is Lisa
    • Tom.introduce(执行: console位于setTimeout的回调函数中,回调函数的this指向window
    • Mary.introduce直接作为setTimeout的函数参数(类似题目题目3.3),会发生隐式绑定丢失,this为默认绑定
    • Lisa.introduce执行虽然位于setTimeout的回调函数中,但保持xxx.fn模式,this为隐式绑定。

    4、显式绑定

    通过call()、apply()、bind()等方法,强行改变this指向。

    • call()和apply()函数会立即执行
    • bind()函数会返回新函数,不会立即执行函数
    • call()和apply()的区别在于call接受若干个参数,apply接受数组。

    5、new绑定

    使用new来构建函数,会执行如下四部操作:

    1. 创建一个空的简单JavaScript对象(即{});
    2. 为步骤1新创建的对象添加属性__proto__,将该属性链接至构造函数的原型对象 ;
    3. 将步骤1新创建的对象作为this的上下文 ;
    4. 如果该函数没有返回对象,则返回this
    1. function User(name, age) {
    2. this.name = name;
    3. this.age = age;
    4. }
    5. var name = 'Tom';
    6. var age = 18;
    7. var zc = new User('zc', 24);
    8. console.log(zc.name)
    9. zc

    6、箭头函数绑定

    箭头函数没有自己的this,它的this指向外层作用域的this,且指向函数定义时的this而非执行时。

    1. this指向外层作用域的this: 箭头函数没有this绑定,但它可以通过作用域链查到外层作用域的this
    2. 指向函数定义时的this而非执行时: JavaScript是静态作用域,就是函数定义之后,作用域就定死了,跟它执行时的地方无关。

    1. name = 'tom'
    2. const obj = {
    3. name: 'zc',
    4. intro: () => {
    5. console.log('My name is ' + this.name)
    6. }
    7. }
    8. obj.intro()
    9. My name is tom

  • 相关阅读:
    【SpringCloud】04 网关springcloud gateway
    mybatis中使用<choose><when><otherwise>标签实现根据条件查询不同sql
    Docker 可视化面板 ——Portainer
    【学习】python装饰器
    【LeetCode】43. 字符串相乘
    Java的方法重载、变量和值传递
    SHOW ME THE CODE - 面向对象程序设计之 - 单一职责原则
    Android Studio设置
    Python初级教程-廖雪峰Python教程
    行为设计模式之状态模式
  • 原文地址:https://blog.csdn.net/qq_46222031/article/details/126407519