【JS进阶】执行上下文与执行栈

【Javascript】图解JS中执行上下文与执行栈 今天我们更深入地讲述了类型转换的诸多细节,除了这一讲的简单题解之外,对于“+”号运算也做了一些补充。总地来讲,我们是在讨论 JavaScript 语言所谓“动态类型”的部分,但是动态类型并不仅限于此。也就是说 JavaScript 中并不仅仅是“类型转换”表现出来动态类型的特性。最近还整理一份JavaScript与ES的笔记,一共25个重要的知识点,对每个知识点都进行了讲解和分析。能帮你快速掌握JavaScript与ES的相关知识,提升工作效率。 阅读详情

执行上下文与执行栈

1.执行上下文

简单来说,执行上下文是一种对 JS 代码执行环境的抽象概念,即只要有 JS 代码在运行,那么它就一定是运行在执行上下文中。

执行上下文的类型分为三种:

  • 全局执行上下文:有且只有一个,浏览器中的全局对象就是 window 对象,全局执行上下文中的 this 指向这个全局对象
  • 函数执行上下文:存在无数个,只有在函数被调用的时候才会被创建,每次调用函数都会创建一个新的执行上下文
  • Eval 函数执行上下文:指的是运行在 eval 函数中的代码,很少用而且不建议使用

例:
在这里插入图片描述
在上面的图中,紫色框的部分为全局上下文,而绿色、蓝色和橙色框的部分,则是不同的函数上下文。可以看到,只有全局上下文中的变量、方法,能够被其它任何上下文访问。

但是可以有任意多个函数上下文,每次调用函数创建一个新的上下文,会创建一个私有作用域,函数内部声明的任何变量都不能在当前函数作用域外部直接访问。

所以,执行上下文的特点在于:

  • 单线程。
  • 同步执行。
  • 只有一个全局上下文。
  • 可有无数个函数上下文。 每个函数调用都会创建一个新的 执行上下文,哪怕是递归调用。

2.执行上下文的生命周期

执行上下文的生命周期包括三个阶段:创建阶段 → 执行阶段 → 回收阶段。

  • 创建阶段:这个阶段后面会详细分析。
  • 执行阶段:执行变量赋值、代码执行
  • 回收阶段:执行上下文出栈,等待虚拟机回收。

如图:
在这里插入图片描述

3.执行上下文的创建阶段

每个执行上下文的基本组成如下:
在这里插入图片描述
下面来分别对这几项工作以及关键概念进行介绍。

3.1 生成变量对象
a.变量对象的创建过程
  1. 建立arguments对象。检查当前上下文中的参数,并建立 arguments对象下的属性与属性值之间的对应关系。
  2. 检查当前上下文的函数声明,也就是使用function关键字进行声明的函数。在变量对象中以函数名建立一个属性,属性值为指向该函数所在内存地址的引用。若该函数名的属性已经存在了,则会用新的引用覆盖。
  3. 检查当前上下文中的变量声明,每找到一个变量声明,就在变量对象中以变量名建立一个属性,其值默认为undefined。同时,为了防止与变量同名的函数被修改为undefined,则会直接将其跳过,不修改其属性值。

如图:
在这里插入图片描述
但是有一件需要注意的事:

function foo() { console.log('function foo') }
var foo = 20;

console.log(foo); // 20

// 以上代码中,变量声明的 foo 遇到函数声明的 foo 会跳过,
// 可是为什么最后 foo 的输出结果仍然是被覆盖了呢?
// 那是因为三条规则仅仅适用于变量对象的创建过程,也就是执行上下文的创建过程。
// 而 foo=20 是在执行上下文的执行过程中运行的,输出结果自然会是20。

再来看另一个例子:

console.log(foo); // ƒ foo() { console.log('function foo') }
function foo() { console.log('function foo') }
var foo = 20;

上面例子的执行顺序为:

  1. 首先将所有函数声明放入变量对象中,即:function foo() { console.log('function foo') }
  2. 其次将所有变量声明放入对象变量中,即:var foo。而此时因为已经存在同名的函数foo(),所以会跳过对 foo 变量的 undefined 赋值。
  3. 然后执行代码,即:console.log(foo); foo = 20;

