javascript 高级程序设计(第4版)阅读笔记(三)
第3章,内容很长,所以更得慢,主要讲的是ECMAScript es的语言基础:语法、数据类型、基本操作符、流控制语句、理解函数,ECMAScript 的语法很大程度上借鉴了 C 语言和其他类 C 语言,如 Java 和 Perl,以下内容主要基于es6。
1、ECMAScript 标识符 和注释
ECMAScript 中一切都区分大小写,为了确保过去和未来es版本的兼容,不能使用关键字、保留字、布尔值true、false和 null来作为函数名。
ECMAScript 标识符,就是变量、函数、属性或函数参数的名称、命名。
开头第一个字符必须是字母、下划线_ ,或者是美元符号$,写法大多建议都是驼峰命名写法,例如:firstSecond、myBox等
//单行注释/* 多行注释多行了 */
2、严格模式
Es5新增的严格模式,加上"use strict" ,不规范的写法会被处理,所有浏览器都支持。
<script type=”text/javascript”>‘use strict’;
//.....全文严格模式
</script>function example(){“use strict”;//...局部严格模式
}
3、语句
语句上虽然说没分号也有效但不建议,写语句要以分号进行结尾;
这样可以避免不必要的错误,比如删行压缩代码时容易出错。
<script type=”text/javascript”>‘use strict’;
//.....全文严格模式
</script>function example(){“use strict”;//...局部严格模式
}
一些单条if判断不写{}花括号也有效但不建议,要用上{}花括号。这样让内容更清晰,更好维护和修改。
4、变量
变量可以用来保存任何类型的数据,有三个关键词声明变量:var、let、const。
5、Var
var message;
这段代码定义了名为message,保存一个特殊值 undefined。
var message = "hi";
这段代码被定义为一个保存字符串值 hi的变量,不仅可以改变保存的值,也可以改变值的类型。
var message = "hi";
message = 100;
var 局部作用域
使用var在一个函数内部定义一个变量,变量在函数退出时被销毁:
function test(){var msg = "123";
}
test();
console.log(msg)//出错
//省略var操作符,定义的是全局变量,调用一次就可以在外部访问到:
function test(){msg = "123";
}
test();
console.log(msg)//123
但在局部作用域中定义全局变量,不好维护,在严格模式下也非常容易报错ReferenceError
如果要定义多个变量,可以逗号分割这么写,换行和缩进不是必须只是为了方便阅读:
var msg = "hi",
flag=false,
age=29;
提升变量,会把变量的提升到作用域的最顶部,也可以反复声明
function foo() {var age = 16;var age = 26;var age = 36;console.log(age);
}
foo(); // 36
6、let
let声明的是块作用域,var声明的是函数作用域,适用于var的作用域也适用于let。在同一个作用域中let不可以重复声明,重复声明会报错
let age;
let age; // SyntaxError;标识符 age已经声明过了
for循环中,使用var会渗透到外部,改成let的话呢,就不会出现这个问题,因为let作用域于for循环内部
for(var i =0; i <5; i++){
//...
}
console.log(i);//5
for (var i = 0; i < 5; ++i) {setTimeout(() => console.log(i), 0)
}
// 你可能以为会输出 0、1、2、3、4
// 实际上会输出 5、5、5、5、5
退出循环时,迭代变量(迭代变量会自增)保存的是导致循环退出的值:5。在之后执行超时逻辑时,所有的 i都是同一个变量都是同一个最终值
for (let i = 0; i < 5; ++i) {setTimeout(() => console.log(i), 0)
}
// 会输出 0、1、2、3、4
使用let的时候,JavaScript 引擎在后台会为每个迭代循环声明一个新的迭代变量。每个 setTimeout引用的都是不同的变量实例,所以 console.log输出的是我们期望的值,也就是循
环执行过程中每个迭代变量的值。
7、const声明
const 的行为与 let 基本相同:不允许重复声明、作用域也是块,区别在于它声明变量时同时初始化变量,修改const声明的变量会导致运行时错误,即常量不能修改。
但如果 const变量引用的是一个对象,那么修改这个对象内部的属性并不违反 const的限制。
const age = 26;
age = 36; // TypeError: 给常量重复赋值会报错
const person = {};
person.name = 'Matt'; // ok
const在for循环中,只能适用于声明一个不会被修改的常量
es6增加了const和let能更精确的声明作用域和语义,怪异的var容易导致出很多不必要的问题。要多限制自己使用let和const,const优先、let次之这样可提升代码质量
8、数据类型
es有6种简单(原始、基本)数据类型:undefined、null、number、string、boolean、symbol(符号)
复杂数据类型:object对象
9、typeof
typeof确定变量的数据类型,会返回如下字符串。对未声明的变量,只能执行一个有用的操作,就是对它调用 typeof。而返回的都是undefined
undefined:未定义
Boolean:布尔值
string:字符串
symbol:符号
number:数字
function:函数
object:表示值为对象(而不是函数)或 null;
例:
console.log(typeof 29); // number
let msg = "hello";
console.log(typeof msg);// string
typeof null; // object,特殊值null会被认为是对一个空对象的引用
10、数据类型详细介绍
10.1数据类型:undefined 基本数据类型
console.log(typeof 29); // number
let msg = "hello";
console.log(typeof msg);// string
typeof null; // object,特殊值null会被认为是对一个空对象的引用
当var或let声明了没初始化时,就相当于赋值了undefined
let msg;
console.log(msg == undefined);//true
10.2数据类型:null 基本数据类型
特殊值 null 值表示一个空对象指针,这也是给typeof传一个 null会返回"object"的原因。
let happy = null;
console.log(typeof(happy));//object
在定义将来要保存对象值的变量时,建议使用 null来初始化,不要使用其他值。这样,只要检查这个变量的值是不是null,就可以知道这个变量是否被重新赋值
undefined 值是由 null 值派生而来的,所以他们表面上相等,但不完全相等
null == undefined;//true
null === undefined;//false
null 和 undefined的用途不一样,undefined 未定义的初始化,而null空对象指针的语义
是在变量无对象可保存的时候来填充使用。这样语义上可以将两者区分开来。
null是假值
if(null){//false 不会执行
}
if(!null){//true 会执行
}
10.3数据类型:boolean 基本数据类型
boolean:true 和false。区别大小写,可以调用Boolean()方法把其他值转为布尔值
let msg = "know";
let msgBoolean = Boolean(msg);
其他数据类型转换Boolean的规则:
if语句会自动使用以上规则将其他数据转换成布尔值
10.4数据类型:Number 基本数据类型
使用八进制和十六进制格式创建的数值在所有数学操作中都被视为十进制数值,
由于 JavaScript 保存数值的方式,实际中可能存在正零(+0)和负零(-0)。正零和负零在所有情况下都被认为是等同的
浮点值:
数值中必须包含小数点,存储浮点值使用的内存空间是存储整数值的两倍,在小数点后面没有数字的情况下,数值就会变成整数。
数值跟一个大写或小写的字母 e,再加上一个要乘的 10 的多少次幂:
let floatNum = 3.125e7; // 等于 31250000 以 3.125 作为系数,乘以 10 的 7 次幂
浮点值的精确度最高可达 17 位小数
如果某个计算得到的数值结果超出了 JavaScript 可以表示的范围,那么这个数值会被自动转换为一个特殊的 Infinity(无穷)值。任何无法表示的负数以-Infinity(负无穷大)表示,正数以 Infinity(正无穷大)表示。Infinity 不能再进行计算
10.5数据类型:NaN
有一个特殊的数值叫 NaN,意思是“不是数值”(Not a Number),用于表示本来要返回数值的操作失败了(而不是抛出错误)在 ECMAScript 中,0、+0 或-0 相除会返回 NaN。
NaN不等于包括 NaN在内的任何值,任何涉及 NaN的操作始终返回 NaN:
console.log(NaN == NaN);//false
isNaN()函数判断这个参数是否“不是数值”,不能转为数值的会返回false
console.log(isNaN(NaN));// true
console.log(isNaN(10));// false,10是数值
console.log(isNaN("10"));// false,可以转换为数值 10
console.log(isNaN("blue")); // true,不可以转换为数值
console.log(isNaN(true)); // false,可以转换为数值 1
数值转换方法:
将非数值转换为数值:Number()、parseInt()和 parseFloat()。
用 Number()函数转换字符串有点反常规,在需要字符串转整数时可以优先使用 parseInt()函数。
parseInt()接收第二个参数,用于指定进制数。parseFloat()函数只解析十进制值,不可指定进制数,没有小数点或者小数点后面只有一个零则返回整数。
10.5数据类型:String 基本数据类型
下面的代码都是合法表示字符串:
let firstName = "John";
let lastName = 'Jacob';
let lastName = `Jingleheimerschmidt`
//开头和结尾的引号必须是同一种
toString()方法返回当前值的字符串等价物,可用于数值、布尔值、对象和字符串值,null和 undefined值没有 toString()方法,直接返回这两个值的字面量文本
let value3 = null;
let value4;
console.log(String(value3)); // "null"
console.log(String(value4)); // "undefined"
字符串值也有 toString()方法返回的是自身的一个副本,数值调用toString()可以接收一个底数(进制)参数来输出得到数值的几进制的字符串。
let num = 10;
console.log(num.toString());// "10"
console.log(num.toString(2));// "1010"
console.log(num.toString(8));// "12"
console.log(num.toString(10)); // "10"
console.log(num.toString(16));// "a"
10.5.1模板字面量
es6新增,模板字面量可以直接保留换行字符,可以跨行定义字符串
let myMultiLineString = 'first line\nsecond line';
let myMultiLineTemplateLiteral = `first line
second line`;
console.log(myMultiLineTemplateLiteral);console.log(myMultiLineString);
// first line
// second line"
模板字面量会保持反引号内部的空格,所以判断字符串长度时,会包含空格的长度
10.5.2字符串插值
字符串插值 所有插入的值都会使用 toString()强制转型为字符串,以前字符串插值这样实现:
let val = 6;
let str1 = "hello";
let str2 = str1 + 'haha,' +'number is'+(val*val);
使用字符串插值 ${} 和模板字面量`` 可以这样实现:
let str3 = `${str1} haha, number is ${val*val}`;
任何 JavaScript 表达式都可以用于插值,所有插入的值都会使用 toString()强制转型为字符串,嵌套的模板字符串无须转义:
let foo = {toStr:()=> 'world'
};
console.log(`hello,${ foo }!);
在插值表达式中可以调用函数和方法:
function capitalize(word) {
return `${ word[0].toUpperCase() }${ word.slice(1) }`;
}
console.log(`${ capitalize('hello') }, ${ capitalize('world') }!`); // Hello, World!
模板也可以插入自己之前的值:
let value = '';
function append() {value = `${value}abc`console.log(value);
}
append(); // abc
append(); // abcabc
append(); // abcabcabc
10.5.3原始字符串
String.raw标签函数,获取原始的模板字面量内容
// 换行符示例
console.log(`first line\nsecond line`);
// first line
// second line
console.log(String.raw`first line\nsecond line`); // "first line\nsecond line"
10.6数据类型:Symbol类型 基本数据类型
Symbol(符号)符号是原始值,且符号实例是唯一、不可变的。符号的用途是创建唯一记号,确保对象属性使用唯一标识符,不会发生属性冲突的危险,进而用作非字符串形式的对象属性。没有模板字面量的方法、只能接收字符串
let a = Symbol();
let b = Symbol();
console.log(a == b); //false
最重要的是Symbol()函数不能与 new关键字一起作为构造函数使用。这样做是为了避免创建符号包装对象。
let mySymbol = new Symbol(); // TypeError: Symbol is not a constructor
Symbol.for()方法全局复用符号
let aa = Symbol.for('foo');// 创建新符号
let bb = Symbol.for('foo'); // 重用已有符号
let cc = Symbol('foo');//没有用全局
console.log(aa === bb);//true
console.log(bb === cc);//false 全局和直接定义的不能等同
Symbol.keyFor()方法接收和查询
如果不是全局符号会返回undefined,否则返回对应的字符串
let s = Symbol.for('ss');
console.log(Symbol.keyFor(s));//ss
let s1 = Symbol('s1');
console.log(Symbol.keyFor(s1));//undefined 非全局返回未定义
10.6数据类型:Object类型 复杂数据类型
对象其实就是一组数据和功能的集合,对象通过 new操作符后跟对象类型的名称来创建。然后再给对象添加属性和方法。Object是一种复杂数据类型,它是这门语言中所有对象的基类。
let o = new Object();
let o = new Object; // 合法,但不推荐
每个 Object实例都有如下属性和方法。
constructor:用于创建当前对象的函数。在前面的例子中,这个属性的值就是 Object()
函数。
isPrototypeOf(object):用于判断当前对象是否为另一个对象的原型。(第 8 章将详细介绍
原型。)
propertyIsEnumerable(propertyName):用于判断给定的属性是否可以使用(本章稍后讨
论的)for-in语句枚举。与 hasOwnProperty()一样,属性名必须是字符串。
toLocaleString():返回对象的字符串表示,该字符串反映对象所在的本地化执行环境。
toString():返回对象的字符串表示。
valueOf():返回对象对应的字符串、数值或布尔值表示。通常与 toString()的返回值相同。
11、操作符
可用于各种值,包括字符串、数值、布尔值,甚至还有对象。在应用给对象时,操作符通常会调用 valueOf()和/或 toString()方法来取得可以计算的值。
一元操作符
let age = 29;
++age;//30,等于age = age + 1;
--age;//29,等于age = age - 1;
后缀版与前缀版的主要区别在于,后缀版递增和递减在语句被求值后才发生
let num1 = 2;
let num2 = 20;
let num3 = num1-- + num2;
let num4 = num1 + num2;
计算 num3时使用的是 num1的原始值(2),而计算 num4时使用的是 num1递减后的值(1)。非数值,会执行与使用 Number()转型函数一样的类型转换
11.1布尔操作符
逻辑非 !
逻辑与 &&
如果其中一个操作数不符合条件,则返回另一个符合条件的。
逻辑或 ||
与逻辑与类似,返回符合条件的
11.2乘性操作符
乘法 *
不能表示乘积,则返回 Infinity 或-Infinity,有任一操作数是 NaN,则返回 NaN
除法 /
跟乘法操作符一样,如果是 0 除以 0,则返回 NaN
取模 取余 %
let result = 26 % 5; // 等于 1
11.3指数操作符
Math.pow()现在有了自己的操作符**
console.log(Math.pow(3, 2);// 9
console.log(3 ** 2);// 9
加性操作符 +
关系操作符:
小于(<)、大于(>)、小于等于(<=)和大于等于(>=),而字符串相比较是比较编码
相等操作符 ==
不等于 !=
会先进行类型转换(通常称为强制类型转换)再确定操作数是否相等
全等 ===
比较相等时不转换操作数
let result1 = ("55" == 55);// true,转换后相等
let result2 = ("55" === 55); // false,不相等,因为数据类型不同
不全等 !===
由于相等和不相等操作符存在类型转换问题,因此推荐使用全等和不全等操作符。这样有助于在代码中保持数据类型的完整性。
11.4条件操作符
variable = boolean_expression ? true_value : false_value;
//条件成立吗?成立true : 不成立false
12、循环
if语句
if(条件){条件成立的操作;
} else if(条件){条件成立的操作;
}else{以上都不成立的操作;
}
花括号省略写法
let i = 30
if (i > 25) console.log("大于 25.")
else console.log("小于 25.");
do-while语句
do-while语句是一种后测试循环语句,即循环体中的代码执行后才会对退出条件进行求值。换句话说,循环体内代码在退出前至少要执行一次。
let i = 0;
do {i += 2;
} while (i > 10);
console.log(i);//2
while语句
先测试循环语句,条件符合才会再执行
let i = 0;
while (i > 10) {i += 2;
}
console.log(i);//0
for语句
for语句也是先测试语句,只不过增加了进入循环之前的初始化代码
let count = 10;
for (let i = 0; i < count; i++) {console.log(i);
}
let count = 10;
let i = 0;
while (i < count) {console.log(i);i++;
}
这两个代码一样
初始化、条件表达式和循环后表达式都不是必需的。因此,下面这种写法可以创建一个无穷循环:
for (初始化变量; 条件表达式; 循环后表达式) { // 循环体 }
for (;;) { // 无穷循环doSomething();
}
如果只包含条件表达式,那么 for循环实际上就变成了 while循环:
let count = 10;
let i = 0;
for (; i < count; ) {console.log(i);i++;
}
for-in语句
for-in语句是一种严格的迭代语句,用于枚举对象中的非符号键属性,在 for in 中可以使用 break 或者 continue 去中断循环,不可以直接用 return 去中断循环
如果 for-in循环要迭代的变量是 null或 undefined,则不执行循环体(枚举就是遍历)
const obj = {a: 'a',b: 'b',c: 'c',[Symbol('a')]: '我是 symbol',
}
// 循环中断
for (let key in obj) {if (key === 'b') {break}console.log('obj.' + key + ' = 我是' + obj[key])
}
//obj.a = 我是a
for-of语句
for-of语句是一种严格的迭代语句,用于遍历可迭代对象的元素
for (const el of [2,4,6,8]) {//const 非必须document.write(el);//2468
}
es2018增加了 for-await-of循环,在后面章节
13、标签语句
break
立即退出循环,强制执行循环后的下一条语句
continue
立即退出循环,但会再次从循环顶部开始执行。(跳出符合条件再重新执行)
let num = 0;
for (let i = 1; i < 10; i++) {if (i % 5 == 0) {break;//此处如果换成continue}num++;
}
console.log(num); // 4
//换成continue后打印num为8
with语句
使用 with语句的主要场景是针对一个对象反复操作,将代码作用域设置为该对象能提供便
利。
严格模式不允许使用 with语句,否则会抛出错误,with语句影响性能且难于调试其中的代码不推荐使用
let qs = location.search.substring(1);
let hostName = location.hostname;
let url = location.href;
//上面代码中的每一行都用到了 location对象。如果使用 with语句,就可以少写一些代码:
with(location) {let qs = search.substring(1);let hostName = hostname;let url = href;
}
switch语句
switch( 表达式 ){
case value1:
// 表达式 等于 value1 时要执行的代码
break;
case value2:
// 表达式 等于 value2 时要执行的代码
break;
default:
// 表达式 不等于任何一个 value 时要执行的代码
}
if (i == 25) {console.log("25");
} else if (i == 35) {console.log("35");
} else if (i == 45) {console.log("45");
} else {console.log("Other");
}
//等同于:
switch (i) {case 25:console.log("25");break;case 35:console.log("35");break;case 45:console.log("45");break;default:console.log("Other");
}
switch 语句在比较每个条件的值时会使用全等操作符,因此不会强制转换数据类型(比如,字符串"10"不等于数值 10)。
case(条件/分支)相当于:“如果表达式等于后面的值,则执行下面的语句。”
break关键字会导致代码执行跳出 switch语句。
default关键字用于在任何条件都没有满足时指定默认执行的语句(相当于 else语句)
14、函数
函数对任何语言来说都是核心组件,因为它们可以封装语句,然后在任何地方、任何时间执行。第 10 章会更详细地介绍函数
以下是函数的基本语法:
function 关键字(参数0, 参数1,...,参数N) {
函数体;
}
关键字(参数0,参数1...);//函数名来调用函数
函数不需要指定是否返回值。任何函数在任何时间都可以使用 return 语句来返回函数的值,用法是后跟要返回的值。比如:
function sum(num1, num2) {let num3 = num1 + num2;return num3;console.log('测试',num3);//不会执行
}
console.log(sum(1,2));//3
要注意的是,只要碰到 return语句,函数就会立即停止执行并退出。因此,return语句后面的
代码不会被执行
return语句也可以不带返回值。这时候,函数会立即停止执行并返回 undefined。这种用法最常用于提前终止函数执行,并不是为了返回值。
function sayHi(name, message) {
return;
console.log("Hello " + name + ", " + message); // 不会执行
}
严格模式对函数也有一些限制:
函数不能以 eval或 arguments作为名称;
函数的参数不能叫 eval或 arguments;
两个命名参数不能拥有同一个名称。
如果违反上述规则,则会导致语法错误,代码也不会执行。
目录
1、ECMAScript 标识符 和注释
2、严格模式
3、语句
4、变量
5、Var
var 局部作用域
6、let
7、const声明
8、数据类型
9、typeof
10、数据类型详细介绍
10.1数据类型:undefined 基本数据类型
10.2数据类型:null 基本数据类型
10.3数据类型:boolean 基本数据类型
10.4数据类型:Number 基本数据类型
10.5数据类型:NaN
数值转换方法:
10.5数据类型:String 基本数据类型
10.5.1模板字面量
10.5.2字符串插值
10.5.3原始字符串
10.6数据类型:Symbol类型 基本数据类型
Symbol.for()方法全局复用符号
Symbol.keyFor()方法接收和查询
11、操作符
一元操作符
11.1布尔操作符
逻辑非 !
逻辑与 &&
逻辑或 ||
11.2乘性操作符
乘法 *
除法 /
11.3指数操作符
加性操作符 +
关系操作符:
相等操作符 ==
不等于 !=
全等 ===
不全等 !===
11.4条件操作符
12、循环
if语句
do-while语句
while语句
for语句
for-in语句
for-of语句
13、标签语句
break
continue
with语句
switch语句
14、函数
javascript 高级程序设计(第4版)阅读笔记(三)相关推荐
- 阅读JavaScript高级程序设计(第二版)笔记
第一章js简介 JavaScript诞生在1995年,当时负责进行输入型验证. JavaScript是一种专为与网页交互而设计的脚本语言,分为 : 1. ECMAScript核心语言功能. 2.文档对 ...
- JavaScript高级程序设计[第3版]
JavaScript高级程序设计[第3版] package xyz.huning.toolkit.pdf;import java.io.FileOutputStream; import java.io ...
- JavaScript高级程序设计第四版学习--第二十四章
title: JavaScript高级程序设计第四版学习–第二十四章 date: 2021-5-31 10:46:01 author: Xilong88 tags: JavaScript 本章内容: ...
- JavaScript高级程序设计 第4版----String
JavaScript高级程序设计 第4版----String 文章目录 JavaScript高级程序设计 第4版----String 1.JavaScript 字符 2.字符串操作方法 1.conca ...
- 《JavaScript高级程序设计 第3版》-学习笔记-1
P1-P30页 1.<script>标签的属性 async:async(html) | async="async"(xhtml),表示立即下载脚本,但不马上执行(执行 ...
- 新书-JavaScript高级程序设计:第2版(预订中,估价)
http://www.china-pub.com/196857 JavaScript的应用在广度和深度上日益扩大和加深,前端开发亟待掌握的JavaScript技能也越来越具有挑战性. 这个新版本几乎全 ...
- JavaScript 权威指南--第七版--阅读笔记--number 部分
Number 数字类型 JavaScript 的主要数字类型 Number 用于表示整数和近似实数. 当一个数字直接出现在 JavaScript 程序中时,它被称为 数字文字.JavaScript 支 ...
- JavaScript高级程序设计红宝书学习笔记第三章基本概念
第三章 基本概念 本章内容 语法 数据类型 操作符 语句 函数 3.1 语法 3.1.1 区分大小写,ECMAScript中的一切(变量.函数名和操作符)都区分大小写. 3.1.2 标识符 标识符:变 ...
- javascript高级程序设计第3版——第6章 面向对象的程序设计
第六章--面向对象的程序设计 这一章主要讲述了:面向对象的语言由于没有类/接口情况下工作的几种模式以及面向对象语言的继承: 模式:工厂模式,构造函数模式,原型模式 继承:原型式继承,寄生式继承,以及寄 ...
最新文章
- idea 配置多个jdk
- 新书上架:《Java SE 实践教程》
- Asp.Net性能优化.
- MySQL数据库优化实战
- 高斯噪声调频matlab,基于MATLAB的2ASK调制与解调设计
- .NET 分布式架构开发实战之二 草稿设计
- 什么是套接字?Socket基本介绍
- [渝粤教育] 西南科技大学 车辆构造 在线考试复习资料
- 深度学习环境搭建之Anaconda安装keras
- SpringMVC 日期类型转换
- Regex.Match 方法
- 没有智能安防 智能家居只是一座空中楼阁
- 使用cocoapods install友盟时报错Error installing UMengAnalytics
- 科研管理系统java源码_(高校科研管理系统)
- vue加载中图片和加载失败图片的占位图
- Mimics:修改像素单位
- PTA查验身份证 (15 分) 一个合法的身份证号码由17位地区、日期编号和顺序编号加1位校验码组成。
- spring boot中如何实现在手机注册和登录时获取验证码(阿里短信服务)
- 关于在Idea里面修改html代码后,打开网页没改变的问题
- 跟谁一起工作,到底有多重要?
热门文章
- Ricoh C4500打印装订位置设置
- 通过ipmi无法从pci网卡启动pxe模式
- sqli-lab 6
- java飞机场模拟程序_基于JAVA的机场航班起降与协调管理系统.ppt
- 谁说抠图要会 PS?这个开源神器还能批量抠,效果拔群!
- 使用msf发动攻击后显示-Host does NOT appear vulnerable.的问题
- python爬虫学习文档整理
- Linux C/C++编程之(十)动态库的制作和使用
- skt计算机仿真,基于AnyCasting的机床床身铸造工艺计算机仿真与优化_朱旭刚
- 交通标志识别Python+TensorFlow实现(QT界面+WEB界面)