网站托管运营方案/杭州网络排名优化
初识ES6
ECMAScript 6.0(以下简称 ES6)是 JavaScript 语言的下一代标准,已经在 2015 年 6 月正式发布了。它的目标,是使得 JavaScript 语言可以用来编写复杂的大型应用程序,成为企业级开发语言。
-
1997年:ECMAScript 1.0
-
1998年:ECMAScript 2.0
-
1999年:ECMAScript 3.0
-
2006年:ECMAScript 4.0 未通过
-
2009年:ECMAScript 5.0
-
2015年:ECMAScript 6.0
-
至今,版本号改用年号的形式。
变量声明
1、let与const不可重复声明(数据不会覆盖)
// varvar a = 10;var a = 20;console.log(a); // 20 // letlet b = 10;// let b = 20; // SyntaxError: Identifier 'b' has already been declared// constconst c = 10;// const c = 20; // SyntaxError: Identifier 'c' has already been declared
2、let
和 const
声明的变量不会在预解析的时候解析(也就是没有变量提升)
console.log(num1)var num1 = 10; // undefinedconsole.log(num2)let num2 = 20; // ReferenceError: Cannot access 'num2' before initializationconsole.log(num3)const num3 = 30; // ReferenceError: Cannot access 'num3' before initialization
3、let
和 const
声明的变量会被所有代码块限制作用范围
(var只有函数限制作用域,let、const 声明的变量,除了函数可以限制,所有的代码块都可以限制其作用域(if/while/for/...)
if(true){var numVar = 10;}console.log(numVar); // 10if(true){let numLet = 20;}// console.log(numLet); // ReferenceError: numLet is not definedif(true){const numConst = 30;}// console.log(numConst); // ReferenceError: numConst is not defined
4、let声明的变量的值可以改变,const声明的值不可改变
//let和const区别let lnum = 100lnum = 200console.log(lnum)const cnum = 100cnum = 200
5、let声明的时候可以不赋值,const声明时必须赋值
解构赋值
对象解构
const Ian = {name:'IIIIIan',age:0}// console.log(name,age) // 报错,因为name和age是Ian对象的属性,不是全局变量const {name,age} = Ianconsole.log(name,age)
数组解构
const arr = [1,2,3]console.log(arr[0],arr[1],arr[2])// 1 2 3, 传统写法console.log(arr)// [1,2,3]console.log(...arr)// 1 2 3, 展开运算符console.log([...arr])// [1,2,3]// 解构赋值const [a,b,c] = arrconsole.log('a,b,c',a,b,c)
模版字符串
ES5 中我们表示字符串的时候使用 ''
或者 ""
在 ES6 中,我们还有一个东西可以表示字符串,就是 ``(反引号)
let str = `hello world`
console.log(typeof str) // string
1、``允许字符串换行
2、反引号可以直接在字符串里面拼接变量
// 模版字符串拼接变量
let num = 100
let str = `hello${num}world${num}`
console.log(str) // hello100world100
字符串扩展
includes()
判断字符串中是否存在指定字符
repeat()
返回一个新字符串,表示将原字符串重复n次。
startsWith()
返回布尔值,表示参数字符串是否在原字符串的头部。
endsWith()
返回布尔值,表示参数字符串是否在原字符串的尾部。
let str = 'hello world'console.log(str.includes('hello')) // trueconsole.log(str.startsWith('hello')) // trueconsole.log(str.endsWith('world')) // trueconsole.log(str.startsWith('ian')) // falseconsole.log(str.repeat(3)) // hello worldhello worldhello world
数值扩展
二进制和八进制表示法
let count1 = 100
let count2 = 0x100
let count3 = 0o100
let count4 = 0b100
(Number.)isFinite()与isNaN()
// isFinite 和 isNaN// isFinite():用来检查一个数值是否为有限的(finite),即不是Infinity。// isNaN():用来检查一个值是否为NaN。console.log('1/3',isFinite(1/3)) console.log('0',isFinite(0)) // trueconsole.log('Infinity',isFinite(Infinity)) // falseconsole.log('NaN',isFinite(NaN)) // falseconsole.log('NaN',isNaN(NaN)) // trueconsole.log('0',isNaN(0)) // falselet num1 = Number.isFinite(100) //truelet num2 = Number.isFinite(100/0) //falselet num3 = Number.isFinite(Infinity) // falselet num4 = Number.isFinite("100") //falselet num1 = Number.isNaN(100) // falselet num2 = Number.isNaN(NaN) //truelet num3 = Number.isNaN("kerwin") //falselet num4 = Number.isNaN("100") // false
减少全局性方法,使得语言逐步模块化,它们与传统的全局方法isFinite()和isNaN()的区别在于,传统方法先调用Number()将非数值的值转为数值,再进行判断,而这两个新方法只对数值有效,Number.isFinite()对于非数值一律返回false, Number.isNaN()只有对于NaN才返回true,非NaN一律返回false。
Number.isInteger()
判断是否为整数
console.log('NaN',Number.isInteger('NaN')) // falseconsole.log('NaN',Number.isInteger(NaN)) // falseconsole.log('0',Number.isInteger(0)) // trueconsole.log('0.1',Number.isInteger(0.1)) // false
Math.trunc
将小数部分抹掉,返回一个整数。
console.log(Math.trunc(1.2)) //1console.log(Math.trunc(1.8))// 1console.log(Math.trunc(-1.8)) //-1console.log(Math.trunc(-1.1))//-1
Math.sign
Math.sign
方法用来判断一个数到底是正数、负数、还是零。对于非数值,会先将其转换为数值。
console.log(Math.sign(1)) // 1console.log(Math.sign(-1)) // -1console.log(Math.sign(0)) // 0console.log(Math.sign(-0)) // -0console.log(Math.sign(NaN)) // NaNconsole.log(Math.sign('ian')) // NaN
数组扩展
...扩展运算符
let arr1 = [1,2,3]
let arr2 = [4,5,6]console.log([...arr1,...arr2])
Array.from
将类数组对象转换为真正数组
function test(){console.log(Array.from(arguments))
}test(1,2,3)let oli = document.querySelectorAll("li")
console.log(Array.from(oli))
Array.of
let arr1 = Array(3)console.log('arr1',arr1);let arr2 = Array.of(3)console.log('arr2',arr2);
find方法
1)该方法主要应用于查找第一个符合条件的数组元素
2)它的参数是一个回调函数。在回调函数中可以写你要查找元素的条件,当条件成立为true时,返回该元素。如果没有符合条件的元素,返回值为undefined
let arr = [11,12,13,14,15]let res1 = arr.find(function(item){return item>13})let res2 = arr.findIndex(function(item){return item>13})let res3 = arr.find(function(item){return item>16})console.log(res1) //14console.log(res2) //3console.log(res3) //undefined
fill方法
使用自己想要的参数替换原数组内容,但是会改变原来的数组
方法用一个固定值填充一个数组中从起始索引(默认为 0
)到终止索引(默认为 array.length
)内的全部元素。它返回修改后的数组。
let arr11 = new Array(3).fill("Ian")
let arr22 = ['a', 'b', 'c'].fill("Ian", 1, 2)
console.log(arr11)//['Ian', 'Ian', 'Ian']
console.log(arr22)// ['a', 'Ian', 'c']// MDN示例const array1 = [1, 2, 3, 4];// Fill with 0 from position 2 until position 4
console.log(array1.fill(0, 2, 4));
// Expected output: Array [1, 2, 0, 0]// Fill with 5 from position 1
console.log(array1.fill(5, 1));
// Expected output: Array [1, 5, 5, 5]console.log(array1.fill(6));
// Expected output: Array [6, 6, 6, 6]
flat与flatMap方法
flatMap()按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回
flat()
方法创建一个新的数组,并根据指定深度递归地将所有子数组元素拼接到新的数组中。
// MDN示例const arr1 = [0, 1, 2, [3, 4]];console.log(arr1.flat());
// expected output: Array [0, 1, 2, 3, 4]const arr2 = [0, 1, [2, [3, [4, 5]]]];console.log(arr2.flat());
// expected output: Array [0, 1, 2, Array [3, Array [4, 5]]]console.log(arr2.flat(2));
// expected output: Array [0, 1, 2, 3, Array [4, 5]]console.log(arr2.flat(Infinity));
// expected output: Array [0, 1, 2, 3, 4, 5]
var obj = [{name: "A",list: ["鞍山", "安庆", "安阳"]},{name: "B",list: ["北京", "保定", "包头"]}
]
console.log(obj.flatMap(item => item.list))//["鞍山", "安庆", "安阳", "北京", "保定", "包头"]
对象扩展
对象简写
let name ="moduleA"let obj = {name,test1(){console.log('test1',this.name)},test2(){console.log('test2',this.name)}}obj.test1()obj.test2()console.log(obj)console.log(obj.name)obj.name = "moduleB"console.log(obj.name)
属性名表达式
let name1 ="moduleA"let obj1 = {name1,[name1+"test1"](){},[name1+"test2"](){}}console.log(obj1)
Object.assign
Object.assign(target, object1,object2)的第一个参数是目标对象,后面可以跟一个或多个源对象作为参数。
target:参数合并后存放的对象
object1:参数1
object2:参数2
const a = {name:"Ian"}const b = {age:18}const c = {height:180}Object.assign(a,b,c)console.log(a)
Object.is
方法判断两个值是否是相同的值
console.log(NaN===NaN) //false
console.log(+0===-0) //trueconsole.log(Object.is(NaN,NaN)) //true
console.log(Object.is(+0,-0)) //false
函数扩展
箭头函数
-
箭头函数是 ES6 里面一个简写函数的语法方式
-
重点: 箭头函数只能简写函数表达式,不能简写声明式函数
function fn() {} // 不能简写
const fun = function () {} // 可以简写
const obj = {fn: function () {} // 可以简写
}
语法: (函数的行参) => { 函数体内要执行的代码 }
const fn = function (a, b) {console.log(a)console.log(b)
}
// 可以使用箭头函数写成
const fun = (a, b) => {console.log(a)console.log(b)
}
const obj = {fn: function (a, b) {console.log(a)console.log(b)}
}
// 可以使用箭头函数写成
const obj2 = {fn: (a, b) => {console.log(a)console.log(b)}
}
箭头函数的特殊性
箭头函数内部没有 this,箭头函数的 this 是上下文的 this
// 在箭头函数定义的位置往上数,这一行是可以打印出 this 的
// 因为这里的 this 是 window
// 所以箭头函数内部的 this 就是 window
const obj = {fn: function () {console.log(this)},// 这个位置是箭头函数的上一行,但是不能打印出 thisfun: () => {// 箭头函数内部的 this 是书写箭头函数的上一行一个可以打印出 this 的位置console.log(this)}
}obj.fn()
obj.fun()
-
按照我们之前的 this 指向来判断,两个都应该指向 obj
-
但是 fun 因为是箭头函数,所以 this 不指向 obj,而是指向 fun 的外层,就是 window
箭头函数内部没有 arguments
这个参数集合
const obj = {fn: function () {console.log(arguments)},fun: () => {console.log(arguments)}
}
obj.fn(1, 2, 3) // 会打印一个伪数组 [1, 2, 3]
obj.fun(1, 2, 3) // 会直接报错
函数的行参只有一个的时候可以不写 ()
其余情况必须写
const obj = {fn: () => {console.log('没有参数,必须写小括号')},fn2: a => {console.log('一个行参,可以不写小括号')},fn3: (a, b) => {console.log('两个或两个以上参数,必须写小括号')}
}
函数体只有一行代码的时候,可以不写 {}
,并且会自动 return
const obj = {fn: a => {return a + 10},fun: a => a + 10
}console.log(fn(10)) // 20
console.log(fun(10)) // 20
函数传递参数的时候的默认值
function fn(a) {a = a || 10console.log(a)
}
fn() // 不传递参数的时候,函数内部的 a 就是 10
fn(20) // 传递了参数 20 的时候,函数内部的 a 就是 20
-
在 ES6 中我们可以直接把默认值写在函数的行参位置
function fn(a = 10) {console.log(a)
}
fn() // 不传递参数的时候,函数内部的 a 就是 10
fn(20) // 传递了参数 20 的时候,函数内部的 a 就是 20
// 箭头函数也可以使用
const fn = (a = 10) => {console.log(a)
}
fn() // 不传递参数的时候,函数内部的 a 就是 10
fn(20) // 传递了参数 20 的时候,函数内部的 a 就是 20
注意: 箭头函数如果需要使用默认值,那么一个参数的时也需要写 ()
Symbol
ES6 引入了一种新的原始数据类型
Symbol
,表示独一无二的值。它属于 JavaScript 语言的原生数据类型之一,其他数据类型是:undefined
、null
、布尔值(Boolean)、字符串(String)、数值(Number)、对象(Object)。
1.使用Symbol作为对象属性名
let name = Symbol()let age = Symbol()var obj = {[name]: '张三',[age]: 18}age = 20// 这里的 age 是一个普通的字符串,不是 Symbol 类型的console.log(obj)let a = Symbol('A')let b = Symbol('A')console.log(a === b) // false
2.Symbol()函数可以接受一个字符串作为参数,表示对 Symbol 实例的描述。这主要是为了在控制台显示,比较容易区分。
let NickName = Symbol('NickName')let obj1 = {[name]: '张三',[NickName]: 'ian'}console.log(obj1)
3.遍历问题
let keys = {name:Symbol("name"),age:Symbol("age")}var obj ={[keys.name]:"Ian",[keys.age]:100,a:1,b:2,c:3}Reflect.ownKeys(obj).forEach(item=>{console.log(item,obj[item])})
4.Symbol.for()可以重新使用同一个 Symbol 值
var obj ={[Symbol.for("name")]:"Ian",[Symbol.for("age")]:100}console.log(obj[Symbol.for("name")])
Iterator迭代器
Iterator 的作用有三个:
一是为各种数据结构,提供一个统一的、简便的访问接口;
二是使得数据结构的成员能够按某种次序排列;
三是 ES6 创造了一种新的遍历命令for...of循环,Iterator 接口主要供for...of循环
let arr = ["kerwin", "tiechui", "gangdaner"]for(let i of arr){console.log(i)
}
Iterator 的遍历过程:
(1)创建一个指针对象,指向当前数据结构的起始位置。也就是说,遍历器对象本质上,就是一个指针对象。
(2)第一次调用指针对象的next方法,可以将指针指向数据结构的第一个成员。
(3)第二次调用指针对象的next方法,指针就指向数据结构的第二个成员。
(4)不断调用指针对象的next方法,直到它指向数据结构的结束位置。
let i = arr[Symbol.iterator]()
console.log(i.next())
console.log(i.next())
console.log(i.next())
console.log(i.next())
ES6 规定,默认的 Iterator 接口部署在数据结构的Symbol.iterator属性,或者说,一个数据结构只要具有Symbol.iterator属性,就可以认为是“可遍历的”(iterable)。Symbol.iterator属性本身是一个函数,就是当前数据结构默认的遍历器生成函数。执行这个函数,就会返回一个遍历器。
原生默认具备 Iterator 接口的数据结构如下。
-
Array
-
Set
-
Map
-
String
-
arguments 对象
-
NodeList 对象
let obj = {0: "kerwin",1: "tiechui",2: "gangdaner",length: 3,[Symbol.iterator]: Array.prototype[Symbol.iterator]
}for (let i of obj) {console.log(i)
}let obj2 = {data: ['kerwin', 'tiechui', "gangdaner"],[Symbol.iterator]() {// let _this = thislet index = 0;return {next: () => {if (index < this.data.length) {return {value: this.data[index++],done: false}} else {return {value: undefined,done: true}}}}}
};for (let i of obj2) {console.log(i)
}
Set结构
它类似于数组,但成员的值都是唯一的,没有重复的值。
初识Set
let s1 = new Set([1, 2, 3, 2, 3])
console.log(s1)let s2 = new Set()
s2.add(1)
s2.add(2)
s2.add(3)
s2.add(3)
console.log(s2)
实例的属性和方法
-
size:返回Set实例的成员总数。
-
Set.prototype.add(value)
:添加某个value。 -
Set.prototype.delete(value)
:删除某个value,返回一个布尔值,表示删除是否成功。 -
Set.prototype.has(value)
:返回一个布尔值,表示该值是否为Set
的成员。 -
Set.prototype.clear()
:清除所有成员,没有返回值。
遍历
-
Set.prototype.keys()
:返回键名的遍历器 -
Set.prototype.values()
:返回键值的遍历器 -
Set.prototype.entries()
:返回键值对的遍历器 -
Set.prototype.forEach()
:遍历每个成员
复杂数据结构去重
function uni(arr) {let res = new Set()return arr.filter(item => {let id = JSON.stringify(item)if (res.has(id)) {return false} else {res.add(id)return true}})}var arr = [1, 2, 3, "data", {name: "Ian"}, {name: "Ian"},[1, 2],[3, 4],[3, 4]]console.log(uni(arr))
Map结构
类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。
初识Map
let m1 = new Map()m1.set("name","Ian")m1.set({a:1},"XX")console.log(m1)let m2= new Map([["name","Ian"],[{a:1},"XX"]])console.log(m2)
实例的属性和方法
-
size:返回 Map 结构的成员总数。
-
Map.prototype.set(key,value)
:添加key对应得value,返回 Map 结构本身。 -
Map.prototype.get(key)
:获取key对应的value -
Map.prototype.delete(key)
:删除某个键(键名+键值) -
Map.prototype.has(key)
:某个键是否在当前 Map 对象之中。 -
Map.prototype.clear()
:清除所有成员,没有返回值。
遍历
-
Map.prototype.keys():返回键名的遍历器。
-
Map.prototype.values():返回键值的遍历器。
-
Map.prototype.entries():返回所有成员的遍历器。
-
Map.prototype.forEach():遍历 Map 的所有成员。
Proxy代理
Proxy如其名, 它的作用是在对象和和对象的属性值之间设置一个代理,获取该对象的值或者设置该对象的值, 以及实例化等等多种操作, 都会被拦截住, 经过这一层我们可以统一处理,我们可以认为它就是“代理器”
get()
let target = {}
let proxy = new Proxy(target,{get(target,prop){return target[prop]}
})
set()
let target = {}
let proxy = new Proxy(target,{get(target,prop){return target[prop]},set(target,prop,value){if(prop==="data"){box.innerHTML = value}target[prop] = value;}
})
has()
let target = {_prop: "内部数据"
}
let proxy = new Proxy(target, {get(target, prop) {return target[prop]},set(target, prop, value) {if (prop === "data") {box.innerHTML = value}target[prop] = value;},has(target, key) {if (key[0] === '_') {return false;}return key in target;}
})
this
let target = new Set()
const proxy = new Proxy(target, {get(target, key) {const value = target[key]// 遇到 Function 都手动绑定一下 thisif (value instanceof Function) {console.log(`访问${value}方法了`)return value.bind(target)//不能 是 call apply }return value}
})
proxy.add(1)
Proxy本质上属于元编程非破坏性数据劫持,在原对象的基础上进行了功能的衍生而又不影响原对象,符合松耦合高内聚的设计理念。
Reflect对象
Reflect 可以用于获取目标对象的行为,它与 Object 类似,但是更易读,为操作对象提供了一种更优雅的方式。它的方法与 Proxy 是对应的。
代替Object的某些方法
const obj = {
};
Reflect.defineProperty(obj, 'name', {value: 'kerwin',writable: false,configurable:false
});
修改某些Object方法返回结果
// 老写法
try {Object.defineProperty(target, property, attributes);// success
} catch (e) {// fail
}// 新写法
if (Reflect.defineProperty(target, property, attributes)) {// success
} else {// fail
}
命令式变为函数行为
const obj = {name:"Ian"
};
//老写法
console.log("name" in obj) //true
//新写法
console.log(Reflect.has(obj, 'name')) //true//老写法
delete obj.name
//新写法
Reflect.deleteProperty(obj, "name")
配合Proxy
let target = new Set()
const proxy = new Proxy(target, {get(target, key) {const value = Reflect.get(target,key)// 遇到 Function 都手动绑定一下 thisif (value instanceof Function) {console.log(`访问${value}方法了`)return value.bind(target)//不能 是 call apply }return value},set() {return Reflect.set(...arguments)}
})
proxy.add(1)
let arr = [1, 2, 3]
let proxy = new Proxy(arr, {get(target, key) {console.log('get', key)return Reflect.get(...arguments)},set(target, key, value) {console.log('set', key, value)return Reflect.set(...arguments)}
})
proxy.push(4)
// 能够打印出很多内容
// get push (寻找 proxy.push 方法)
// get length (获取当前的 length)
// set 3 4 (设置 proxy[3] = 4)
// set length 4 (设置 proxy.length = 4)
Promise
Promise 是异步编程的一种解决方案,比传统的解决方案回调函数, 更合理和更强大。ES6 将其写进了语言标准,统一了用法,原生提供了Promise对象 。
回调地狱
-
当一个回调函数嵌套一个回调函数的时候
-
就会出现一个嵌套结构
-
当嵌套的多了就会出现回调地狱的情况
-
比如我们发送三个 ajax 请求
-
第一个正常发送
-
第二个请求需要第一个请求的结果中的某一个值作为参数
-
第三个请求需要第二个请求的结果中的某一个值作为参数
-
javascriptajax({url: '我是第一个请求',success (res) {// 现在发送第二个请求ajax({url: '我是第二个请求',data: { a: res.a, b: res.b },success (res2) {// 进行第三个请求ajax({url: '我是第三个请求',data: { a: res2.a, b: res2.b },success (res3) { console.log(res3) }})}})}})
Promise使用
new Promise(function (resolve, reject) {// resolve 表示成功的回调// reject 表示失败的回调
}).then(function (res) {// 成功的函数
}).catch(function (err) {// 失败的函数
})
Promise 对象的状态
Promise 对象通过自身的状态,来控制异步操作。Promise 实例具有三种状态。
异步操作未完成(pending) 异步操作成功(fulfilled) 异步操作失败(rejected)
这三种的状态的变化途径只有两种。
从“未完成”到“成功” 从“未完成”到“失败”
一旦状态发生变化,就凝固了,不会再有新的状态变化。这也是 Promise 这个名字的由来,它的英语意思是“承诺”,一旦承诺成效,就不得再改变了。这也意味着,Promise 实例的状态变化只可能发生一次。
因此,Promise 的最终结果只有两种。
异步操作成功,Promise 实例传回一个值(value),状态变为fulfilled。 异步操作失败,Promise 实例抛出一个错误(error),状态变为rejected。
Promise.all
Promise.all()
方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。
const p = Promise.all([p1, p2, p3]);
p的状态由p1,p2,p3 决定,分成两种情况。
(1)只有p1
、p2
、p3
的状态都变成fulfilled
,p
的状态才会变成fulfilled
,此时p1
、p2
、p3
的返回值组成一个数组,传递给p
的回调函数。
(2)只要p1
、p2
、p3
之中有一个被rejected
,p
的状态就变成rejected
,此时第一个被reject
的实例的返回值,会传递给p
的回调函数。
Promise.race
Promise.race()
方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例。
const p = Promise.race([p1, p2, p3]);
上面代码中,只要p1
、p2
、p3
之中有一个实例率先改变状态,p
的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p
的回调函数。
Generator 函数
Generator 函数是 ES6 提供的一种异步编程解决方案
Generator 函数是一个状态机,封装了多个内部状态。
执行 Generator 函数会返回一个遍历器对象,也就是说,Generator 函数除了状态机,还是一个遍历器对象生成函数。返回的遍历器对象,可以依次遍历 Generator 函数内部的每一个状态。
一般使用
function *gen(){console.log(1)yield;console.log(2)yield;console.log(3)
}let g = gen()
g.next()
g.next()
g.next()
yield(产出)表达式是暂停执行的标记,而next方法可以恢复执行。
function *gen(){yield 1;yield 2;
}let g = gen()
let res1 = g.next()
console.log(res1)
let res2 = g.next()
console.log(res2)
let res3 = g.next()
console.log(res3)
function *gen(){let res1 = yield;console.log(res1)let res2 = yield;console.log(res2)
}let g = gen()
g.next("data-1")
g.next("data-2")
g.next("data-3")
异步流程
// 手动代码
function *gen(){let res1 = yield ajax("1.json")console.log(res1)let res2 = yield ajax("2.json")console.log(res2)
}let g = gen() g.next().value.then(data=>{g.next(data).value.then(data=>{g.next(data)})
}) // 自动代码
function* gen() {let res1 = yield ajax("1.json")console.log(res1)let res2 = yield ajax("2.json")console.log(res2)
}function AutoRun(gen) {let g = gen();function next(data) {let res = g.next(data);if (res.done) return res.value.then(function (data) {next(data);});}next();
}AutoRun(gen);
Class语法
类的写法
// 创造一个自行车类class Bike{constructor(name, price){this.name = namethis.price = price}// 方法show(){console.log('这是一辆自行车'+this.name+'价格是'+this.price)}}// 实例化一个自行车let bike = new Bike('Giant', 2000)bike.show()console.log(bike)
Getter和Setter
class List{constructor(element){this.element = element}get html(){return this.element.innerHTML}set html(arr){this.element.innerHTML = arr.map(item=>`<li>${item}</li>`).join('')}}let list = new List(document.querySelector('#list'))list.html = ['a', 'b', 'c']
静态属性、静态方法
class Person {static name = "Person这个类"constructor(name,age){this.name = name;this.age = age;}say(){console.log(this.name,this.age)}static eat(){console.log("eat")}}let obj = new Person("Ian",100)console.log(Person.name)Person.eat()
继承
ES6 规定,子类必须在
constructor()
方法中调用super()
,否则就会报错。这是因为子类自己的this
对象,必须先通过父类的构造函数完成塑造,得到与父类同样的实例属性和方法,然后再对其进行加工,添加子类自己的实例属性和方法。如果不调用super()
方法,子类就得不到自己的this
对象。
class Person {static name = "Person这个类"constructor(name,age){this.name = name;this.age = age;}say(){console.log(this.name,this.age)}static eat(){console.log("eat")}
}
class Student extends Person{constructor(name,age,score){super(name,age)this.score = score}// 方法重写say(){super.say()console.log(this.score)}static eat(){super.eat();console.log("student eat")}
}
let obj1 = new Student("Ian",100,200)
console.log(obj1)
obj1.say()
Student.eat()
JavaScript 现在有两种模块。一种是 ES6 模块,简称 ESM;另一种是 CommonJS 模块,简称 CJS。
CommonJS 模块是 Node.js 专用的,与 ES6 模块不兼容。语法上面,两者最明显的差异是,CommonJS 模块使用
require()
和module.exports
,ES6 模块使用import
和export
。
// 方法一
export default A1import a1 from "./1.js"
// 方法二
export {A1,A2}import {A1,A2} from "./1.js"import {A1 as a1,A2 as a2} from "./1.js"import * as obj from "./1.js"export function A1(){console.log("A1")
}
export function A2(){console.log("A2")
}import {A1,A2} from "./1.js"import {A1 as a1,A2 as a2} from "./1.js"import * as obj from "./1.js"
// 混合应用
export {A1}
export default A2import A2,{A1} from "./1.js"
初识ES7
求幂运算符
console.log(Math.pow(2, 3))console.log(2**3)
数组的includes方法
[1, 2, NaN].includes(NaN) // true
[1, 2, NaN].indexOf(NaN) // -1
如果仅仅查找数据是否在数组中,建议使用includes,如果是查找数据的索引位置,建议使用indexOf更好一些
初识ES8
async
async 函数,使得异步操作变得更加方便。
-
更好的语义。
-
返回值是 Promise。
async function test(){}
test()
Await
await
命令后面是一个 Promise 对象,返回该对象的结果。如果不是 Promise 对象,就直接返回对应的值。
async function test(){var res1 = await ajax("http://localhost:3000/news1")var res2 = await ajax("http://localhost:3000/news2")return res2
}test().then(res=>{console.log("返回结果",res)
}).catch(err=>{console.log("err",err)
})
错误处理
try{var res1 = await ajax("http://localhost:3000/news1")var res2 = await ajax("http://localhost:3000/news2")
}catch(err){console.log("err",err)
}
对象方法扩展
Object.values
let obj = {name:"Ian",age:100}console.log(Object.values(obj))
Object.entries
let obj1 = {name:"Ian",age:100}console.log(Object.entries(obj1))
getOwnPropertyDescriptors
let obj = {name:"Ian",age:100}console.log(Object.values(obj))console.log(Object.getOwnPropertyDescriptors(obj))
克隆对象
let obj1 = {name:"Kerwin",age:100,location:{provice:"辽宁",city:"大连"},//只设置city,防止破坏provinceget city(){return this.location.city},set city(value){this.location.city = value},set nameset(value){this.name = value.substring(0,1).toUpperCase()+value.substring(1)},get nameset(){return this.name}
}
console.log(Object.getOwnPropertyDescriptors(obj1))
var obj2= {}//Object.assign(obj2,obj1)//无法克隆 get set方法
Object.defineProperties(obj2,Object.getOwnPropertyDescriptors(obj1))
字符串填充
padStart()、padEnd()方法可以使得字符串达到固定长度,有两个参数,字符串目标长度和填充内容。
let str = 'Ian'console.log(str.padStart(10, 'I'))console.log(str.padEnd(10, 'I'))
函数参数的末尾加逗号
『末尾逗号』在添加新的参数、属性、元素时是有用的,你可以直接新加一行而不必给上一行再补充一个逗号,这样使版本控制工具的修改记录也更加整洁
function test(a,b,c,){console.log(a,b)}test(1,2,3,)
初识ES9
对象的剩余参数与扩展运算符
对象的剩余参数
let obj = {name:"kerwin",age:100,location:"dalian"
}
let {name,...other} = obj
console.log(name) //kerwin
console.log(other) //{age: 100, location: 'dalian'}
对象的扩展运算符
let obj1 = {name:"kerwin"
}
let obj2 = {age:100
}
console.log({...obj1,...obj2})
正则表达式命名捕获组
JS正则表达式可以返回一个匹配的对象, 一个包含匹配字符串的类数组, 比如: 以 YYYY-MM-DD的格式解析日期,
这样的代码可读性很差, 并且在改变正则表达式的结构的时候很有可能就会改变匹配对象的索引
ES9允许使用命名捕获 ?<name> , 在打开捕获括号后立即命名
let str = "今天是2022-10-10"let reg = /([0-9]{4})-([0-9]{2})-([0-9]{2})/g
let res1 = reg.exec(str)console.log(res1)let str = "今天是2022-10-10"
let reg = /(?<year>[0-9]{4})-(?<month>[0-9]{2})-(?<day>[0-9]{2})/g
let res1 = reg.exec(str)
console.log(res1)
Promise.finally()
无论是成功还是失败, 都运行同样的代码, 比如隐藏对话框, 关闭数据连接
function ajax(){return new Promise((resolve,reject)=>{reject(1111)})
}
//showloading
ajax().then(res=>{
}).catch(err=>{
}).finally(()=>{//hideloadingconsole.log("finally")
})
异步遍历器
同步遍历器的问题
function* fn() {yield 1111yield 2222}
const syncI = fn();
console.log(syncI.next())
console.log(syncI.next())
console.log(syncI.next())
异步遍历器
function* fn() {yield new Promise(resolve=>resolve("1111"))yield new Promise(resolve=>resolve("2222"))}
const syncI = fn();
syncI.next().value.then(res=>{console.log(res)})
syncI.next().value.then(res=>{console.log(res)})
value
属性的返回值是一个 Promise 对象,用来放置异步操作。但是这样写很麻烦,不太符合直觉,语义也比较绕。
异步遍历器生成函数
Generator 函数返回一个同步遍历器,异步 Generator 函数的作用,是返回一个异步遍历器对象。在语法上,异步 Generator 函数就是async函数与 Generator 函数的结合。
async function* fn() {yield new Promise(resolve=>resolve("1111"))yield new Promise(resolve=>resolve("2222"))
}
const asyncI = fn();
asyncI.next().then(res=>{console.log(res)return asyncI.next()
}).then(res=>{console.log(res)return asyncI.next()
}).then(res=>{console.log(res)
})
for await of
for...of
循环用于遍历同步的 Iterator 接口。新引入的for await...of
循环,则是用于遍历异步的 Iterator 接口。
function timer(t) {return new Promise(resolve => {setTimeout(() => {resolve(t)}, t)})}async function* fn() {yield timer(1000)//任务1yield timer(2000)//任务2yield timer(3000)//任务3
}// 使用 for await ...of
async function fn1() {for await(const val of fn()) {console.log("start",Date.now())console.log(val);console.log("end",Date.now())}
}
fn1();
nodejs用法
// 传统写法
function main(inputFilePath) {const readStream = fs.createReadStream(inputFilePath,{ encoding: 'utf8', highWaterMark: 1024 });readStream.on('data', (chunk) => {console.log('>>> '+chunk);});readStream.on('end', () => {console.log('### DONE ###');});
}// 异步遍历器写法
async function main(inputFilePath) {const readStream = fs.createReadStream(inputFilePath,{ encoding: 'utf8', highWaterMark: 1024 });for await (const chunk of readStream) {console.log('>>> '+chunk);}console.log('### DONE ###');
}
初识ES10
Object.fromEntries
将键值对列表转换为对象(数组和字符串)
const arr = [["name", "kerwin"], ["age", 100]];
console.log(Object.fromEntries(arr))//{name: 'kerwin', age: 100}let str ="name=kerwin&age=100"
let searchParams = new URLSearchParams(str)
console.log(Object.fromEntries(searchParams))//{name: 'kerwin', age: '100'}
trimStart() and trimEnd()
let str = " IAN "
console.log("|"+str.trimStart(str)+"|")
console.log("|"+str.trimEnd(str)+"|")
console.log("|"+str.trimLeft(str)+"|")
console.log("|"+str.trimRight(str)+"|")
Symbol 对象的 description 属性
为Symbol对象添加了只读属性 description ,该对象返回包含Symbol描述的字符串。
let s = Symbol("Ian")
console.log(s)
console.log(s.description) //Ian
可选的 catch
let pro1 = new Promise(function (resolve, reject) {//执行器函数setTimeout(() => {resolve("成功的结果")}, 30000)
})
let pro2 = new Promise(function (resolve, reject) {//执行器函数setTimeout(() => {reject()}, 2000)
})
async function test() {try {await Promise.race([pro1, pro2])} catch {console.log("不关心错误结果,网络超时")}
}
test()
初识ES11
Promise.allSettled
Promise.allSettled() 方法返回一个在所有给定的 promise 都已经 fulfilled 或 rejected 后的 promise ,并带有一个对象数组,每个对象表示对应的 promise 结果。
const promises = [ ajax('/200接口'), ajax('/401接口') ];Promise.allSettled(promises).then(results=>{// 过滤出成功的请求results.filter(item =>item.status === 'fulfilled');过滤出失败的请求results.filter(item=> item.status === 'rejected');
})
module新增
动态导入 import()
标准用法的 import 导入的模块是静态的,会使所有被导入的模块,在加载时就被编译(无法做到按需编译,降低首页加载速度)。有些场景中,你可能希望根据条件导入模块或者按需导入模块,这时你可以使用动态导入代替静态导入。
<body><button>login</button><script type="module">let role1 = "管理员"let role2 = "普通用户"function login(){return "普通用户"}async function render(role){if(role===role1){let res1 = await import("./1.js")console.log(res1.default)}else{let res2 = await import("./2.js")console.log(res2.default)}}let obtn = document.querySelector("button")obtn.onclick = function(){let role = login()render(role)}</script>
</body>
import.meta
import.meta 会返回一个对象,有一个 url 属性,返回当前模块的url路径,只能在模块内部使用。
<script type="module">import obj from './1.js'
</script>//1.jsconsole.log(import.meta)
export default {}
export * as obj from 'module'
字符串的matchAll方法
matchAll() 方法返回一个包含所有匹配正则表达式的结果的迭代器。可以使用 for...of 遍历,或者使用 展开运算符(...) 或者 Array.from 转换为数组.
let str = `
<ul>
<li>1111</li>
<li>2222</li>
<li>3333</li>
<li>4444</li>
</ul>
`
let reg = /<li>(.*)<\/li>/gconsole.log(str.match(reg))
//'<li>1111</li>', '<li>2222</li>', '<li>3333</li>', '<li>4444</li>'
let str = `
<ul>
<li>1111</li>
<li>2222</li>
<li>3333</li>
<li>4444</li>
</ul>
`
let reg = /<li>(.*)<\/li>/g
let match = null;
while(match = reg.exec(str)){console.log(match[0])console.log(match[1])
}
let str = `
<ul>
<li>1111</li>
<li>2222</li>
<li>3333</li>
<li>4444</li>
</ul>
`
let reg = /<li>(.*)<\/li>/gfor(let i of str.matchAll(reg)){console.log(i)
}
BigInt
JavaScript 能够准确表示的整数范围在-2^53到2^53之间(不含两个端点),超过这个范围,无法精确表示这个值,这使得 JavaScript 不适合进行科学和金融方面的精确计算。
9007199254740992 //9007199254740992
9007199254740993 //9007199254740992Math.pow(2,53) === Math.pow(2,53)+1// 为了与 Number 类型区别,BigInt 类型的数据必须添加后缀`n`。
1234 // 普通整数
1234n // BigInt// BigInt 的运算
1n + 2n // 3n
globalThis
globalThis 提供了一个标准的方式来获取不同环境下的全局 this 对象(也就是全局对象自身)。不像 window 或者 self这些属性,它确保可以在有无窗口的各种环境下正常工作。所以,你可以安心的使用 globalThis,不必担心它的运行环境。为便于记忆,你只需要记住,全局作用域中的 this 就是 globalThis。
//以前
var getGlobal = function () {if (typeof self !== 'undefined') { return self; }if (typeof window !== 'undefined') { return window; }if (typeof global !== 'undefined') { return global; }throw new Error('unable to locate global object');
};let globals = getGlobal()if (globals.document) {console.log("进行dom操作相关")
} else {console.log("不能进行dom操作")
}//现在
if (globalThis.document) {console.log("进行dom操作相关")
} else {console.log("不能进行dom操作")
}
空值合并运算符
空值合并运算符(??)是一个逻辑运算符。当左侧操作数为 null 或 undefined 时,其返回右侧的操作数。否则返回左侧的操作数。
console.log(obj.introduction || "这个人很懒")
console.log(obj.introduction ?? "这个人很懒")
??和 || 的区别是什么呢?
他们两个最大的区别就是 ’ '和 0,??的左侧 为 ’ '或者为 0 的时候,依然会返回左侧的值;
|| 会对左侧的数据进行boolean类型转换,所以’ '和 0 会被转换成false,返回右侧的值
可选链操作符
可选链前面的值如果是null或undefined,则不再执行后面的,之前返回可选链前面的值
let obj = {name:"kerwin",introduction:0,// location:{// city:"dalian"// }
}console.log(obj && obj.location && obj.location.city)
console.log(obj?.location?.city)
初识ES12
逻辑赋值操作符
逻辑赋值操作符 ??=、&&=、 ||=
let a = true
let b = false
//a &&= b //false
a ||= b ; //true
console.log(a)let obj = {name:"kerwin",
}obj.introduction = obj.introduction??"很懒"
obj.introduction??="很懒"
数字分隔符
分隔符不仅可以分割十进制,也可以分割二净值或者十六净值的数据
const number = 1_000_000_000_000;
const binary = 0b1010_0101_1111_1101;
const hex = 0xA1_B2_C3;
replaceAll
replaceAll(被替换的,用来替换掉的)
所有匹配都会被替代项替换。模式可以是字符串或正则表达式,而替换项可以是字符串或针对每次匹配执行的函数。并返回一个全新的字符串
const str =
"I wish to wish the wish you wish to wish, but if you wish the wish the witch wishes, I won't wish the wish you wish to wish. ";
const newStr = str.replaceAll("wish", "Ian");
console.log(newStr);
Promise.any
只要参数实例有一个变成fulfilled
状态,包装实例就会变成fulfilled
状态;如果所有参数实例都变成rejected
状态,包装实例就会变成rejected
状态。
Promise.any()
跟Promise.race()
方法很像,只有一点不同,就是Promise.any()
不会因为某个 Promise 变成rejected
状态而结束,必须等到所有参数 Promise 变成rejected
状态才会结束。
WeakRef
在一般情况下,对象的引用是强引用的,这意味着只要持有对象的引用,它就不会被垃圾回收。只有当该对象没有任何的强引用时,垃圾回收才会销毁该对象并且回收该对象所占的内存空间。
而
WeakRef
允许您保留对另一个对象的弱引用,而不会阻止被弱引用对象被垃圾回收
let target = {};
let wr = new WeakRef(target);
console.log('wr.deref()',wr.deref());
console.log('wr',wr);
WeakRef 实例对象有一个deref()
方法,如果原始对象存在,该方法返回原始对象;如果原始对象已经被垃圾回收机制清除,该方法返回undefined
。
let like = new WeakRef(document.getElementById("like"))
let mymap = new WeakMap()
mymap.set(like.deref(), {click: 0
})
like.deref().onclick = function () {let times = mymap.get(like.deref())times.click++
}setTimeout(() => {document.body.removeChild(like.deref())
}, 2000)
FinalizationRegistry
清理器注册表功能 FinalizationRegistry,用来指定目标对象被垃圾回收机制清除以后,所要执行的回调函数。
const registry = new FinalizationRegistry(data => {// ....
});
registry.register(obj, "some value");
registry.unregister(obj);
let like = new WeakRef(document.getElementById("like"))
let mymap = new WeakMap()
mymap.set(like.deref(), {click: 0
})
like.deref().onclick = function () {let times = mymap.get(like.deref())times.click++
}setTimeout(() => {// registry.register(document.getElementById("like"), mymap.get(like.deref()));registry.register(like.deref(), mymap.get(like.deref()));document.body.removeChild(like.deref())
}, 2000)const registry = new FinalizationRegistry(data => {// ....console.log("被销毁了", data)
});
初识ES13
私有属性和方法
class Cache{#obj ={}get(key){return this.#obj[key]}set(key,value){this.#obj[key] =value}}let cache = new Cache()cache.set("name","Ian")console.log(cache.name)console.log(cache.get("name"))
静态成员的私有属性和方法
我们还可以给类定义静态成员和静态私有函数。类的静态方法可以使用
this
关键字访问其他的私有或者公有静态成员
class Cache{#obj ={}static #count = 0static getCount(){return this.#count}get(key){return this.#obj[key]}set(key,value){this.#obj[key] =value}}let cache = new Cache()cache.set("name","Ian")console.log(cache.name)console.log(cache.get("name"))console.log(Cache.getCount())
静态代码块
ES13允许在类中通过
static
关键字定义一系列静态代码块,这些代码块只会在类被创造的时候执行一次。这其实有点像一些其他的如C#和Java等面向对象的编程语言的静态构造函数的用法
一个类可以定义任意多的静态代码块,这些代码块会和穿插在它们之间的静态成员变量一起按照定义的顺序在类初始化的时候执行一次。我们还可以使用super
关键字来访问父类的属性。
class Cache{static obj = new Map()static {this.obj.set("name","Ian")this.obj.set("age",100)}static{console.log(this.obj)}}console.log(Cache.obj)
使用in来判断某个对象是否拥有某个私有属性
class Cache {#obj = {}get(key) {return this.#obj[key]}set(key, value) {this.#obj[key] = value}hasObj(){return #obj in this}
}let cache = new Cache()
console.log(cache.hasObj())
支持在最外层写await
顶层
await
只能用在 ES6 模块,不能用在 CommonJS 模块。这是因为 CommonJS 模块的require()
是同步加载,如果有顶层await
,就没法处理加载了。
<script type="module">function ajax() {return new Promise((resolve) => {setTimeout(() => {resolve("data-1111");}, 1000);})
}let res = await ajax();
console.log(res)</script>
at函数来索引元素
let arr = ["kerwin","tiechui","gangdan","xiaoming"]console.log(arr[1])
console.log(arr[arr.length-1]) //变丑了
console.log(arr[arr.length-2]) //变丑了console.log(arr.at(1))
console.log(arr.at(-1))
console.log(arr.at(-2))
正则匹配的开始和结束索引
let str = "今天是2022-11-10"
let reg = /(?<year>[0-9]{4})-(?<month>[0-9]{2})-(?<day>[0-9]{2})/d//exec
let res = reg.exec(str)
console.log(res)
findLast()和findLastIndex()函数
let arr = [11,12,13,14,15]// let res = arr.find(function(value){
// return value % 2 === 0
// })
// let res = arr.findIndex(function(value){
// return value % 2 === 0
// })
// let res = arr.findLast(function(value){
// return value % 2 === 0
// })
let res = arr.findLastIndex(function(value){return value % 2 === 0
})
console.log(res)
Error对象的Cause属性
Error对象多了一个
cause
属性来指明错误出现的原因。这个属性可以帮助我们为错误添加更多的上下文信息,从而帮助使用者们更好地定位错误。
function getData(){try{console.log(kerwin)}catch(e){throw new Error('New error 1111111',{cause:"这是因为,,,,,,,,,"});}
}try{getData()
}catch(e){console.log(e.cause)
}
相关文章:

ES6-ES13学习笔记
初识ES6 ECMAScript 6.0(以下简称 ES6)是 JavaScript 语言的下一代标准,已经在 2015 年 6 月正式发布了。它的目标,是使得 JavaScript 语言可以用来编写复杂的大型应用程序,成为企业级开发语言。 1997年:EC…...

【Qt开发】QtCharts图表——在ui上添加QChartView控件并进行绘图配置
【Qt开发】QtCharts图表——在ui上添加QChartView控件并进行绘图配置 文章目录 控件安装和模块导入在ui上添加QChartView控件QChartView图表配置附录:C语言到C的入门知识点(主要适用于C语言精通到Qt的C开发入门)C语言与C的不同C中写C语言代码…...

Android14 屏幕录制(屏幕投影)和音频播放采集
Android 5开始支持屏幕采集, Android 10支持音频播放采集,不过Android 14用前台服务做屏幕录制时要增加一些处理. 1. app manifest 需要增加: <manifest><uses-permission android:name"android.permission.FOREGROUND_SERVICE" /><uses…...

一行实现88个群智能算法优化混合核极限学习机HKELM的多特征输入单输出的数据回归预测Matlab程序全家桶
一行实现88个群智能算法优化混合核极限学习机HKELM的多特征输入单输出的数据回归预测Matlab程序全家桶 文章目录 前言一行实现88个群智能算法优化混合核极限学习机HKELM的多特征输入单输出的数据回归预测Matlab程序全家桶 一、HKELM模型1. 极限学习机(ELM࿰…...

redis面试(十五)公平锁队列重排
队列重拍 先说一下当前的加锁状态 anyLock由客户端A持有队列中是客户端B、客户端C并且客户端B现在是排在头部 那么队列重拍就是队列中某个客户端长时间没有重新申请加锁,没有刷新分数,就会被队列中挤掉。 假设这个长时间没有加锁的客户端是B。 总结 …...

python 基础语法os模块
一、os模块 待总结 二、os.path模块 1.abspath()方法--获取绝对路径 abspathO)方法用于返回文件或者目录的绝对路径。 语法格式如下: os .path.abspath(path) 参数说明: path:表示要获取绝对路径的相对路径,可以是文件也可以是目录。 返回值:返回获取到的绝…...

图论------迪杰斯特拉(Dijkstra)算法求单源最短路径。
编程要求 在图的应用中,有一个很重要的需求:我们需要知道从某一个点开始,到其他所有点的最短路径。这其中,Dijkstra 算法是典型的最短路径算法。 本关的编程任务是补全右侧代码片段中 Begin 至 End 中间的代码,实现 …...

河工院首届工业设计大赛程序组(挑战赛)题解
更好的阅读体验 \huge{\color{red}{更好的阅读体验}} 更好的阅读体验 寻找ACMer 思想: 签到题按照题意遍历字符串,不断向后寻找包含 ACMer 完整字符串的数量即可 std标程: #include <iostream> #include <cstring> #include …...

文件上传漏洞(二,靶场搭建及漏洞利用)
前言: 本文基于github上的upload-labs,PHP study以及bp抓包软件进行操作。 一,靶场搭建。 靶场链接 1,下载zip文件到PHP study下的www文件夹内,并解压。 2,创建网站。 此处php版本应选择较老版本&…...

大厂面试题分享第二期
大厂面试题分享第二期 如果执行了一条命令,"select count(*)from…",使用哪个引擎更快,为什么?垃圾回收器 CMS 和 G1的区别介绍一下CMS和G1CMS(并发)垃圾收集器G1垃圾回收器 HTTPS和HTTP的区别主…...

zabbix安装
a.安装 Zabbix 仓库 # rpm -Uvh https://repo.zabbix.com/zabbix/5.0/rhel/7/x86_64/zabbix-release-5.0-1.el7.noarch.rpm # yum clean all b. 安装 Zabbix server、前端、agent # yum install zabbix-server-mysql zabbix-agent c. 安装Zabbix前端 启用红帽软件集合 # …...

SpringBoot集成日志框架
SpringBoot集成日志框架 Java生态体系日志框架介绍 简介 在Java生态体系中,围绕着日志,有很多成熟的解决方案。关于日志输出,主要有两类工具。 一类是日志框架(Log4j、Logback),主要用来进行日志的输出的…...

CSS笔记总结(Xmind格式):第三天
Xmind鸟瞰图: 简单文字总结: css知识: 边框线: 1.border-width:边框的粗细 2.border-style:边框线的样式(solid实线,double双实线,dotted点线,dashed虚线) 3.border-color:边框线的颜色 4.简写形式&a…...

WordPress原创插件:Keyword-ranking-seo 1.0 关键词排名插件 有利于seo
WordPress原创插件:Keyword-ranking-seo 1.0 关键词排名插件 有利于seo 当用户访问网站时,该链接会随机选择一个关键词,并使用选定的搜索引擎进行搜索。 插件下载链接 https://download.csdn.net/download/huayula/89632792...

Docker Swarm 管理
Docker Swarm 是 Docker 提供的一种用于管理容器集群的工具。一、Docker Swarm 的主要特点包括: 高可用性:可以自动检测和恢复故障节点,确保服务的持续可用性。 例如,当某个工作节点出现故障时,Swarm 会将其上的任务重…...

跨平台、多格式、云同步,Koodo Reader背后的技术亮点
前言 对于像我这样的书虫来说,能够找到一个既方便又舒适的阅读环境,简直就是人生中的一大幸事;今天,就让小江湖我带你走进一个不一样的阅读世界——Koodo Reade! 无论是在喧嚣的都市,还是在宁静的乡村&a…...

【Story】如何高效记录并整理编程学习笔记?
目录 一、为何笔记在编程学习中如此重要?1.1 知识的捕捉1.2 理解和消化1.3 知识的复习1.4 知识的分享 二、建立高效的笔记系统2.1 确定笔记的目标2.2 选择合适的工具2.3 笔记的结构化2.4 记录有效的内容2.5 定期回顾和更新 三、保持笔记条理性的技巧3.1 使用一致的格…...

jenkins 安装以及自动构建maven项目并且运行
在这里找到你对应jdk的版本的jenkins包 War Jenkins Packages 我这里用的使java8,所以下载 https://mirrors.jenkins.io/war-stable/2.60.1/jenkins.war 然后jenkins可以安装到centos系统 在本地windows系统运行命令行 scp C:\Users\98090\Downloads\jenkins.war root@192…...

Java虚拟机:虚拟机介绍
大家好,我是栗筝i,这篇文章是我的 “栗筝i 的 Java 技术栈” 专栏的第 033 篇文章,在 “栗筝i 的 Java 技术栈” 这个专栏中我会持续为大家更新 Java 技术相关全套技术栈内容。专栏的主要目标是已经有一定 Java 开发经验,并希望进…...
硬件面试经典 100 题(31~40 题)CRE4
31、多级放大电路的级间耦合方式有哪几种?哪种耦合方式的电路零点偏移最严重?哪种耦合方式可以实现阻抗变换? 有三种耦合方式:直接耦合、阻容耦合、变压器耦合。直接耦合的电路零点漂移最严重,变压器耦合的电路可以实现…...

ReactNative笔记(自用)
环境 ios更换gem镜像源: 查看当前源: gem sources -l 移除默认源: gem sources --remove https://rubygems.org/。添加新的源: 添加 Ruby China 的镜像源: gem source -a https://gems.ruby-china.com/或者添加其他镜像源。 清华大学的gem源: htt…...

嵌入式八股-面试30题(20240812)
TCP和UDP的区别是什么? **TCP(Transmission Control Protocol)**是面向连接的协议,提供可靠的、顺序的数据传输。它通过三次握手建立连接,并在数据传输过程中使用确认和重传机制来确保数据的正确性。TCP还支持流量控制和拥塞控制…...

单一职责原则(SRP)
目录 1、定义 2、优点 3、原则的重要性 4、 示例 5、注意事项 单一职责原则(Single Responsibility Principle, SRP)是面向对象设计中的一项重要原则,属于 SOLID 原则之一。它的核心思想是:一个类应该只有一个引起它变化的原因&am…...

骨传导耳机怎么选?分享五款资深用户都说好的骨传导耳机!
在追求健康生活的道路上,运动健身已成为一种时尚潮流,而音乐则是这场潮流中不可或缺的催化剂。然而,传统耳机在运动场景下的局限性日益凸显,难以满足运动者对自由与舒适的双重追求。正是基于这样的市场需求,骨传导耳机…...

【计算机网络——分组延时,丢失,吞吐量】
处理延时:1检查分组首部信息,决定将该分组导向何处所需时间。2检查比特级别的差错所需时间:分析这个分组是否出错,目标IP地址字段提取出来,查路由表……。 传播延时和传输延时:传输延时就是分组到链路所需…...

使用1panel 申请证书配置雷池站点
1.创建测试站点 2.使用1panel申请测试站点的自签名证书 ps:雷池支持自签的证书 关于如果选择网站的SSL证书 百度搜索 看起来是证书的问题 调整了参数重新申请一个证书上传 注意,如果文件上传错了,雷池会报错,如下图 再次访问配…...

4章7节:用R做数据重塑,数据去重和数据的匹配
在数据科学的分析流程中,数据重塑是一项非常重要的操作。数据的重塑通常指将数据从一种形式转换为另一种形式,以满足后续分析的需求。R语言提供了丰富的工具和函数来帮助用户高效地进行数据重塑操作。本文中,我们将深入探讨数据重塑的概念及其…...

大数据面试SQL(七):累加刚好超过各省GDP40%的地市名称
文章目录 累加刚好超过各省GDP40%的地市名称 一、题目 二、分析 三、SQL实战 四、样例数据参考 累加刚好超过各省GDP40%的地市名称 一、题目 现有各省地级市的gdp数据,求从高到低累加刚好超过各省GDP40%的地市名称,临界地市也需要。 例如: 浙江省…...

建议收藏!这4款设计师常用的素材管理软件,助你工作效率翻倍!
嘿,设计师们!你是否还在为那一堆堆散乱的素材头疼?每次灵感来袭,却要花费大量时间在层层文件夹中苦苦搜寻?别急,今天我就来给大家推荐4款超给力的素材管理软件,它们不仅能帮你轻松整理素材库&am…...

用于NLP领域的排序模型最佳实践
在自然语言处理(NLP)领域,用于排序任务的模型通常是指那些能够对文本进行排序、比较或评估其相关性的模型。这些模型可以应用于诸如文档排序、句子排序、问答系统中的答案排序等多种场景。在当前的研究和发展中,基于深度学习的方法…...