JavaScript 的继承方式及优缺点

JS篇(010)-JavaScript 继承的方式和优缺点 答案:六种方式 * 一、原型链继承 + 缺点: + 1. 引用类型的属性被所有实例共享 + 2. 在创建 Child 的实例时,不能向 Parent 传参 * 二、借用构造函数(经典继承) + 优点: + 1. 避免了引用类型的属性被所有实例共享 + 2. 可以在 Child 中向 Parent 传参 + 缺点: + 1. 方法都在构造函数中定义,每次创建实例都会创建一遍方法。 * 三、组合继承 + 优点: + 1. 融合原型链继承和构造函数的优点,是 ... 阅读详情

在这里插入图片描述


阅读原文


前言

JavaScript 原本不是纯粹的 “OOP” 语言,因为在 ES5 规范中没有类的概念,在 ES6 中才正式加入了 class 的编程方式,在 ES6 之前,也都是使用面向对象的编程方式,当然是 JavaScript 独有的面向对象编程,而且这种编程方式是建立在 JavaScript 独特的原型链的基础之上的,我们本篇就将对原型链以及面向对象编程最常用到的继承进行刨析。


继承简介

在 JavaScript 的中的面向对象编程,继承是给构造函数之间建立关系非常重要的方式,根据 JavaScript 原型链的特点,其实继承就是更改原本默认的原型链,形成新的原型链的过程。


复制的方式进行继承

复制的方式进行继承指定是对象与对象间的浅复制和深复制,这种方式到底算不算继承的一种备受争议,我们也把它放在我们的内容中,当作一个 “不正经” 的继承。

1、浅复制

创建一个浅复制的函数,第一个参数为复制的源对象,第二个参数为目标对象。

// 浅复制方法
function extend(p, c = {}) {
    for (let k in p) {
        c[k] = p[k];
    }
    return c;
}

// 源对象
let parent = {
    a: 1,
    b: function() {
        console.log(1);
    }
};

// 目标对象
let child = {
    c: 2
};

// 执行
extend(parent, child);
console.log(child); // { c: 2, a: 1, b: ƒ }

上面的 extend 方法在 ES6 标准中可以直接使用 Object.assign 方法所替代。

2、深复制

可以组合使用 JSON.stringify 和 JSON.parse 来实现,但是有局限性,不能处理函数和正则类型,所以我们自己实现一个方法,参数与浅复制相同。

// 深复制方法
function extendDeeply(p, c = {}) {
    for (let k in p) {
        if (typeof p[k] === "object" && typeof p[k] !== null) {
            c[k] = p[k] instanceof Array ? [] : {};
            extendDeeply(p[k], c[k]);
        } else {
            c[k] = p[k];
        }
    }
    return c;
}

// 源对象
let parent = {
    a: {
        b: 1
    },
    b: [1, 2, 3],
    c: 1,
    d: function() {
        console.log(1);
    }
};

// 执行
let child = extendDeeply(parent);

console.log(child); // { a: {b: 1}, b: [1, 2, 3], c: 1, d: ƒ }
console.log(child.a === parent.a); // false
console.log(child.b === parent.b); // false
console.log(child.d === parent.d); // true

在上面可以看出复制后的新对象 child 的 a 属性和 b 的引用是独立的,与 parent 的 a 和 b 毫无关系,实现了深复制,但是 extendDeeply 函数并没有对函数类型做处理,因为函数内部执行相同的逻辑指向不同引用是浪费内存的。


原型替换

原型替换是继承当中最简单也是最直接的方式,即直接让父类和子类共用同一个原型对象,一般有两种实现方式。

// 原型替换
// 父类
function Parent() {}

// 子类
function Child() {}

// 简单粗暴的写法
Child.prototype = Parent.prototype;

// 另一种种实现方式
Object.setPrototypeOf(Child.prototype, Parent.prototype);

上面这种方式 Child 的原型被替换掉,Child 的实例可以直接调用 Parent 原型上的方法,实现了对父类原型方法的继承。