因此,这里输出的 foo 为函数对象,而不是 20。

其中关键的地方在于:始终将var foo = 20视为两个分离的操作,即var foo和foo = 20。从而使得在赋值之前,输出 foo 变量。

b.变量对象与活动对象

变量对象与活动对象其实都是同一个对象,只是处于执行上下文的不同生命周期。不过只有处于函数调用栈栈顶的执行上下文中的变量对象,才会变成活动对象。

看下面这个例子:

function test() {
    console.log(a);
    console.log(foo());

    var a = 1;
    function foo() {
        return 2;
    }
}

test();

在全局作用域中调用test()时,test()的执行上下文开始创建。

在创建过程中,test 方法的执行上下文结构如下:

testEC = {
	// VO 为 Variable Object的缩写,即变量对象
    VO: {
        //注:在浏览器的展示中,函数的参数可能并不是放在arguments对象中
        arguments: {...},  
        foo: <foo reference>,  // 表示 foo 的地址引用
        a: undefined,
        this: Window
    },
    scopeChain: {}
}

而未进入执行阶段之前,变量对象 VO 中的属性均不能访问!但是进入执行阶段后,变量对象转为活动对象,其中的属性均可以被访问,随后开始执行阶段的各项操作。

// 执行阶段
VO ->  AO   // Active Object 活动对象
AO = {
    arguments: {...},
    foo: <foo reference>,
    a: 1,
    this: Window
}

所以,在上面的例子中,代码的执行顺序如下:

function test() {
    //创建阶段
    function foo() {
        return 2;
    }
    var a;
    
    //执行阶段
    console.log(a); // undefined
    console.log(foo()); // 2
    a = 1;
}

test();
c.全局上下文的变量对象

全局上下文有一个特殊的地方,它的变量对象,就是window对象。而这个特殊,在this指向上也同样适用,this也是指向window。

除此之外,全局上下文的生命周期,与程序的生命周期一致,只要程序运行不结束,比如关掉浏览器窗口,全局上下文就会一直存在。其他所有的上下文环境,都能直接访问全局上下文的属性。

3.2 创建作用域链

作用域链本质上是一个指向当前环境与上层环境的一系列变量对象的指针列表(它只引用但不实际包含变量对象),作用域链保证了当前执行环境对符合访问权限的变量和函数的有序访问。

看下面这个例子:

var a = 1;             
function out() {
    var b = 2;
    function inner() {
        var c = 3;
        console.log(a+b+c);
    }
    inner();          
}
out();

首先,代码开始运行时就创建了全局上下文环境,接着运行到out()时创建 out函数的执行上下文,最后运行到inner()时创建 inner函数的执行上下文,我们设定他们的变量对象分别为VO(global),VO(out), VO(inner)。

我们可以直接用一个数组来表示作用域链,数组的第一项scopeChain[0]为作用域链的最前端,而数组的最后一项,为作用域链的最末端。

注意,所有的最末端都为全局变量对象!

  1. 对于全局作用域链:由于它只含全局作用域,没有上级,因此它的作用域链只指向本身的全局变量对象。在查找标识符时只能从本身的全局变量对象中查找。

    此时的全局上下文环境如下:

    // 全局上下文环境
    globalEC = {
        VO: {
            out: <out reference>,  // 表示 out 的地址引用
            a: undefined
        },
        scopeChain: [VO(global)], // 作用域链
    }
    
  2. 对于函数out的作用域链:可以引用函数out本身的变量对象以及全局的变量对象。查找标识符时,先在函数out变量对象中寻找,找不到的话再去上一级全局变量对象查找。

    此时out函数的执行上下文环境如下:

    // out 函数的执行上下文
    outEC = {
        VO: {
            arguments: {...},
            inner: <inner reference>,  // 表示 inner 的地址引用
            b: undefined
        },
        scopeChain: [VO(out), VO(global)], // 作用域链
    }
    

    如图:
    在这里插入图片描述

  3. 对于函数inner的作用域链:可以引用函数inner本身的变量对象和上一级out函数的变量对象以及全局的变量对象。查找标识符时依次从inner,out,全局变量对象中查找。

    此时inner函数的执行上下文环境如下:

    innerEC = {
        VO: {
            arguments: {...},  
            c: undefined,
        },  // 变量对象
        scopeChain: [VO(inner), VO(out), VO(global)], // 作用域链
    }
    

    如图:
    在这里插入图片描述

