Js基础总结一

strict关键声明

"use strict"; 

设立"严格模式"的目的,主要有以下几个:错误检测、规范、效率、安全、面向未来

  • 消除Javascript语法的一些不合理、不严谨之处,减少一些怪异行为;
  • 消除代码运行的一些不安全之处,保证代码运行的安全;
  • 提高编译器效率,增加运行速度;
  • 为未来新版本的Javascript做好铺垫。

严格模式影响范围

  • 变量: var、delete、变量关键字
  • 对象: 只读属性、 对象字面量属性重复申明
  • 函数:参数重名、arguments对象、申明
  • 其他:this、eval、关键字…
1.对于变量声明限制 – 变量显式声明
'use strict';
// 声明变量不带var
i = 1; // Uncaught ReferenceError: i is not defined
function demo_1(){
	o = 2; // Uncaught ReferenceError: o is not defined
	// 循环时,初始化没用var定义
	for (i = 10 - 1; i >= 0; i--) { // Uncaught ReferenceError: i is not defined
		console.log(i);
	}
}
2.禁止this关键字指向全局对象
function demo_2_1() {
	console.log(this); // Window 对象
	return !this; // 返回false
}

function demo_2_2() {
	'use strict';
	console.log(this); // undefined
	return !this;// 返回true
}
3.禁止删除变量

严格模式下无法删除变量。只有configurable设置为true的对象属性,才能被删除。


function deom_3(){
	'use strict';
	var x = 1;
	delete x; // 语法错误 Delete of an unqualified identifier in strict mode.
  var o = Object.create(null, {'x': {
      value: 1,
      configurable: true
  }});
  delete o.x; // 删除成功
}

4.函数不能有重名的参数

正常模式下,如果函数有多个重名的参数,可以用arguments[i]读取。严格模式下,这属于语法错误。


function deom_4(a, a, b) { 
// 语法错误 Duplicate parameter name not allowed in this context
  return ;
}

数据类型

涵盖数据类型有: Number、 String、 Array、 Json、 Boolean、 Object。

创建数组

var arr1 = [1,2,3,4];
var arr2 = new Array(1,2,3,4);

创建对象

var obj1 = {
	name:'ffewi',
	age:23,
	gender:'M',
	city:'chengdu',
	hasCar:false,
	hasBuilder:false,
	habits:['js','java','mybatis','mysql','spring'],
	others:undefined,
	lucky:null
};

变量:变量名是大小写英文、数字、$和_的组合,且不能用数字开头

var variable1 =123;
var $variable2 = 'abc';
var _variable3 = ['helllo'];

字符串

1.转意符

’ 与 " 使用时,需要通过转意符\使用,但是 ' 里面可以包含 " , 同理 " 里面可以包含 ' 直接使用 。

var str1 = 'I\'m \"ok!\"';// I'm "ok!"
var str2 = "I'm 'ok'!";// I'm 'ok'!
var str3 = 'I"m "ok"!';// I"m "ok"!

赋值可以直接,ASCII直接编码出字符,也可以通过编码Unicode编码直接编码出中文;进制缩写 8进制:oct (\) 10进制:dec 16进制:hex (\x)

//  \x 16进制 \n 换行符 \t 制表符
var str4 = '\x41';// A字符  
str4 = '\102';// 8进制的 B 字符
var chinese_str4 = '\u55f2';// 中文 :嗲
2.字符串操作

字符串可以看出数组来操作 下表以0开头 不在index范围 值为: undifined
;修改其中一个index的字符值,不影响原本字符串的内容 遵循java中 String 为不可变类。

var str5 = 'my name is ffewi';
str5[11] + str5[12] + str5[13] + str5[14] + str5[15];// ffewi
str5[-1];// undefined
str5[16];// undefined

尝试修改 str5最后的‘ffewi’ 为 ‘world’。

str5[11] = 'w';
str5[12] = 'o';
str5[13] = 'r';
str5[14] = 'l';
str5[15] = 'd';
console.log(str5[11] + str5[12] + str5[13] + str5[14] + str5[15]);// ffewi
3.常用方法

String 的一些常用的方法:toUpperCase(大写)、 toLowerCase(小写)、 substring(截取)、 indexOf(索引);