上面第二种方式使用了 Object.setPrototypeOf 方法,该方法是将传入第一个参数对象的原型设置为第二个参数传入的对象,所以我们第一个参数传入的是 Child 的原型,将 Child 原型的原型设置成了 Parent 的原型,使父、子类原型链产生关联,Child 的实例继承了 Parent 原型上的方法,在 NodeJS 中的内置模块 util 中用来实现继承的方法 inherits,底层就是使用这种方式实现的。

缺点:父类的实例也同样可以调用子类的原型方法,我们希望继承是单向的,否则无法区分父、子类关系,这种方式一般是不可取的。


原型链继承

原型链继承的思路是子类的原型的原型是父类的原型,形成了一条原型链,建立子类与父类原型的关系。

// 原型链继承
// 父类
function Parent(name) {
    this.name = name;
    this.hobby = ["basketball", "football"];
}

// 子类
function Child() {}

// 继承
Child.prototype = new Parent();

上面用 Parent 的实例替换了 Child 自己的原型,由于父类的实例原型直接指向 Parent.prototype,所以也使父、子类原型链产生关联,子类实例继承了父类原型的方法。

缺点 1:只能继承父类原型上的方法,却无法继承父类上的属性。
缺点 2:由于原型对象被替换,原本原型的 constructor 属性丢失。
缺点 3:如果父类的构造函数中有属性,则创建的父类的实例也会有这个属性,用这个实例的作为子类的原型,这个属性就变成了所有子类实例所共有的,这个属性可能是多余的,并不是我们想要的,也可能我们希望它不是共有的,而是每个实例自己的。


构造函数继承

构造函数继承又被国内的开发者叫做 “经典继承”。

// 构造函数继承
// 父类
function Parent(name) {
    this.name = name;
}

// 子类
function Child() {
    Parent.apply(this, arguments);
}

let c = new Child("Panda");
console.log(c); // { name: 'Panda' }

构造函数继承的原理就是在创建 Child 实例的时候执行了 Child 构造函数,并借用 call 或 apply 在内部执行了父类 Parent,并把父类的属性创建给了 this,即子类的实例,解决了原型链继承不能继承父类属性的缺点。

缺点:子类的实例只能继承父类的属性,却不能继承父类的原型的方法。


构造函数原型链组合继承

为了使子类既能继承父类原型的方法,又能继承父类的属性到自己的实例上,就有了这种组合使用的方式。

// 构造函数原型链组合继承
// 父类
function Parent(name) {
    this.name = name;
}

Parent.prototype.sayName = function() {
    console.log(this.name);
};

// 子类
function Child() {
    Parent.apply(this, arguments);
}

// 继承
Child.prototype = new Parent();

let c = new Child("Panda");
console.log(c); // { name: 'Panda' }
c.sayName(); // Panda

这种继承看似完美,但是之前 constructor 丢失和子类原型上多余共有属性的问题还是没有解决,在这基础上又产生了新的问题。

缺点:父类被执行了两次,在使用 call 或 apply 继承属性时执行一次,在创建实例替换子类原型时又被执行了一次。


原型式继承

原型式继承主要用来解决用父类的实例替换子类的原型时共有属性的问题,以及父类构造函数执行两次的问题,也就是说通过原型式继承能保证子类的原型是 “干净的”,而保证只在继承父类的属性时执行一次父类。

// 原型式继承
// 父类
function Parent(name) {
    this.name = name;
}

// 子类
function Child() {
    Parent.apply(this, arguments);
}

// 继承函数
function create(obj) {
    function F() {}
    F.prototype = obj;
    return new F();
}

// 继承
Child.prototype = create(Parent.prototype);

let c = new Child("Panda");
console.log(c); // { name: 'Panda' }

原型式继承其实是借助了一个中间的构造函数,将中间构造函数 F 的 prototype 替换成了父类的原型,并创建了一个 F 的实例返回,这个实例是不具备任何属性的(干净的),用这个实例替换子类的原型,因为这个实例的原型指向 F 的原型,F 的原型同时又是父类的原型对象,所以子类实例继承了父类原型的方法,父类只在创建子类实例的时候执行了一次,省去了创建父类实例的过程。