3.3 确定 this 指向

有关this的指向问题,见…

4.执行上下文栈

在代码开始执行时,首先会产生一个全局执行上下文环境,调用函数时,会产生函数执行上下文环境,函数调用完成后,它的执行上下文环境以及其中的数据都会被销毁,重新回到全局执行环境,网页关闭后全局执行环境也会销毁。其实这是一个压栈出栈的过程,全局上下文环境永远在栈底,而当前正在执行的函数上下文在栈顶。

例如:

var a = 1;             //1.进入全局上下文环境
function out() {
    var b = 2;
    function inner() {
        var c = 3;
        console.log(a+b+c);
    }
    inner();          //3.进入inner函数上下文环境
}
out(); //2.进入out函数上下文环境

↑以上代码的执行会经历以下过程:

  1. 当代码开始执行时就创建全局执行上下文环境,全局上下文入栈。
  2. 全局上下文入栈后,其中的代码开始执行,进行赋值、函数调用等操作,执行到out()时,激活函数out创建自己的执行上下文环境,out函数上下文入栈。
  3. out函数上下文入栈后,其中的代码开始执行,进行赋值、函数调用等操作,执行到inner()时,激活函数inner创建自己的执行上下文环境,inner函数上下文入栈。
  4. inner函数上下文入栈后,其中的代码开始执行,进行赋值、函数调用、打印等操作,由于里面没有可以生成其他执行上下文的需要,所有代码执行完毕后,inner函数上下文出栈。
  5. inner函数上下文出栈,又回到了out函数执行上下文环境,接着执行out函数中后面剩下的代码,由于后面没有可以生成其他执行上下文的需要,所有代码执行完毕后,out函数上下文出栈。
  6. out函数上下文出栈后,又回到了全局执行上下文环境,直到浏览器窗口关闭,全局上下文出栈。

如下图:
在这里插入图片描述

总结

我们可以得到一些结论:

  • 全局上下文在代码开始执行时就创建,只有唯一的一个,永远在栈底,浏览器窗口关闭时出栈。
  • 函数被调用的时候创建上下文环境。
  • 只有栈顶的上下文处于活动状态,其变量对象成为活动对象,并执行其中的代码。
JavaScript进阶1之作用域、执行上下文的顺序执行、可执行代码、执行上下文栈 JavaScript采用静态作用域,于是执行 foo 函数,先从 foo 函数内部查找是否有局部变量 value,如果没有,就根据书写的位置,查找上面一层的代码,也就是 value 等于 1,所以结果会打印 1。如果没有,就从调用函数的作用域,也就是 bar 函数内部查找 value 变量,所以结果会打印 2。但是使用var表达式定义函数add1,只有变量声明提前了,变量初始化代码仍然在原来的位置,没法提前执行。用函数语句创建的函数add2,函数名称和函数体均被提前,在声明它之前就使用它。 阅读详情

相关推荐

JavaScript中的执行上下文和执行栈

通过了解执行上下文的类型和执行栈的工作原理,我们可以更好地理解代码的执行过程,包括变量和函数的作用域以及this关键字的值。每当JavaScript引擎执行一段可执行代码时,都会创建一个新的执行上下文。在JavaScript中,执行上下文和执行栈是理解代码执行过程中的重要概念。当JavaScript引擎执行代码时,会将执行上下文压入执行栈中。执行栈采用先进后出(LIFO)的原则,即最后压入的执行上下文会最先执行并在执行完毕后出栈。执行上下文分为三种类型:全局执行上下文、函数执行上下文和eval执行上下文。

