ES6

一、

let命令:用来声明一个变量,和var非常类似

const命令:用来声明一个常量,常量就是不可变的量

用let声明变量注意事项:

1.使用let声明的变量,所声明的变量只在命令所在的代码块内有效

<script type="text/javascript">

      {

         let a = 10;

         //alert(a)

         var b = 10;

       }

         //alert(a)报错

         alert(b)//10

 </script>

2.使用let命令声明的变量在域解析的时候不会被提升

           console.log(a)//undefined

           var a = 10;

           console.log(b)//报错

           let b = 10;

3.let不允许在同一个作用域下生明已经存在的变量

           //var a = 10;

           //var a;//不报错

           let a = 10;

           let a;//报错

4.let在for循环中的运用

               var btn = document.querySelectorAll('input');

                for(var i = 0; i < btn.length; i++) {

                     btn[i].onclick = function() {

                           console.log(i)//5

                           this.style.background = 'red';

                     }

                }

                /*for(var i = 0; i < btn.length; i++) {

                     btn[i].index = i;

                     btn[i].onclick = function() {

                           console.log(this.index)//0123

                           btn[this.index].style.background = 'red';

                     }

                }*/

                /*for(let i = 0; i < btn.length; i++) {

                     btn[i].onclick = function() {

                           console.log(i)//012345

                           this.style.background = 'red';

                     }

                }*/

在循环语句中是一个父作用域,在循环体之中是一个子作用域

               for(let i=0;i<3;i++){

                     let i = 10;

                     console.log(i)//10 父作用域与子作用域是分离的

                }

                console.log(i)//报错 let出来的变量只在循环语句中有用,在之外就未定义报错了

const命令同样有let的123条特点,第一所声明的常量只在其所在的代码块内有效,第二声明的常量不会被提升,第三 不能声明已经被声明过的变量或者常量。还有两点:

1.声明的时候必须赋值

                var a;//正常

                let b;//正常

                const c;//报错

2.声明的常量储存简单的数据类型时候不可改变其值,如果储存的是对象,那么引用不可以被改变,至于对象里面的数据如何变化,是没有关系的。

               /*const a = 10;

                const a = 52;*/

                const obj = {a : 10}

                obj.a = 20;

二、

变量的结构赋值:本质上就是一种匹配模式,只要等号两边的模式相同,那么左边的变量就可以被赋予对应的值;

结构赋值主要分为:

1.数组的结构赋值

               /*let [a,[[b],c]] = [1,[[2],3]]

                console.log(a,b,c) //1,2,3*/

                /*let [,,a] = [1,2,3]

                console.log(a)//3*/

                let [y = 1] = [];

                console.log(y)//1

2.对象的结构赋值

               //let {a,b} = {b : 'bbb',a: 'aaa'}

                //console.log(a,b) //aaa bbb

                let {a : b} = {a : 1}

                console.log(a)//报错

                //console.log(b)//1

3.基本类型的结构赋值

               //let [a,b,c,d] = '1234';

                //console.log(a,b,c,d)//1,2,3,4

                //let {length:len} = 'tangxiaoqiang';

                //console.log(len)//13

                //let {toString:ts} = 1;

                //let {toString:bs} = true;

                //console.log(ts === Number.prototype.toString)//true

                //console.log(bs === Boolean.prototype.toString)//true

                //null和undefined 不能进行结构赋值

                let {a} = null;//报错

三、

数据结构Set

集合的基本概念:

     集合是由一组无序且唯一(即不重复)的项组成的。这个数据结构使用了与有限集合相同的数学概念,应用在计算机的数据结构中。

特点:key 和 vaule 相同,没有重复的value.

ES6提供了数据结构Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。

1.如何创建一个Set

                //const a = new Set([1,2,3])

                //console.log(a)//Set(3) {1, 2, 3}

2.Set类的属性

                const a = new Set([1,2,3])

                console.log(a.size)//3  size类似与length