//toUpperCase() 字符串转换为大写
var str6 =str5.toUpperCase();// MY NAME IS FFEWI

//toLowerCase() 字符串转换为小写
var str7 =str6.toLowerCase();// my name is ffewi

//indexOf(string)索引字符内容的位置,以0开头 首个匹配字符的下标
var index = str7.indexOf('ffewi');// 11

var lastIndex = str7.lastIndexOf('f');// 12

var noIndex = str7.indexOf('notFound');// -1

//substring(a,b)  区间为[a,b); String.length  长度值从1开始 与数组区别 数组以0角标开始
var str8 = str7.substring(11,str7.length);// ffewi

//substring(a)  区间为[a,字符末尾]
var str9 = str7.substring(11);// ffewi

数组

1.数组的长度

数组在javaString拥有 length() 方法,Array拥有length属性。jslength 同时可以表示StringArray的长度。

var str1 = 'hello!';
console.log(str1.length);// 6
var arr1 = new Array('a1','a2','a3',4,[1,2,3,4]);
console.log(arr1.length);// 5
2.数组的定义

数组的定义:new Array(ob1,ob2,ob2,...) 或者 [ob1,ob2,ob3,...] ; 且里面的内容值是Object任意类型。

var arr2 = new Array(1,'2b',[3,'4d']);
var arr3 = [1,'2b',[3,'4d']];
console.log("定义的数组arr2:" + arr2);// 定义的数组arr2:1,2b,3,4d
console.log("定义的数组arr3:" + arr3);// 定义的数组arr3:1,2b,3,4d

比较上面两看着相似的数组。

console.log(arr2==arr3);//false 对象比较
console.log(arr2[1]===arr3[1]);//true 值比较
3.数组的操作

修改Arraylength将会改变Ta的储存结构,增加长度填充undifined,减少长度截取末尾,与java区别,此处Array是可变的数组。

自动填充 - increament

/* 上面 arr3长度为3 */
// 赋值后,由于第4、5位没有值,默认填充undifined;[1, "2b", Array(2), empty × 2, 5]
arr3[5] = 5;// 第6个值设置为5
console.log(arr3 + "填充的倒数第二位值为:" + arr3[4]);// 1,2b,3,4d,,,5填充的倒数第二位值为:undefined
console.log("填充的内容是undifined: " + (arr3[4] == 'undifined'));// 填充的内容是undifined: false
console.log("填充的内容是null:" + (arr3[4] == null));// 填充的内容是null:true

自动缩减 - reduce

arr3.length = 2;// 将长度变为2,原数组后面的元素自动丢弃
console.log("arr3.length reduce to 2 : " + arr3);// arr3.length reduce to 2 : 1,2b
console.log(arr3[5]);// undefined

null 和 undefined 的区别

var a;
var b=null;
console.log(a);// undefined
console.log(b);// null
console.log(a == b);// true
console.log(a === b);// false
4.常用的方法
  1. indexOf(索引)
  2. slice(切片)
  3. push/pop(入栈/弹栈)末尾元素
  4. unshift/shift(入栈/弹栈)头元素
  5. sort(排序)
  6. reverse(反转)
  7. splice(几乎万能的方法,相当于拥有增删改)
  8. concat(连接多个array)
  9. join(以 内容 来连接array里面的元素)

indexOf && lastIndexOf

var arr4 = [1,'3',22,30,'1'];
var index1 = arr4.indexOf(1);
var index2 = arr4.lastIndexOf('1');
var index3 = arr4.indexOf('not found');//没有元素 返回-1
// indexOf Method : 0  lastIndexOf Method : 4 not have index : -1
console.log("indexOf Method : " + index1 + "  lastIndexOf Method : " + index2 + " not have index : " + index3);

slice

对应String.Method’s substring() 范围为 [a,b) 或者 [a,length)slice() 无参数直接 [0,length]

var arr5 = [1,2,3,4,5,6,7,8];
var arr5_1 = arr5.slice(4,8);
console.log("slice(a,b) [a,b) : "+arr5_1);// slice(a,b) [a,b) : 5,6,7,8
var arr5_2 = arr5.slice(4);
console.log("slice(a) [a...length)  : "+arr5_2);// slice(a) [a...length)  : 5,6,7,8
var arr5_3 = arr5.slice();
console.log("arr5.slice() equals copy arr5 to arr5_3 : " +arr5_3);// arr5.slice() equals copy arr5 to arr5_3 : 1,2,3,4,5,6,7,8