syntax_api860的博客 199

关于执行上下文

一、什么是执行上下文? 简而言之,执行上下文是评估和执行 JavaScript 代码的环境的抽象概念。每当 Javascript 代码在运行的时候,它都是在执行上下文中运行。 二、执行上下文的类型 JavaScript 中有包含三种类型。 全局执行上下文 — 这是默认或者说基础的上下文,任何不在函数内部的代码都在全局上下文中。它会执行两件事:创建一个全局的 window 对象(浏览器的情况下),并且设置 this 的值等于这个全局对象。一个程序中只会有一个全局执行上下文。 函数执行上下文 — 每当

qq_38261819的博客 1304

【Step-By-Step】一周面试题深入解析 / 周刊02

关于【Step-By-Step】Step-By-Step是我于 2019-05-20 开始的一个项目,每个工作日发布一道面试题。每个周末我会仔细阅读大家的答案,整理最一...

cpongo11的博客 215

执行上下文

this执行上下文也叫this执行环境?为什么呢就让我这个英语zz来解释下 context:环境; 上下文 执行环境:执行环境中定义了变量或函数有权访问的其他数据,决定了他们给各自行为,每个执行环境都有一个与之关联的变量对象,环境中定义的所有变量和函数都保持在这个对象中,虽然我们无法访问到这个对象,但是解析器可以在处理数据的时候在后台使用他 ...

qq_39148344的博客 2304

NXP S32K3xx 多次复位(reset)后MCU跑死、崩溃、出错分析

s32k3出现多次复位后死机的情况

HeFlyYoung的博客 9515

VINS-Fusion实战:从零搭建无人机视觉SLAM系统(附ROS配置全流程)

本文详细介绍了如何从零开始为无人机搭建基于VINS-Fusion的视觉SLAM系统。内容涵盖硬件选型(重点推荐双目相机与IMU搭配)、ROS环境配置、传感器标定、核心参数调优以及实际飞行测试与问题排解全流程,旨在帮助开发者实现稳定、精确的无人机自主定位与导航。

wasm7browser的博客 214

执行上下文、执行栈

执行上下文、执行栈

Lyrelion的博客 1806

可信数据空间关键技术和功能架构研究

可信数据空间(TDS)是实现数据安全共享的基础设施,通过数字合约和使用控制技术确保数据跨域流通的可信与安全。其架构包括服务平台和接入连接器,关键技术涵盖访问控制、隐私计算、区块链等。评估重点在于合规性、连接器能力、互联互通及安全体系。核心在于构建规则引擎而非简单数据汇聚,连接器开发比平台建设更重要。当前面临技术成本博弈、跨域身份互认等挑战,需平衡安全、性能与成本,推动数据要素市场发展。

逸尘的专栏 2223

进阶:JS 执行上下文与执行栈,变量对象

点击上方“IT平头哥联盟”,选择“置顶或者星标”与你一起成长~作者:以乐之名https://segmentfault.com/a/1190000017890535写在开篇已经不敢自称前端小...

画漫画的程序员∙苏南 176

智能音箱麦克风阵列实战:Python实现宽带GSC波束形成(附完整代码)

本文从工程实战角度,详细介绍了如何在智能音箱中利用Python实现宽带GSC波束形成算法。文章深入解析了广义旁瓣消除器(GSC)的核心架构,包括固定波束形成、阻塞矩阵与自适应滤波路径,并提供了完整的仿真代码、关键参数(如LMS步长)调优方法,以及面向嵌入式部署的计算优化与移植考量,旨在帮助开发者构建在真实噪声环境下高效工作的语音增强系统。

opencv7vision的博客 342

(保姆式教程:从下数据到画图)python如何利用EOF分析SSTA海温异常现象并画图

保姆式教程,教你如何利用python分析1979-2004年的太平洋地区的海温异常SSTA,并且绘制出空间模态和时间序列的图片。

shayuxing的博客 2万+

函数调用时的临时对象_进阶:JS 执行上下文与执行栈,变量对象