3.Set类的方法

                const a = new Set([1,2,3])

                //1.set.add(value) 添加一个数据,返回Set结构本身

                //a.add('a').add('b').add('c')

                //console.log(a)//{1, 2, 3, "a", "b","c"}

                //2.set.delete(value) 删除指定数据,返回一个布尔值,表示删除是否成功

                //console.log(a.delete(1));//true

                //console.log(a)//2,3

                ///console.log(a.delete(1));//false

                //3.set.has(value) 判断该值是否为Set的成员,返回一个布尔值

                //console.log(a.has(1))//false

                //console.log(a.has(2))//true

                //4.set.clear()清除所有的数据,没有返回值

                //a.clear()

                //console.log(a)

                //5.keys() 返回键值的遍历器

                //console.log(a.keys())

                //6.values() 返回键值的遍历器

                //console.log(a.values())

                //7.entries()返回键值对的遍历器

                //console.log(a.entries())

                //8.forEach() 使用回调函数遍历每个成员

                /*a.forEach(function(value,key,set){

                     console.log(value + 'tjx')

                })

                console.log(a)*/

                //Set不允许有重复的数据的

                a.add(1);

                console.log(a)//1,2,3

四、

数据结构Map

 字典:是用来存储不重复key的Hash结构。不同于集合(Set)的是,字典使用的是[键,值]的形式来存储数据的。

javascript的对象(Object:{})只能用字符串当作键。这给它的使用带来了很大的限制。

为了解决这个问题,ES6提供了Map数据结构。它类似与对象,也是键值对的集合,但是‘键’的范围不限制于字符串,各类数据的值(包括对象)都可以当作键,也就是说,Object结构提供了“字符串-值”的对应,Map结构提供了“值-值”的对应,是一种更加完善的Hash结构实现。如果你需要“键值对”的数据结构,Map比Object跟合适。

1.如何创建Map

               const map = new Map([

                     ['a',1],

                     ['b',2]

                ])

                //console.log(map)//{"a" => 1, "b" => 2}*/

2.Map类的属性

                const map = new Map([

                     ['a',1],

                     ['b',2]

                ])

                console.log(map.size)//2

3.Map类的方法

1.set(key,value)设置键名key对应的键值为value,然后返回整个Map结构。如果已有值,则键值会被更新,否则就新生成该键。

2.get(key)get方法读取key对应的键值,如果找不到key,返回undefined.

3.delete(key)删除某个键,返回true,如果删除失败返回false.

4.has(key)方法返回一个布尔值,表示某个键是否在当前Map对象之中。

5.clear()清除数据,没有返回值。

6.keys()返回键名的遍历器

7.values()返回键值的遍历器

8.entries()返回键值对的遍历器

9.forEach()使用回调函数遍历每个成员

                //1.set(key,value)设置键名key对应的键值为value,然后返回整个Map结构。如果已有值,则键值会被更新,否则就新生成该键。

                const map = new Map([

                     ['a', 1],

                     ['b', 2]

                ])

                map.set('miaov', 'ketang').set('new', 'www').set('miaov', 'body');

                console.log(map) //重复写对个相同key会被后面的值覆盖

                //2.get(key)get方法读取key对应的键值,如果找不到key,返回undefined.

                console.log(map.get('new'))

                console.log(map.get('aa'))

                //3.delete(key)删除某个键,返回true,如果删除失败返回false.

                console.log(map.delete('new')) //true

                console.log(map)

                console.log(map.delete('new')) //false

                //4.has(key)方法返回一个布尔值,表示某个键是否在当前Map对象之中。

                console.log(map.has('new')) //false

                map.set('new', '添加了')

                console.log(map.has('new')) //true

                //5.clear()清除数据,没有返回值。

                //map.clear()

                //console.log(map) //{}

                //6.keys()返回键名的遍历器

                console.log(map.keys())

                //7. values() 返回键值的遍历器

                console.log(map.values())

                //8.entries() 返回键值对的遍历器 !!!!

                console.log(map.entries())

                //9. forEach() 使用回调函数遍历每个成员

                map.forEach(function(key,value,map){

                     console.log(key + ':' + value)

                })

                //Map在使用的一些注意事项:

                //map.set(NaN,10).set(NaN,100)

                //console.log(map)//NaN,100

                map.set({},'a').set({},'b')

                console.log(map) //Object {} => "a" Object {} => "b"

                console.log({} === {})//false 比较的不是值而是内存地址所以不相等

                //map里面key的排列顺序永远都是按照添加的顺序排列的

五、

Iterator:

基本概念:

在ES6中新增了Set和Map两种数据结构,在加上JS之前原有的数组和对象,这样就有了四种数据集合,平时还可以组合使用它们,定义自己的数据结构,比如数组的成员是Map,Map的成员是对象等,这样就需要一种统一的接口机制,来处理所有不同的数据结构。

Iterator就是这样一种机制。它是一种接口,为各种不同的数据结构提供统一的访问机制,任何数据结构只要部署Iterator接口,就可以完成遍历操作,而且这种遍历操作是***依次*处理该数据结构的所有成员。

Iterator遍历器的作用:

 -为各种数据结构,提供一个统一的,简便的访问接口。

 - 使得数据结构的成员都能够按照某种次序排列

 - ES6新增了遍历命令for...of循环,Iterator接口主要提供for..of消费

Iterator的遍历过程:

-创建一个指针对象,指向当前数据结构的起始位置。也就是说,遍历器对象本质上,就是一个指针对象。

-第一次调用指针对象的next方法,可以将指针指向数据结构的第一个成员。

-第二次调用指针对象的next方法,指针就指向数据结构的第二个成员。

- 不断调用指针对象的next方法,直到它指向数据结构的结束位置。

第一次调用next方法,都会返回数据结构的当前成员的信息。具体来说,就是返回一个包含value和done两个属性的对象。其中,value属性是当前成员的值,done属于是一个布尔值,表示遍历是否结束。

               //1.手写Iterator接口

                /*const arr = [1,2,3];

                function iterator(arr){

                     let index = 0;

                     return {

                           next:function(){

                                return index < arr.length ?

                                {value : arr[index++],done:false}:

                                {value : undefined,done:true};

                           }

                     }

                }

                const it = iterator(arr);

                console.log(it.next());

                console.log(it.next());

                console.log(it.next());

                console.log(it.next());*/

                //2.凡是具有Symbol.iterator属性的数据结构都具有Iteratorjiek

                const arr = [1,2,3];

                const set = new Set(['a','b','c']);

                const map = new Map([['a',1]]);

                const itArr = arr[Symbol.iterator]();

                const itSet = set[Symbol.iterator]();

                const itMap = map[Symbol.iterator]();

                console.log(itArr);

                console.log(itSet);

                console.log(itMap);

                console.log(itSet.next());

                console.log(itSet.next());

                console.log(itSet.next());

                console.log(itSet.next());

                const obj = {};

                console.log(obj[Symbol.iterator]);//undefined

                /*3.具备iterator接口的数据结构都可以进行下操作:

                -结构负值

                -扩展运算符*/

                //let [x,y] = set;

                //console.log(x,y)//a b

                //...

                let str = 'miaov';

                let arrStr = [...str];

                //console.log(arrStr)//["m", "i", "a", "o", "v"]

                //数组去重

                const  arr2 = [{},[],1,1,'a','a',1,2];

                console.log([...new Set(arr2)])//数组 [Object, Array(0), 1, "a", 2]

                console.log(new Set(arr2))//集合 {Object {}, [], 1, "a", 2}

                //4.for..of循环

                const ofArr = [1,2,3,4];

                for(let i of ofArr){

                     console.log(i)

                }

                const m = new Map();

                m.set('a',1).set('b',2).set('c',3);

                for(let data of m){

                     console.log(data)

                }

                for(let [key,value] of m){

                     console.log(key,value)

                }

六、

class:

js语言的传统方法是通过构造函数,定义并且生成新的对象,是一种基于原型的面相对象系统:这种写法跟传统的面向对象语言(比如c++和java)差异很大,很容易让新学习这门语言的人感到困惑,所以,在ES6中新增加了类的概念,可以使用class关键字声明一个类,之后这个类来实例化对象。

               //ES5的构造函数

                /*const Miaov = function(a,b){

                     this.a = a;

                     this.b = b;

                     return this;

                };

                Miaov.prototype = {

                     constructor : Miaov,

                     print:function(){

                           console.log(this.a+' '+this.b)

                     }

                };

                const miaov = new Miaov('hello','world').print()*/

                //ES6的写法

                class Miaov {

                     constructor(a,b){

                           this.a = a;

                           this.b = b;

                           return this;

                     }

                     print(){

                           console.log(this.a+' '+this.b)

                     }

                };

                const miaov = new Miaov('hello','world').print()

                console.log(typeof Miaov)

                //1.Miaov中的constructor方法是构造方法,this关键字则代表实例对象。也就是说es5的构造函数Miaov,对应ES的Miaov这个类的构造方法。

                //2Miaov这个类除了构造方法,还定义了一个print方法,注意,定义‘类’的方法的时候,前面不需要加上function这个关键字,直接吧函数定义放进去就可以啦,另外方法之间不需要逗号分隔,加了会报错。

                //3构造函数的prototype属性,在ES6的‘类’上面继续存在,而且类的所有方法都定义在类的prototype属性上面

                     console.log(Miaov.prototype)

                //4定义在类的方法都是不可以枚举的

                console.log(Object.keys(Miaov.prototype))

                //5.constructor方法是类的默认方法,通过new命令生成对象实例时,自动调用该方法。一个类必须有constructor方法,如果没有显示定义,一个空的constructor方法会被默认添加

                class P {};

                const p = new P();

                console.log(p);

                //6.生成类的实例对象的写法,与ES5完全一样,也是使用new命令,如果忘记加上new,像函数那样调用class,将会报错

                //p();

七、

Symbol:

什么是Symbol?

Symbol表示独一无二的值。他是JS中第七种数据类型。

基本的数据类型:Null Undefined Number Boolean String Symbol

引用数据类型;Object

                let s1 = Symbol();

                let s2 = Symbol();

                console.log(typeof s1)//'symbol'

                console.log(s1 === s2)//false

                //Symbol函数前不能使用new否则会报错,原因在于Symbol是一种原始类型的值,不是对象。

                //let s3 = new Symbol();

                console.log(s1)

                console.log(s2)

                //Symbol函数接收一个字符串作为参数,表示对Symbol的描述,主要是为了在控制台显示,或者转为字符串的时候,比较容易区分

                /*let s3 = Symbol('miaov');

                let s4 = Symbol('leo');

                console.log(s3,s4)//Symbol(miaov) Symbol(leo)、

                console.log(Symbol('momo') === Symbol('momo'))*///false 参数仅仅只是一个描述

                //2 Symbol数据类型的转换

                console.log(String(Symbol('miaov')))//Symbol(miaov)

                console.log(Symbol('leo').toString())//Symbol(leo)

                console.log(!!Symbol())//true

                //console.log(Number(Symbol()))//报错

                //console.log(Symbol('ttt') + 'txj')//报错 和字符串不可以进行拼接

                //console.log(Symbol('miaov')*100)//报错 不能做任何运算

                //3.作为对象的属性名

                /*let yyy = Symbol('yyy');

                const obj = {};

                obj[yyy] = 'hello';

                console.log(obj)

                console.log(obj[yyy])*/

                /*let ss =Symbol('ss');

                const data = {

                     [ss]:'miaov'

                }

                console.log(data)

                console.log(data[ss])*/

                const data = {

                     [Symbol()]:123,

                     a : 1,

                     b : 2

                }

                //console.log(data[Symbol()]);//获取不到

                //Symbol不能被for...in循环遍历,虽然不能被遍历,但是也不是私有的属性,可以通过Object.getOwnPropertySymbols方法获得一个对象的所有的Symbol属性

                for(let i in data ){

                     console.log(i)//a,b

                }

                console.log(Object.getOwnPropertySymbols(data))

                console.log(data[Object.getOwnPropertySymbols(data)[0]])

八、

内置对象的扩展:

字符串扩展

               //模版字符串 ``

                let fa = true;

                let html = `<ul>

                                       <li>

                                          <span>${'首页'}</span>

                                          <span></span>

                                          <span class="${fa ? 'show' : 'hide'}"></span>

                                          <span></span>

                                          <span></span>

                                     </li>

                              </ul>`;

                console.log(html)

                /*1.repeat()返回值为布尔值

                2.includes()查找字符串中是否包含字符串  返回值为布尔值

                startsWidth()查找字符串开头是否包含字符串

                endsWidth()查找字符串结尾是否包含字符串

                */

                /*let str1 = 'a';

                let str2 = str1.repeat(3) //传入参数为个数

                console.log(str2)*/

                let str = 'miaov';

                console.log(str.includes('ao'))//true

                console.log(str.includes('b'))//false

                console.log(str.startsWith('m'))//true

                console.log(str.startsWith('i'))//false

                console.log(str.endsWith('aov'))//true