原型式继承在 ES5 标准中被封装成了一个专门的方法 Object.create,该方法的第一个参数与上面 create 函数的参数相同,即要作为原型的对象,第二个参数则可以传递一个对象,会把对象上的属性添加到这个原型上,一般第二个参数用来弥补 constructor 的丢失问题,这个方法不兼容 IE 低版本浏览器。


寄生式继承

寄生式继承就是用来解决子统一为原型式继承中返回的对象统一添加方法的问题,只是在原型式继承的基础上做了小小的修改。

// 寄生式继承
// 父类
function Parent(name) {
    this.name = name;
}

// 子类
function Child() {
    Parent.apply(this, arguments);
}

// 继承函数
function create(obj) {
    function F() {}
    F.prototype = obj;
    return new F();
}

// 将子类方法私有化函数
function creatFunction(obj) {
    // 调用继承函数
    let clone = create(obj);
    // 子类原型方法(多个)
    clone.sayName = function() {};
    clone.sayHello = function() {};

    return clone;
}

// 继承
Child.prototype = creatFunction(Parent.prototype);

缺点:因为寄生式继承最后返回的是一个对象,如果用一个变量直接来接收它,那相当于添加的所有方法都变成这个对象自身的了,如果创建了多个这样的对象,无法实现相同方法的复用。


寄生组合式继承

// 寄生组合式继承
// 父类
function P(name, age) {
    this.name = name;
    this.age = age;
}

P.prototype.headCount = 1;
P.prototype.eat = function() {
    console.log("eating...");
};

// 子类
function C(name, age) {
    P.apply(this, arguments);
}

// 寄生组合式继承方法
function myCreate(Child, Parent) {
    function F() {}
    F.prototype = Parent.prototype;
    Child.prototype = new F();
    Child.prototype.constructor = Child;
    // 让 Child 子类的静态属性 super 和 base 指向父类的原型
    Child.super = Child.base = Parent.prototype;
}

// 调用方法实现继承
myCreate(C, P);

// 向子类原型添加属性方法,因为子类构造函数的原型被替换,所以属性方法仍然在替换之后
C.prototype.language = "javascript";
C.prototype.work = function() {
    console.log("writing code use " + this.language);
};
C.work = function() {
    this.super.eat();
};

// 验证继承是否成功
let f = new C("nihao", 16);
f.work();
C.work();

// writing code use javascript
// eating...

寄生组合式继承基本规避了其他继承的大部分缺点,应该比较强大了,也是平时使用最多的一种继承,其中 Child.super 方法的作用是为了在调用子类静态属性的时候可以调用父类的原型方法。

缺点:子类没有继承父类的静态方法。


class…extends… 继承

在 ES6 规范中有了类的概念,使继承变得容易,在规避上面缺点的完成继承的同时,又在继承时继承了父类的静态属性。

// class...extends... 继承
// 父类
class P {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }
    sayName() {
        console.log(this.name);
    }
    static sayHi() {
        console.log("Hello");
    }
}

// 子类继承父类
class C extends P {
    constructor(name, age) {
        supper(name, age); // 继承父类的属性
    }
    sayHello() {
        P.sayHi();
    }
    static sayHello() {
        super.sayHi();
    }
}

let c = new C("jack", 18);

c.sayName(); // jack
c.sayHello(); // Hello
C.sayHi(); // Hello
C.sayHello(); // Hello

在子类的 constructor 中调用 supper 可以实现对父类属性的继承,父类的原型方法和静态方法直接会被子类继承,在子类的原型方法中使用父类的原型方法只需使用 this 或 supper 调用即可,此时 this 指向子类的实例,如果在子类的静态方法中使用 this 或 supper 调用父类的静态方法,此时 this 指向子类本身。


