JavaScript this、闭包和箭头函数

news/2024/7/24 12:53:47 标签: javascript, 开发语言, ecmascript

1 this

this是函数内部的特殊对象之一(其他还有arguments、caller、new.target)。

this的 指向或值是不确定的取决于函数的调用方式

在JavaScript中,this的指向有以下几种情况:

  • 作为对象的方法调用
  • 作为普通函数调用
  • 构造器调用
  • Function.prototype.call或Function.prototype.apply调用

此外,this在使用 闭包 和 箭头函数 时的情况我们在后面介绍两者时再谈。


1.作为对象的方法调用

当函数作为对象的方法被调用时,this指向该对象。

javascript">const obj = {
    name: 'obj',
    getName: function () {
        console.log(this.name);
    }
}
obj.getName(); //obj

2.作为普通函数调用

当函数不作为对象的属性被调用时,this指向全局对象,浏览器中是window对象。

javascript">const name = 'window'
const getName = function () {
    console.log(this.name);
}
getName(); //window

3.构造器调用

当函数被new调用时,this指向新创建的对象。

javascript">const Person = function (name) {
    this.name = name;
}
const person = new Person('person');

console.log(person.name); //person

4.Function.prototype.call或Function.prototype.apply调用

当使用call或apply调用时,this指向传入的第一个参数。

javascript">const obj = {
    name: 'obj'
}
const getName = function () {
    console.log(this.name);
}
getName.call(obj); //obj

2 闭包

闭包(closure)是指访问了另一个函数作用域中的变量的函数

创建闭包的最常见的方式就是在一个函数内部创建另一个函数,即嵌套函数

javascript">const a4=4;
var a5=5;
const func1 = function (a3) {
    const a2=2;
    function func2() {
        const a1=1;
        return function func3(){
            console.log(a1+a2+a3+a4+a5);
        }
    };
    return func2();
};
const result=func1(3);
result();

外部函数的活动对象位于内部函数作用域链上的第二个,该作用域链直到全局执行上下文才终止。

活动对象是包含函数的所有局部变量的对象(包括arguments对象),在函数调用时被创建,在函数执行完后被销毁,即只存在于函数执行期间。而在全局上下文中,这叫做变量对象

image-20230829134446401

[[Scopes]]保存了函数的作用域链。

闭包读取函数内部的变量,这使得变量始终保存在内存中,不会在函数调用后被自动清除,这会导致内存泄漏,如果闭包的作用域中有大量的变量,会占用大量的内存。

3 箭头函数

箭头函数是ES6新增的语法,它的this指向是固定的,指向定义时所在的对象,而不是使用时所在的对象

示例:

javascript">window.count=1;
function Counter() {
    this.count = 0;
    console.log(this);
    this.add = function () {
        this.count++;
    }
}
var counter = new Counter();
setTimeout(counter.add, 1000);
setTimeout(function () {
    console.log(counter.count);
    console.log(window.count);
}, 2000);

输出结果为

javascript">Counter {count: 0}
0
2

奇怪,为什么输出结果是0和2,而不是1和1呢?

这是因为setTimeout中的this指向了window,而不是counter,所以counter.add()中的this.count++实际上是window.count++,而不是counter.count++。

解决方法:

1.使用bind绑定this

javascript">setTimeout(counter.add.bind(counter), 1000);

2.使用_this = this保存this

javascript">function Counter() {
    var _this = this;
    this.count = 0;
    console.log(this);
    this.add = function () {
        _this.count++;
    }
}

3.使用箭头函数

javascript">function Counter() {
    this.count = 0;
    console.log(this);
    this.add = () => {
        this.count++;
    }
}

http://www.niftyadmin.cn/n/4999166.html

相关文章

React 配置别名 @ ( js/ts 项目中通过 @craco/craco 配置)

一、简介 在 Vue 项目当中,可以使用 来表示 src/,但在 React 项目中,默认却没有该功能,因此需要进行手动的配置来实现该功能。 别名主要解决的问题:每个页面都使用路径的方式进行引入,这样很麻烦&#xff…

Qt应用开发(基础篇)——向导对话框 QWizard

一、前言 QWizard类继承于QDialog,为有向导界面需求的应用环境提供了一个框架。 对话框窗口 QDialog QWizard向导对话框是一个拥有队列界面的特殊对话框,向导的目的是引导用户一步一步的完成预设的流程。向导常用于软件安装界面向导、硬件线路安装向导、…

【前端】CSS-Flex弹性盒模型布局

目录 一、前言二、Flex布局是什么1、任何一个容器都可以指定为Flex布局2、行内元素也可以使用Flex布局3、Webkit内核的浏览器,必须加上-webkit前缀 三、基本概念四、flex常用的两种属性1、容器属性2、项目属性 五、容器属性1、flex-direction①、定义②、语句1&…

Windows中安装nvm进行Node版本控制与详细使用教程

1.nvm介绍 nvm英文全程也叫node.js version management,是一个nodejs的版本管理工具。nvm和npm都是node.js版本管理工具,但是为了解决node各种不同之间版本存在不兼容的问题,因此可以通过nvm安装和切换不同版本的node。 2.nvm下载 可在点此…

深兰科技再次荣登“全球独角兽企业500强排行榜”

9月1日,由青岛市人民政府、中国人民大学中国民营企业研究中心共同主办,青岛市民营经济发展局、崂山区人民政府、北京隐形独角兽信息科技院承办的,以“塑造产业发展新优势,激发经济发展新活力”为主题的“2023第五届全球独角兽企业…

linux离线安装rdbtools,需先安装python

离线安装python3 下载python包,下载地址:https://www.python.org/ftp/python/ 我选的是https://www.python.org/ftp/python/3.9.0/Python-3.9.0.tgz 将文件上传至linux服务器,解压 tar -xf Python-3.9.0.tgz cd Python-3.9.0 mkdir /usr/l…

van-cascader 异步加载

vant官网 异步加载选项 在使用级联选择时当一次性拿到数据量太大时不仅接口慢而且前端渲染页面也会变慢,用户体验很不好,建议使用异步加载选项, 拿到的接口让后端返回一个是否还有下一级的判断,不然van-cascader判断没有childre…

设计模式-9--迭代器模式(Iterator Pattern)

一、什么是迭代器模式 迭代器模式(Iterator Pattern)是一种行为型设计模式,用于提供一种统一的方式来访问一个聚合对象中的各个元素,而不需要暴露该聚合对象的内部结构。迭代器模式将遍历集合的责任从集合对象中分离出来&#xf…