数组的扩展

               //数组的扩展

                //Array.from() 转换成数组

                /*var lis = document.querySelectorAll('li');

                console.log(Array.isArray(lis))//false

                let lis2 = Array.from(lis)

                console.log(lis2);

                console.log(Array.isArray(lis2))//true

                //Array.of()创建数组

                const arr = Array.of(1);

                console.log(arr)//true*/

                //find()查找数组中符合要求的元素,并且返回数组中第一个符合要求的元素 都不符合返回undefined

                //findIndex()查找数组中符合要求的元素,并且返回数组中第一个符合要求的元素的下标 都不符合返回-1;

                /*const arr = [1,2,3,4]

                let res = arr.find(function(a){

                     return a<0;

                })

                console.log(res)//1 元素*/

                /*let res = arr.findIndex(function(a){

                     return a<2;

                })

                console.log(res)//0 下标*/

                //fill()

                /*const arr = [1,2,3,4];

                arr.fill('aaa',1,3)

                console.log(arr)//[1, "aaa", "aaa", 4]*/

对象的扩展

               //对象的简洁表示法

                let a = 1;

                /*const obj = {

                     a : a

                }

                console.log(obj) //Object {a: 1}

                const obj = {a}

                console.log(obj)//Object {a: 1}*/

                /*const obj = {

                     fn : function(){

                           console.log(1)

                     },

                     fn2(){

                           console.log(2)

                     }

                }

                obj.fn();//1

                obj.fn2();//2

                */

                //Object.is() 判断两个对象是否一样 就是样子一样

                console.log(Object.is(NaN,NaN))//true

                console.log(Object.is(+0,-0))//false

                //Object.assign()

                //用于对象的合并,将原对象所有可以枚举属性,复制到目标对象

                let obj1 = {a:1};

                let obj2 = {a:2,b:3};

                let obj3 = {c : 'abc'};

                //Object.assign(目标对象,源对象,源对象...)

                Object.assign(obj1,obj2,obj3)

                console.log(obj1) //{a: 2, b: 3, c: "abc"}

                //目标元素相同属性名的会被源对象的相同的覆盖

九、

函数的扩展:

               //函数的扩展

                //1.为函数参数指定默认值

                /*function fn(a,b){

                     a = a || 10;

                     b = b || 20;

                     console.log(a + b);

                }

                fn();//30

                fn(0,10)//20*/

                /*function fn(a = 10,b = 20){

                     console.log(a + b);

                }

                fn();//30

                fn(0,10)//10*/

                //2.函数的rest参数

                //rest 参数形式为(“...变量名”),用于获取函数的多余参数,这样就不需要使用arguments对象了。rest参数搭配的变量是一个数组,该变量将多余的参数放入数组中。

                /*function sum(){

                     var args = arguments;

                     var res = 0;

                     for(var i = 0;i<args.length;i++){

                           res += args[i];

                     }

                     console.log(res)

                }

                sum(1,2)//3*/

                /*function sum(a,...arr){//...arr后面在写参数就会报错

                     var res = a;

                     for(var i=0;i<arr.length;i++){

                           res += arr[i];

                     }

                     console.log(res)

                }

                sum(10,1,2,3)//16*/

                //3.箭头函数

                //使用‘箭头’(=>)定义函数

                /*const fn = a => a;

                const fn2 = function(a){

                     return a;

                }

                console.log(fn(1))//1

                console.log(fn2(1))//1*/

                //const fn = (a,b) => a + b;

                //console.log(fn(1,2))//3

                /*const fn = (a,b) => {

                     a = a * 2;

                     b = b * 2;

                     return a + b;

                };

                console.log(fn(1,2))//6*/

                //const fn = (a,b) =>({a,b});

                //console.log(fn(1,2))//Object {a: 1, b: 2}

                //var arr =  [1,2,4,3,7,0];

                /*arr.sort(function(a,b){

                     return a - b;

                })

                console.log(arr)*///[0, 1, 2, 3, 4, 7]

                //arr.sort((a,b) => a - b);

                //console.log(arr)//[0, 1, 2, 3, 4, 7]

                //1箭头函数体内没有自己的this对象,所以在使用的时候,其内部的this就是定义时所在的环境对象,而不是使用时所在环境对象

                /*function fn(){

                     setTimeout(function(){

                           console.log(this);//Window

                     },1000)

                     setTimeout(() => {

                           console.log(this)//Object {a: 1}

                     },1000)

                }

                var obj = {a : 1};

                fn.call(obj);*/

                //不能给箭头函数使用 call applu bind 去改变其内部的this指向

                //2箭头函数体内没有arguments对象,如果要用,可以用Rest参数代替

                /*function fn(){

                     setTimeout(() => {

                           console.log(arguments)

                     },1000)

                }

                fn(1,2,3)*/

                //const fn =(...arr) => arr;

                //console.log(fn(1,2,3,4));//[1, 2, 3, 4]

                 //3不可以当作构造函数,不可以使用new命令,否则会抛出一个错误

                // const fn = (a,b) => a + b;

                 //const f = new fn(1,2)//报错

                 //4 箭头函数不能用作Generator函数