push / pop

末尾操作push(ob1,…) 插入多个pop() 弹出一个。

var arr6 = ['a','b','c','d','e','f'];
arr6.push('g');
// push one : a,b,c,d,e,f,g
console.log("push one : " + arr6);

arr6.push('h',[1,2,3]);
// push more than one : a,b,c,d,e,f,g,h,1,2,3
console.log("push more than one : " + arr6);

arr6.pop();
// pop must be pop one ,can't pop more than one : a,b,c,d,e,f,g,h
console.log("pop must be pop one ,can't pop more than one : " + arr6);

var len = arr6.length;
// 从尾开始清空数组
for(var i= 0;i<len;i++){arr6.pop()}
// arr6.pop() to undifined : undefined
console.log("arr6.pop() to undifined : " + arr6.pop());

unshift / shift

头端操作unshift(ob1,…) 多个;shift() 去除一个;没有值时,在调用shift() 返回undifined ,不会报错。

var arr7 = [1,2,3,4,5];
arr7.unshift(0);
// unshift one : 0,1,2,3,4,5
console.log("unshift one : "+arr7);

arr7.unshift(['a','b','c'],-1);
// unshift more than one : a,b,c,-1,0,1,2,3,4,5
console.log("unshift more than one : " + arr7);

arr7.shift();
// shift each time just can shift one : -1,0,1,2,3,4,5
console.log("shift each time just can shift one : " + arr7);

len = arr7.length;
// 从头开始清空数组
for(var i=0;i<len;i++){arr7.shift()}
// for to shift to undifined : undefined
console.log("for to shift to undifined : " + arr7.shift());

sort / reserve

排序和反转

var arr8 = [4,7,8,9,['-1',16,11]];// 一般情况下 ,排序都是同种类型数据,所以不要找茬
arr8 = [11,88,5,66,32,45];
// [11, 88, 5, 66, 32, 45]
console.log(arr8);

var arr8_3 = [];
// 这样才能复制arr8的实际内容 而不是 修改对象引用
arr8_3 = arr8.slice();
var arr8_1 = arr8.sort();
// [11,32,45,5,66,88]   [11,32,45,5,66,88]  [11,32,45,5,66,88]
console.log(arr8 + "   " + arr8_1 + "  " + arr8.sort());

var arr8_2 = arr8.reverse();
// 会看到 arr8_1 arr8_2 只是对象引用,并无实际值存储
// 排序:[88,66,5,45,32,11] 反转:[88,66,5,45,32,11] 本尊arr8: 88,66,5,45,32,11 arr8_3 11,88,5,66,32,45
console.log("排序:["+arr8_1+"]反转:["+arr8_2+"]本尊arr8:"+arr8+"arr8_3"+arr8_3);

arr8.reverse();
// 排序:[11,32,45,5,66,88] 反转:[11,32,45,5,66,88] 本尊arr8: 11,32,45,5,66,88 arr8_3 11,88,5,66,32,45
console.log("排序:["+arr8_1+"]反转:["+arr8_2+"]本尊arr8:"+arr8+"arr8_3"+arr8_3);

// [11, 88, 5, 66, 32, 45]
console.log(arr8_3);

splice

splice(index1_start,index2_count,content1,conten2,…) 可以在任意位置添加,或者删除 需要制定脚标与连续删除的个数。

var arr9 = ['beijing','chengdu','shanghai','zigong','kunming','fushun'];
//删除从chengdu开始 的两个地名  (a,b) 从[a] -->b个元素
var delElements = arr9.splice(1,2);
// beijing,zigong,kunming,fushun 被删除的元素:chengdu,shanghai
console.log(arr9+" 被删除的元素:"+delElements);

//删除的同时添加
var delElements1 = arr9.splice(0,1,'chongqing',['xiamen','fujian','hulan']);
// chongqing,xiamen,fujian,hulan,zigong,kunming,fushun 被删除的元素 :beijing
console.log(arr9+" 被删除的元素 :"+delElements1);


var delElements2 = arr9.splice(2,0)//不删除任何,
// chongqing,xiamen,fujian,hulan,zigong,kunming,fushun delElements2 :
console.log(arr9+" delElements2 : "+ delElements2);

