IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> 读《不一样的javascript》之this问题 -> 正文阅读

[JavaScript知识库]读《不一样的javascript》之this问题

《不一样的javascript》系列

  1. this指向问题


前言

this指向一直以来都是困扰我的问题,看完本书后有一些明悟,记录一下


提示:以下是本篇文章正文内容,下面案例可供参考

一、what is this?

MDN描述:

在绝大多数情况下,函数的调用方式决定了 this 的值(运行时绑定)

当前执行上下文(global、function 或 eval)的一个属性,在非严格模式下,总是指向一个对象,在严格模式下可以是任意值。

执行上下文可以了解为执行环境,可以当成一个对象。这个系列以后写。
那它是指向函数本身吗,还是指向函数作用域呢?还是其他?

二、绑定

1. 绑定时间与位置

绑定时间

函数调用时绑定

绑定位置

  1. 取决于函数在哪里调用
  2. this永远不指向函数作用域,
    因为函数作用域是一套变量标识符查找规则,也可以看作一个对象,
    但是作用域无法通过代码访问,它存在js引擎内部
    这个和 [[pototype]]属性一样你是访问不到的

2. 四大绑定规则

2.1 默认绑定

  1. 独立调用函数或者call,apply绑定null 和undefined
  2. 分为严格模式和非严格模式
  3. 非严格模式绑定全局对象
 		function foo() {
            console.log(this.a);
            function bar() {
                console.log(b);
            }
            bar() //4
        }
        var a = 3;
        var b = 4;
        foo(); //3
  1. 严格模式 绑定undefined
        function foo() {
            'use strict'
            console.log(this.a)
        }
        var a = 3;
        foo(); //Cannot read properties of undefined (reading 'a')

2.2 隐式绑定

  1. 调用位置有上下文对象,或者这么说:被某个对象包含或者拥有(对象.调用函数)
        function foo() {
            console.log(this.a)
        }
        var obj = {
            foo: foo,
            a: 2
        }
        var a = 3;
        obj.foo(); //2
  1. 隐式丢失:丢失绑定对象,采用了默认绑定。其实就是暴露了函数使他变成独立执行。
  • 第一种:
    函数别名引用:
function foo() {
            console.log(this.a)
        }
        var obj = {
            foo: foo,
            a: 2
        }
        var a = '233'
        var bar = obj.foo
        bar(); //233

其实这里obj.foo 指向引用了foo的引用,bar()相当于默认绑定了。

  • 函数作为参数传参丢失绑定
		function foo() {
            console.log(this.a)
        }

        function doFoo(fn) {
            fn()
        }
        var obj = {
            foo: foo,
            a: 2
        }
        var a = '2333'
        doFoo(obj.foo);//2333

2.3 显示绑定

就是通过call apply 函数改变this 指向
  • 硬绑定:通过辅助函数包裹函数 接收参数返回值
		function foo(something) {
            console.log(this.a, something);
            return this.a + something;
        }

        function bind(fn, obj) {
            return function() {
                return fn.apply(obj, arguments)
            }
        }
        var obj = {
            a: 2
        }
        var a = 3;
        var bar = bind(foo, obj);
        var res = bar(3)//2,3
        console.log(res);//5

这和原生bind很像了。

2.4. new 绑定

new 构造函数 它会做什么呢

  • 创建一个全新对象
  • 新对象连接__proto__
  • 新对象绑定到函数调用this
  • 如果函数没有其他对象,返回新对象

3. 优先级

new>显示绑定>隐式绑定>默认绑定

4 .箭头函数

根据外层作用域来决定this,这里是书的描述(存疑,为什么不是外层调用函数的执行上下文的this)
我的理解是箭头函数绑定在外层函数调用时绑定在外层函数的this,一旦外层函数调用的this不同箭头函数则不同,可以参考下面题二

三、做道题

  var myObject = {
            foo: 'bar',
            func: function() {
                var self = this
                console.log(this.foo);
                console.log(self.foo);
                (function() {
                    console.log(this.foo);
                    console.log(self.foo);
                }())
            }
        }
        var foo = 'window'
        myObject.func() //bar bar window bar

        var name = 'window'

        function Person(name) {
            this.name = name
            this.obj = {
                name: 'obj',
                foo1: function() {
                    return function() {
                        console.log(this.name)
                    }
                },
                foo2: function() {
                    return () => {
                        console.log(this.name)
                    }
                }
            }
        }
        var person1 = new Person('person1')
        var person2 = new Person('person2')

        person1.obj.foo1()() 
        //window 相当于person1.obj.foo1()返回一个匿名函数fn fn() 默认绑定
        person1.obj.foo1.call(person2)() 
        //window foo1绑定的是person 但返回还是一个匿名函数fn
        person1.obj.foo1().call(person2) 
        //person2 相当于返回匿名函数fn.call(person2)

        person1.obj.foo2()() 
        //obj 箭头函数绑定的是外层作用域的this 也就是foo2 的this foo2的this在obj的隐式绑定上
        person1.obj.foo2.call(person2)() 
        //foo2的this显式绑定在person2上
        person1.obj.foo2().call(person2)
         //obj foo2的this 不变
  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-11-14 21:32:45  更:2021-11-14 21:33:11 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/10 7:05:03-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码