十、

异步操作之Promise:

Promise:是ES6中新增的异步编程解决方案,体现在代码中他是一个对象,可以通过Promise构造函数来实例化。

new Promise(cb) === > 实例的基本使用 Pending Resolved Rejected

两个原型方法:

 - Promise.prototype.then()

 - Promise.prototype.catch()

两个常用的静态方法:

 - Promise.all()

 - Promise.resolve()

new Promise(cb)

pending(进行中) ===>Resolved(已完成)

Pending(进行中) ===>Rejected(已失败)

               const imgs = [

                     'http://att.img.xiushuang.com/allimg/160712/16015312A-0.jpg',

                     'http://file20.mafengwo.net/M00/19/20/wKgB3FGj_XOARavMAADwfO6Uxgw93.jpeg',

                     'http://i2.hdslb.com/bfs/archive/795cbe9de1cc6c6b76ffb65ca3ec52bff3cf1af7.jpg',

                     'http://img.bimg.126.net/photo/O6mJjq5DOgYqQDpfuqx0WQ==/2319072333119924755.jpg'

                ];

                /*const p = new Promise(function(resolve,reject){

                     const img = new Image();

                     img.src = '';

                     img.onload = function(){

                           resolve(this);

                     };

                     img.onerror = function(err){

                           reject(new Error('图片加载失败'))

                     };

                });

                console.log(123)

                p.then(function (img){

                     console.log('完成')

                     document.body.appendChild(img)

                }).catch(function(err){

                     console.log(err)

                })

                console.log(456)*/

                function loadImg(url){

                     const p = new Promise(function(resolve,reject){

                     const img = new Image();

                     img.src = url;

                     img.onload = function(){

                           resolve(this);

                     };

                     img.onerror = function(err){

                           reject(new Error('图片加载失败'))

                     };

                });

                return p;

                }

                /*loadImg(imgs[2]).then(function(img){

                     document.body.appendChild(img)

                })*/

                /*Promise.all可以将多个Promise实例包装成一个新的Promise实例;

                -当所有Promise实例的状态都变成resolved,Promise.all的状态才会变成resolved,此时返回值组成一个数组,传递给then中的resolve函数.

                -只要其中有一个被rejected,Promise.all的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数.*/

                /*const allDone = Promise.all([loadImg(imgs[0]),loadImg(imgs[1]),loadImg('')]);

                allDone.then(function(datas){

                     datas.forEach(function(item,i){

                           document.body.appendChild(item)

                     });

                }).catch(function(err){

                     console.log(err)

                })*/

                //参数是Promise实例,将不做任何修改,原封不动的返回这个实例

                /*Promise.resolve(loadImg(imgs[0])).then(function(img){

                     document.body.appendChild(img)

                })*/

                /*Promise.resolve({

                     then(resolve,reject){

                           const img = new Image();

                           img.src = imgs[1];

                           img.onload = function(){

                                resolve(this);

                           }

                     }

                }).then(function(img){

                     document.body.appendChild(img)

                })*/

                /*Promise.resolve('miaov').then(function(str){

                     console.log(str)

                })*/

                const p = Promise.resolve();

                console.log(p)

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值