点击上方“IT平头哥联盟”,选择“置顶或者星标”与你一起成长~作者:以乐之名https://segmentfault.com/a/1190000017890535写在开篇已经不敢自称前端小白,曾经吹过的牛逼总要一点点去实现。正如前领导说的,自己喝酒吹过的牛皮,跪着都得含着泪去实现。那么没有年终完美总结,来个新年莽撞开始可好。进击巨人系列开篇,不忘初心,砥砺前行。理解执行上下文执行上下文(...

weixin_39559469的博客 126

ClearML中文文档实战:从安装到第一个实验的保姆级教程

本文提供ClearML从零开始的实战指南,涵盖核心组件理解、Python SDK安装、服务器配置及首个自动化实验的完整流程。通过改造PyTorch训练脚本的实例,详细演示了如何利用ClearML自动记录实验参数、指标与模型,实现机器学习实验的可复现性与高效管理,并简要介绍了进阶的自动化工作流。

weixin_29216049的博客 398

js函数、js对象的这些点你真的懂吗?_js textcolor(1)

: 显式原型属性 : 隐式原型属性函数的prototype: 定义函数时被自动赋值, 值默认为{}, 即用为原型对象 实例对象的__proto__: 在创建实例对象时被自动添加, 并赋值为构造函数的prototype值 原型对象即为当前实例对象的父对象所有的实例对象都有__proto__属性, 它指向的就是原型对象 这样通过__proto__属性就形成了一个链的结构---->原型链 当查找对象内部的属性/方法时, js引擎自动沿着这个原型链查找 当给对象属性赋值时不会使用原型链, 而只是在当前对象中进行操作

2401_87555514的博客 1138

别光看Demo了!用UE5 Lyra框架快速搭建你的多人对战游戏原型(含完整配置流程)

本文详细介绍了如何利用UE5 Lyra框架快速搭建多人对战游戏原型,包含完整的配置流程和实战案例。Lyra作为可直接二次开发的游戏模板,内置了GAS技能系统、Enhanced Input输入控制等核心功能,大幅缩短开发周期。通过替换角色模型、调整武器数值和配置新地图规则,开发者可在48小时内完成科幻团队竞技游戏原型的搭建。

weixin_28717411的博客 457

ICC2: pin shape不在track上引起的drc如何解决?

我正在「拾陆楼」和朋友们讨论有趣的话题,你⼀起来吧?

m0_61544122的博客 434

js函数、js对象的这些点你真的懂吗?_js textcolor

创建一个Function的实例对象给对象添加prototype属性, 其值为object空对象(原型对象)给原型对象添加constructor属性, 指向当前函数对象✨原创不易还希望各位大佬支持一下\textcolor{blue}{原创不易,还希望各位大佬支持一下}原创不易,还希望各位大佬支持一下。

2401_87555332的博客 804

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

2024年C C++最全js函数、js对象的这些点你真的懂吗?_js textcolor,2024年最新2024大厂C C++社招面试题

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新如果你需要这些资料,可以戳这里获取 : 显式原型属性 : 隐式原型属性函数的prototype: 定义函数时被自动赋值, 值默认为{}, 即用为原型对象 实例对象的__proto__: 在创建实例对象时被自动添加, 并赋值为构造函数的prototyp

2401_84976527的博客 852

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

深度解析 JavaScript:赋予 Web 灵魂的“全栈语言”

JavaScript 绝非一门简单的脚本语言,它的底层蕴含着深邃的计算机科学与语言哲学。从基础的语法糖到复杂的内存管理,从浏览器的单线程约束到 Node.js 的全栈拓展,掌握 JavaScript 就是掌握了一把开启现代数字世界大门的万能钥匙。对于开发者而言,真正的进阶始于对每一行代码背后运行机制的敬畏与追问。保持好奇,持续探索,方能在 JavaScript 的星辰大海中乘风破浪。

2602_95057108的博客 173

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

【2021 第二期】简而不单,单而不简的执行上下文