concat / join

前者连接两个数组,后者把数组里面的值 通过‘content’ 内容连接起来

var arr10 = [1,2,3];
var arr11 = ['a','b','c',['aaa','bbb'],11];
var concat10_11 = arr10.concat(arr11);
// 1,2,3,a,b,c,aaa,bbb,11  arr10: 1,2,3
console.log(concat10_11+"  arr10: "+arr10);//数据结构不变
// ["aaa", "bbb"]
console.log(concat10_11[6]);

var join1 = arr10.join('-');
var join2 = arr11.join('-');
// 1-2-3  a-b-c-aaa,bbb-11
console.log(join1+"  "+ join2);
// object  string
console.log(typeof(arr11)+"  "+typeof("ffewi"));

Object

Object的声明 以及 一些方法

var ffewi = {
	name:'ffewi',
	age:23,
	gender:'M',
	height:172,
	weight:74,
	habits:['java','js','mysql'],
	other:null,
	test:'看来不能不赋值',
	QQ:undefined
};
console.log("ffewi's message : "+"name: "+ffewi.name + " habits:"+ffewi.habits + " other:" + ffewi.other);

//看来使用 == 比较 undifined == null 时 会自动把undifined-->null?
console.log("比较 undifined == null :"+(undefined==null));//答案是true
console.log(" undifined QQ :"+ ffewi.QQ +"  compare undifined :"+(ffewi.QQ===undefined) +" compare undifined with null : "+(ffewi.QQ==null));

//当声明对象 属性带有特殊值是 用‘’ 加以修饰
var ffewi1 = {
	'show-msg':'hello',
	//show-msg:123 这样修饰会出现 “Unexpected token -” 访问时 也只能用 ffewi1['show-msg'],不能用. 的方式
};
console.log(ffewi1['show-msg']);

//访问没有的属性 返回值为 undifined
console.log(ffewi1.age);

//动态增加属性 直接用 ob.property=args 或者 ob[property]=args
ffewi1.age = 23;
ffewi1['like-people']='all of you';
console.log("{"+ffewi1.age+","+ffewi1['show-msg']+","+ffewi1['like-people']+"}");

//删除object里面有的属性 
delete ffewi1['show-msg'];
console.log("{"+ffewi1.age+","+ffewi1['show-msg']+","+ffewi1['like-people']+"}");

//常用 方法, 判断某个属性在不在object里面 :in  判断某个属性是不是 object 自己拥有的属性,非父类属性 hasOwnProperty
var in1 = 'age' in ffewi1;
var in2 = 'toString' in ffewi1;
console.log("age 自身属性在否:"+in1+" toString 继承父类属性在否:"+in2);//in 包含父类属性

var in3 = ffewi1.hasOwnProperty('age');
var in4 = ffewi1.hasOwnProperty('toString');
console.log("age 自身属性在否:"+in3+" toString 继承父类属性在否:"+in4);//hasOwnProperty 只判断自己的属性

条件判断

JavaScriptnullundefined0NaN和空字符串 ‘’ 视为false,其他值一概视为true


if(true){
	console.log("这个语法简单,自己领会");
}else{
	console.log("其它内容,可以自己嵌套着使用看看");
}
if(!0){
	console.log("0 is false");
}
if(-1){
	console.log("-1 is true");
}

循环

循环:主要有for 和 while 循环
例子:计算1*2*3*…*10

var sum;//undifined
sum = 1;
var loopTime = 10;
var count = 0;//统计乘的次数
//正常的for
for(var i=1;i<=loopTime;i++){
	sum *= i;
	count++;
}
console.log(sum+" count : "+count);//362880

//for in 常用来遍历数组
var sum1 = 1;
var number1 = [1,2,3,4,5,6,7,8,9,10];
//i为角标.. for in 遍历数组
for(var i in number1){
	sum1 *= number1[i]; 
	//console.log(sum1+"and i = " + i);
}
console.log(sum1);//362880

//for in 遍历对象
var ffewi = {
	name:'ffewi',
	age:23,
	gender:'M',
	habtis:['java','js','mysql']
};
for(var value in ffewi){
	console.log(value+" :"+ffewi[value]);
}