vllm运行过程中出现cuda out of memory 将长序列分解为多个小块,每个块分别处理。这样可以减少单次 Prefill 的计算量和显存占用,从而优化 TTFT 和显存使用效率。考虑使用 CPU 卸载(如 --cpu-offload-gb),将部分缓存卸载到 CPU 内存中,扩展 GPU 的虚拟内存。在大语言模型中,当输入序列很长(例如超过 1024 个 Token)时,Prefill 阶段的计算量会非常大。最后增加了enable-chunked-prefill参数和max_num_batched_tokens解决了问题。参数来进一步优化性能。 阅读详情

相关推荐

【技术实践指南】Python解析FactSet Revere供应链数据:构建企业级断裂与重构监测指标

本文提供了一份企业级Python实践指南,详细解析如何利用FactSet Revere供应链数据库,构建供应链断裂与重构监测指标。内容涵盖数据清洗、关系对筛选、时间序列处理及核心指标(断裂、恢复、转移)的工程化实现,旨在帮助数据工程师与分析师搭建自动化、可解释的供应链风险监控系统。

weixin_29051811的博客 932

JS继承的多种方式

前言JavaScript 原本不是纯粹的 “OOP” 语言,因为在 ES5 规范中没有类的概念,在 ES6 中才正式加入了 class 的编程方式,在 ES6 之前,也都是使用面向对象的编程方式,当然是 JavaScript 独有的面向对象编程,而且这种编程方式是建立在 JavaScript 独特的原型链的基础之上的,我们本篇就将对原型链以及面向对象编程最常用到的继承进行刨析。继承简介在 Java...

weixin_33919950的博客 153

基于Python的微信聊天记录分析——数据获取

本篇为“基于Python的微信聊天记录分析”第一篇,主要涉及数据获取,包括Python环境配置、WeChatMsg项目配置和运行、获取聊天记录等内容,流程简单、比较基础,后续这个系列会涉及基于Python的数据处理、统计分析、NLP技术等内容。希望和大家多多交流,共同进步!

Henryli1202的博客 1万+

js实现继承的三种方式

js实现继承的三种方式 1.借用构造函数 //父类 function Parent() { this.arr = [1,2,3]; } //子类 function Child(name) { Parent.call(this);//将父类构造函数的this指向子类 this.name = name; } Parent.protorype.show = function() {}/...

qq_43204698的博客 442

保姆级教程:SAP ABAPer如何为VF01销售发票和MIRO发票校验配置凭证替代(含AC_DOCUMENT BADI完整代码示例)

本文详细解析了SAP ABAP中通过AC_DOCUMENT BADI实现VF01销售发票和MIRO发票校验的凭证替代技术。从技术选型到BADI实施步骤,再到核心逻辑代码示例,为ABAP开发者提供了一套完整的解决方案,帮助应对财务部门复杂的业务需求。

weixin_30421809的博客 351

STM32外部中断与事件机制深度解析:从硬件触发到软件响应

本文深入解析STM32外部中断与事件机制,从硬件触发到软件响应的完整流程。通过对比中断和事件的应用场景、响应速度及配置方法,帮助开发者优化嵌入式系统设计,特别适合需要低功耗或高实时性的项目。

weixin_29175469的博客 409

谈谈javascript中的面向对象和继承

面向对象语言都有一个标志,那就是它们都有类的概念,而通过类可以创建任意多个具有相同属性和方法的对象。

一点一滴滴 813

二次规划问题(qp)和序列二次规划问题(sqp)的简单理解

当二次规划的约束为非线性约束时,通常会采用sqp进行求解,用连续求解qp的方法来得到非线性约束条件下的最优解,上述的qpoases和osqp均无法直接求解非线性约束问题,所以如果使用这两个库的话,注意,sqp是结果,而不是原因,只有在非线性约束的情况下才会考虑sqp求解,如果问题本身就是线性约束,则直接用qp解就行。对于工程师而言,我们在编写代码的时候,并不关心二次规划问题的求解细节,所以一般是把二次规划问题建立好后,直接调用三方库进行求解。因为约束为非线性约束,所以先将约束进行线性化,约束原方程为。

zmhzmhzm的博客 1万+

js(javascript)实现继承的6种方式以及优缺点详解