大伙儿好~,我是小鹿,公众号:「小鹿动画学编程」 原创作者。 2021 第二期。 想必大伙儿看到本期的标题很有疑惑,为什么是简而不单,单而不简的执行上下文呢?我来先解释一下,对于 javaScript 上一些抽象的概念,我们可以把它讲的非常复杂,也可以把它讲的极其简单,更可以把它讲的既复杂又简单。 嗯~ 最近重新回顾了这些抽象的概念,发现有些概念之前并不能很好的融会贯通,所以把这些相对抽象难以理解的概念作为几期文章来写。 不妨打开在谷歌搜「执行上下文」关键词,几篇相对排名靠前的优秀文章回呈现出来。 .

小鹿动画学编程 616

「JavaScript进阶」一文吃透执行上下文和执行栈

前言 学习 JavaScript ,理解其内部执行逻辑是很重要的,今天这篇文章就来讲讲 JavaScript 执行上下文和执行栈。 JavaScript 系列文章:JavaScript进阶 什么是执行上下文和执行栈? 执行上下文 执行上下文就是当前 JavaScript 代码被解析和执行时所在环境的抽象概念。 有全局执行上下文、函数执行上下文、Eval 函数执行上下文三种执行上下文类型。 类型 定义 全局执行上下文 Global code - 首次运行程序时创建的默认环境 函数执

荣荣 365

js总结篇下(看完你就学会整个js——进阶篇)

1.数据类型 # 数据类型 ## 基本(值)类型 * string: 任意字符串 * number: 任意数字 * boolean: true/false * undefined: undefined * null: null ## 对象类型 * object: 基本对象类型 * function: 特殊对象, 可以执行 * array: 特殊对象, 可通过下标执行, 内部有序 判断数据类型 * typeof 返回数据类型的字符串表达 可以判断数值, 字符串, undefined

Sakura1921的博客 317

JavaScript 作用域与作用域链:变量访问的底层规则

本文解析 JavaScript 作用域与作用域链,及与执行上下文的关联。作用域分全局、函数、块级,是变量访问范围(静态);作用域链是变量查找路径。二者与动态的执行上下文配合,共同支撑代码运行,影响变量访问规则。

ik_makabaka的博客 947

前端工程师成长路径:从HTML新手到全栈实践者

Web前端开发是一门融合界面构建、交互逻辑与系统思维的工程实践。其核心原理在于理解浏览器渲染机制、JavaScript执行上下文及前后端协同模型;技术价值体现在将抽象需求转化为可维护、高性能、跨终端的用户界面;典型应用场景覆盖企业官网、H5营销页、移动Web App及中后台系统。在真实项目压力下,开发者需经历HTML/CSS基础夯实、原生JS底层认知、组件化造轮子、服务端能力拓展、移动端深度适配等关键阶段——这些并非线性进阶,而是能力维度的螺旋上升。本文以一位普通前端工程师六年真实成长轨迹为样本,拆解可验证

diaozhiwa5526的博客 395

理解Javascript中的执行上下文和执行栈

前言 本文3356字,阅读大约需要9分钟。 总括: 本文深入的讲解了Javascript中的执行上下文和执行栈。 原文地址:Understanding Execution Context and Execution Stack in Javascript 公众号:「前端进阶学习」,回复「666」,获取一揽子前端技术书籍 流水在碰到底处时才会释放活力。 正文 如果你是或者想成为一名Java...

前端小渣 834

JavaScript进阶之执行上下文和执行栈

js引擎的执行过程 执行上下文和执行栈属于js引擎的执行过程的预编译阶段。 执行上下文(Execution Context) 执行上下文是当前 JavaScript 代码被解析和执行时所在环境的抽象概念。可以理解为当执行代码时做的准备工作。 执行上下文按照运行环境被分成三类: 全局执行上下文(JS代码加载完毕后,进入代码预编译即进入全局环境) ...

aoqiaozao4482的博客 184
上一篇: 【JS基础】DOM和BOM
下一篇: 【JS进阶】this指向
cannotbecounted
博客等级 码龄7年 101粉丝 59原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值