//while 循环   与   do while 循环
//结构 :
//判断后执行
while(false){
	console.log("这里的这句话不会出现在控制台!");
}
//先执行一次,以后每次执行都判断下
do{
	console.log("这里的这句话会出现在控制台! belive me!");
}while(false);

Map / Set

JavaScript的默认对象表示方式{}可以视为其他语言中的MapDictionary的数据结构,即一组键值对。但是JavaScript的对象有个小问题,就是键必须是字符串。但实际上Number或者其他数据类型作为键也是非常合理的。为了解决这个问题,最新的ES6规范引入了新的数据类型Map。要测试你的浏览器是否支持ES6规范,请执行以下代码,如果浏览器报ReferenceError错误,那么你需要换一个支持ES6的浏览器。

简单总结

  • Map 以键值对存储,方便查找,添加 ,删除
  • Set 不可以存放重复元素,当存入重复的时候操作即为覆盖原有值

声明方式

  • new Map()/new Set()
  • 初始Map [[key1,value1],[key2,value2],[],…]
  • Set [value1,value2,value3,…]

简单操作

  • m.get(key) 获取
  • m.set(key,value) 添加
  • m.delete(key) 删除
  • m.has(key) 返回结果 : true/false
var m = new Map([['name','ffewi']]);
m.set('name2','ffewi2');

var s = new Set(['name','ffewi']);
s.add('ffewi1');
console.log("map: "+m +" set: "+s);
/*小结
 *Map和Set是ES6标准新增的数据类型,请根据浏览器的支持情况决定是否要使用 
 * */