js继承的6种方式 想要继承,就必须要提供个父类(继承谁,提供继承的属性)      一、原型链继承      重点:让新实例的原型等于父类的实例。     特点:1、实例可继承的属性有:实例的构造函数的属性,父类构造函数属性,父类原型的属性。(新实例不会继承父类实例的属性!)     缺点:1、新实例无法向父类构造函数传参。        2、继承单一。        3、所有新实例都会共享父类实例的属性。(原型上的属性是共享的,一个实例修改了原型属性,另一个实例的原型属性也会被修改!)      二、

m0_53592673的博客 2205

MATLAB 基于 Baker 映射和 Logistic 混沌序列的图像加解密实现

图像加密是信息安全领域的重要研究方向,在数字版权保护、隐私保护等领域有着广泛应用。本文将介绍基于 MATLAB 的 Baker 映射和 Logistic 混沌序列的图像加解密算法,该算法利用混沌系统的初值敏感性和伪随机性,能够有效地对图像进行加密和解密。基于 Baker 映射和 Logistic 混沌序列的图像加解密算法是一种有效的方法,可以应用于数字版权保护、隐私保护等领域。MATLAB 提供了强大的工具和函数,可以方便地实现该算法。

走向CTO的路上... 935

C语言实现惯性导航初始对准全部核心代码

惯性导航初始对准包括间接粗对准和卡尔曼滤波精对准,其中。为基于卡尔曼滤波的精对准,其中。

十八与她的博客 2283

javascript继承、js继承实现方式、js继承优缺点

有如下父类 function People(name,age){ this.name = name this.age = age this.seelp = function(){ console.log('i am seelp') } } People.prototype.eat = function(){ console.log('i can eat') } 原型链继承 原理: 子类 的 prototype = 父类 的 实例 优点: 简单 不占

xiao_yu_liu的博客 266

TC3XX - MCAL知识点(十一):WDG EB-tresos配置说明与代码浅析

在AUTOSAR中,看门狗栈实现了三种监控机制:实时监控:用于周期软件的定时监控期限监督:针对非周期软件逻辑监督:用于监督执行顺序的正确性看门狗(WDG)驱动实现AUTOSAR(4.2.2)中规定的看门狗SWS,提供初始化、改变操作模式和设置触发条件(超时)等服务,供看门狗硬件(WDT)用户使用。WDG驱动的用户包括:模式管理模块(用于初始化),WdgM通过Wdglf设置触发条件和驱动运行模式设置。WdgM实施上述监督机制。AUTOSAR扩展触发概念,以支持窗口看门狗模式。

梦想技术家 3603

js/javascript 继承方式主要有哪些?及其优缺点特点

大家先看看这之前这篇文章,牢记一些概念。 链接: 构造函数,原型,实例的关系,原型链是什么. // 1.原型链继承 // 先看个小栗子 function F(){ } let s = new F() Object.prototype.x = 1 console.log(s.x) // 1 通过原型链获得的x值 s.x = 2 console.log(s.x) // 2 自己的x值 /* // 以上是原型搜索机制,当以读取模式访问一个实例属性时, // 先再实例搜索这个属性,如果没有会继续搜索原型 //

kyyius的博客 698

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

JavaScript中的几种继承方式及优缺点

继承也是前端里面的重要的一个知识点,在实际工作中或者面试中也会经常的遇到,那么通过这篇文章我们详细的了解一下继承的几种方式以及各种继承方式的优缺点! 在《JavaScript高级程序设计》一书中主要介绍了6种继承方式以及他们的优缺点,这6种分别为原型链继承、借用构造函数继承、组合继承、原型式继承、寄生式继承以及寄生组合式继承。本文除了介绍这6种继承方式外,还会介绍ES6中的class类继承

幽幽谷 1236

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

15.JavaScript深入之继承的多种方式和优缺点 - Js中文网

JavaScript深入系列第十五篇,讲解JavaScript各种继承方式和优缺点。 写在前面 本文讲解JavaScript各种继承方式和优缺点。 但是注意: 这篇文章更像是笔记,哎,再让我感叹一句:《JavaScript高级程序设计》写得真是太好了! 1.原型链继承 function Parent () { this.name = 'kevin'; } Parent.prototy...

Mark_yangyx的博客 287

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

JavaScript的6种继承方式及其优缺点汇总

来源 |https://blog.youkuaiyun.com/wosifp/article/details/104190819第一种:原型链继承利用原型链的特点进行继承function Pare...

web前端开发 259

【Javascript高级】 Javascript 之继承的多种实现方式和优缺点

Javascript 之继承的多种实现方式和优缺点,每一种实现方式都有自己的优缺点。

小牛itbull的博客 802

js继承的几种方式及优缺点

1、原型链继承 function Parent () { this.name = 'kevin'; } Parent.prototype.getName = function () { console.log(this.name); } function Child () { } Child.prototype = new Parent(); var child1 = new Child(); console.log(child1.getName()) // kevin 问

qq_35469739的博客 587

js 六种继承方式介绍及优缺点

js继承方式

混世小妲己 1759

js的六种继承方式及其优缺点

一、原型链继承 /* 原型链: JavaScript中实现继承最简单的方式就是使用原型链,将子类型的原型指向父类型的实例即可,即“子类型.prototype = new 父类型();”,实现方法如下: */ //为父类型创建构造函数 function SuperType () { this.name = ['zc','ls','ww']; this.property = true; } //为父类型添加方法 SuperType.proto

m0_53592673的博客 275

JS继承的几种方式及优缺点

原型链继承:原理:将父类的实例作为子类的原型 二.构造函数继承:原理:在子类构造函数中调用父类构造函数,可以在子类构造函数中使用call()和apply()方法改变this指向

qq_56088882的博客 2637

JavaScript中的继承有哪些方式?各有什么优缺点

在 JavaScript 中,继承主要通过原型链实现,常见的继承方式有以下几种,每种方式都有其优缺点。1. 原型链继承;2. 构造函数继承;3. 组合继承(经典继承);4. 原型式继承;5. 寄生式继承;6. 寄生组合式继承(最优解);7. ES6 class 继承

分享前端工程化、AI 应用、Agent 开发与大模型实践! 659

JS继承方式及其优缺点总结

- 优点:最简单的方式,将子类的原型指向父类的实例即可。 - 缺点:一是引用类型的属性被所有实例共享,修改堆内存数据时会将所有实例数据都修改,但是直接创建新的存储对象就不会产生这个错误。二是创建子类实例时不能向超类型的构造函数中传递参数。(因此开发中很少单独使用原型链)- 优点:能实现属性的继承,也可以在子类型创建实例时为父类型传递参数。 - 缺点:借用构造函数虽然解决了刚才的问题,但不能继承构造函数的原型,只能继承构造函数的属性和方法。因此每次创建子类实例时都会调用构造函数、复制构造函数,会影

yyysss9的博客 2091

【JavaScript修炼】javascript多种继承方式及其优缺点

javascript多种继承方式及其优缺点前言一、原型链继承二、借用构造函数(经典继承)三、组合继承四、原型式继承五、寄生式继承六、寄生组合式继承总结🍩原型链继承:🍩借用构造函数:🍩组合继承:🍩原型式继承🍩寄生式继承🍩寄生组合式继承 前言 本文介绍了javascript中多种继承方式及其优缺点,读完本文将收获: 知道javascript中6种继承方式的实现原理 知道各种继承方式的优缺点 理解各种继承方式之间的联系 一、原型链继承 顾名思义,原型链继承利用了构造函数的原型对象来实现继承。如下代码中有两

laplacepoisson的博客 918

6种JavaScript继承方式及优缺点

温馨提示:想要更好的理解JS继承方式,须了解构造函数、原型对象、实例化对象、原型链等概念 第一种:原型链继承 利用原型链的特点进行继承 function Parent(){ this.name = 'web前端'; this.type = ['JS','HTML','CSS']; } Parent.prototype.Say=function(){ console.log(...

wosifp的博客 714
上一篇: 浅谈 JavaScript 原型链
下一篇: Git 命令总结,从零到熟悉(全)
Panda Shen
博客等级 码龄10年 18粉丝 50原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值