console.log(m.get('name')+"  "+s);
//遍历 map set 使用iterable  因为他们没有下标
//遍历Array可以采用下标循环,遍历Map和Set就无法使用下标。为了统一集合类型,
//ES6标准引入了新的iterable类型,Array、Map和Set都属于iterable类型
//结构:
var arr = [];
var index = 0;
for(var value of m){
	arr[index]=value;
	index++;
}
arr[index]="set 部分";
index++;
for(var value of s){
	arr[index]=value;
	index++;
}
console.log(arr);
//forEach(function(data,index,object){});  data:索引,或者脚标,index 角标或者索引纸箱的值,object对象本身
m.forEach(function(date,index,obj){
	console.log(index+":"+date+"  对象自己:"+obj);
});
s.forEach(function(date,index,obj){
	console.log(index+":"+date+"  对象自己:"+obj);
});
var arr2= [1,2,'name'];
arr2.forEach(function(date,index,obj){
	console.log(index+":"+date+"  对象自己:"+obj);
});
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
目标检测(Object Detection)是计算机视觉领域的一个核心问题,其主要任务是找出图像中所有感兴趣的目标(物体),并确定它们的类别和位置。以下是对目标检测的详细阐述: 一、基本概念 目标检测的任务是解决“在哪里?是什么?”的问题,即定位出图像中目标的位置并识别出目标的类别。由于各类物体具有不同的外观、形状和姿态,加上成像时光照、遮挡等因素的干扰,目标检测一直是计算机视觉领域最具挑战性的任务之一。 二、核心问题 目标检测涉及以下几个核心问题: 分类问题:判断图像中的目标属于哪个类别。 定位问题:确定目标在图像中的具体位置。 大小问题:目标可能具有不同的大小。 形状问题:目标可能具有不同的形状。 三、算法分类 基于深度学习的目标检测算法主要分为两大类: Two-stage算法:先进行区域生成(Region Proposal),生成有可能包含待检物体的预选框(Region Proposal),再通过卷积神经网络进行样本分类。常见的Two-stage算法包括R-CNN、Fast R-CNN、Faster R-CNN等。 One-stage算法:不用生成区域提议,直接在网络中提取特征来预测物体分类和位置。常见的One-stage算法包括YOLO系列(YOLOv1、YOLOv2、YOLOv3、YOLOv4、YOLOv5等)、SSD和RetinaNet等。 四、算法原理 以YOLO系列为例,YOLO将目标检测视为回归问题,将输入图像一次性划分为多个区域,直接在输出层预测边界框和类别概率。YOLO采用卷积网络来提取特征,使用全连接层来得到预测值。其网络结构通常包含多个卷积层和全连接层,通过卷积层提取图像特征,通过全连接层输出预测结果。 五、应用领域 目标检测技术已经广泛应用于各个领域,为人们的生活带来了极大的便利。以下是一些主要的应用领域: 安全监控:在商场、银行
目标检测(Object Detection)是计算机视觉领域的一个核心问题,其主要任务是找出图像中所有感兴趣的目标(物体),并确定它们的类别和位置。以下是对目标检测的详细阐述: 一、基本概念 目标检测的任务是解决“在哪里?是什么?”的问题,即定位出图像中目标的位置并识别出目标的类别。由于各类物体具有不同的外观、形状和姿态,加上成像时光照、遮挡等因素的干扰,目标检测一直是计算机视觉领域最具挑战性的任务之一。 二、核心问题 目标检测涉及以下几个核心问题: 分类问题:判断图像中的目标属于哪个类别。 定位问题:确定目标在图像中的具体位置。 大小问题:目标可能具有不同的大小。 形状问题:目标可能具有不同的形状。 三、算法分类 基于深度学习的目标检测算法主要分为两大类: Two-stage算法:先进行区域生成(Region Proposal),生成有可能包含待检物体的预选框(Region Proposal),再通过卷积神经网络进行样本分类。常见的Two-stage算法包括R-CNN、Fast R-CNN、Faster R-CNN等。 One-stage算法:不用生成区域提议,直接在网络中提取特征来预测物体分类和位置。常见的One-stage算法包括YOLO系列(YOLOv1、YOLOv2、YOLOv3、YOLOv4、YOLOv5等)、SSD和RetinaNet等。 四、算法原理 以YOLO系列为例,YOLO将目标检测视为回归问题,将输入图像一次性划分为多个区域,直接在输出层预测边界框和类别概率。YOLO采用卷积网络来提取特征,使用全连接层来得到预测值。其网络结构通常包含多个卷积层和全连接层,通过卷积层提取图像特征,通过全连接层输出预测结果。 五、应用领域 目标检测技术已经广泛应用于各个领域,为人们的生活带来了极大的便利。以下是一些主要的应用领域: 安全监控:在商场、银行
健身国际俱乐部系统是一种专为健身俱乐部设计的管理软件,它通过集成多种功能来提高俱乐部的运营效率和服务质量。这类系统通常包含以下几个核心模块: 1. **会员管理**:系统能够记录会员的基本信息、会籍状态、健身历史和偏好,以及会员卡的使用情况。通过会员管理,俱乐部可以更好地了解会员需求,提供个性化服务,并提高会员满意度和忠诚度。 2. **课程预约**:会员可以通过系统预约健身课程,系统会提供课程时间、教练、地点等详细信息,并允许会员根据个人时间表进行预约。这有助于俱乐部合理安排课程,避免资源浪费。 3. **教练管理**:系统可以管理教练的个人信息、课程安排、会员反馈等,帮助俱乐部评估教练表现,优化教练团队。 4. **财务管理**:包括会员卡销售、课程费用、私教费用等财务活动的记录和管理,确保俱乐部的财务透明度和准确性。 5. **库存管理**:对于俱乐部内的商品销售,如健身装备、营养补充品等,系统能够进行库存管理,包括进货、销售、库存盘点等。 6. **据分析**:系统能够收集和分析会员活动据,为俱乐部提供业务洞察,帮助俱乐部制定更有效的营销策略和业务决策。 7. **在线互动**:一些系统还提供在线平台,让会员可以查看课程、预约私教、参与社区讨论等,增强会员之间的互动和俱乐部的社区感。 8. **移动应用**:随着移动设备的普及,一些健身俱乐部系统还提供移动应用,方便会员随时随地管理自己的健身计划。 9. **安全性**:系统会确保所有会员信息的安全,采取适当的据加密和安全措施,保护会员隐私。 10. **可扩展性**:随着俱乐部业务的扩展,系统应该能够轻松添加新的功能和服务,以适应不断变化的市场需求。 健身国际俱乐部系统的选择和实施,需要考虑俱乐部的具体需求、预算和技术能力,以确保系统能够有效地支持俱乐部的运营和发展。通过这些系统的实施,健身俱乐部能够提供更加专业和高效的服务,吸引和保留更多的会员,从而在竞争激烈的
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值