当前位置: 首页 > news >正文

HTML-ES6.0核心技术

1.ES6简介

  1. ECMAScript 6.0(以下简称 ES6)是 JavaScript 语言的下一代标准,已经在2015年6月正式发布了。
  2. 它的目标,是使得 JavaScript 语言可以用来编写复杂的大型应用程序,成为企业级开发语言。
  3. ECMAScript 和 JavaScript 的关系是,前者是后者的规格,后者是前者的一种实现(另外的 ECMAScript 方言还有 Jscript 和 ActionScript)。日常场合,这两个词是可以互换的。
  4. ES6 从开始制定到最后发布,整整用了15年 2009年12月,ECMAScript 5.0版正式发布 2011年6月,ECMAscript5.1版发布,并且成为ISO国际标准(ISO/IEC 16262:2011)。 2013年3月,ECMAScript6草案冻结,不再添加新功能。新的功能设想将被放到ECMAScript 7。 2013年12月,ECMAScript6草案发布。然后是12个月的讨论期,听取各方反馈。 2015年6月,ECMAScript6正式通过,成为国际标准。从2000年算起,这时已经过去了15年。

附录:

ECMA是“European Computer Manufacturers Association”的缩写,中文名称为欧洲计算机制造商协会。是1961年成立的旨在建立统一的电脑操作格式标准(包括程序语言和输入输出)的组织。

2.ES6基础编程

2.1.let命令

ES6新增了let命令,用来声明变量。它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效。

2.1.1.let命令存在块级作用域

if (true) {var a = 10;let b = 20;
}
console.log(a); //10
console.log(b); //Uncaught ReferenceError: b is not defined

上面代码在代码块之中,分别用var和let声明了两个变量。然后在代码块之外调用这两个变量,结果let声明的变量报错,var声明的变量返回了正确的值。这表明,let声明的变量只在它所在的代码块有效。

那为什么需要块级作用域呢? ES5只有全局作用域和函数作用域,没有块级作用域,这带来很多不合理的场景。 下面场景中,内层变量可能会覆盖外层变量。

var tmp = new Date();
function fn(){console.log(tmp);if(false){var tmp = 'hello world';}
}
fn();    //undefined

上面代码中,函数f执行后,输出结果为undefined,原因在于变量提升,导致内层的tmp变量覆盖了外层的tmp变量。

2.1.2.Let不存在变量提升

//var的情况
console.log(foo);
var foo = 2;   //undefined
//let的情况
console.log(bar);
let bar = 2;   //ReferenceError: Cannot access 'bar'

上面代码中,变量foo用var命令声明,会发生变量提升,即脚本开始运行时,变量foo已经存在了,但是没有值,所以会输出undefined。 变量bar用let命令声明,不会发生变量提升。这表示在声明它之前,变量bar是不存在的,这时如果用到它,就会抛出一个错误。 因此,使用let声明变量,极大的消除了代码的潜在bug的隐患。

2.1.2.Let暂时性死区

只要块级作用域内存在let命令,它所声明的变量就“绑定”(binding)这个区域,不再受外部的影响。

var temp = 123;
if(true){temp = 'abc';  //ReferenceError: Cannot access 'temp' let temp;
}

上面代码中,存在全局变量temp,但是块级作用域内let又声明了一个局部变量tmp,导致后者绑定这个块级作用域,所以在let声明变量前,对temp赋值会报错。

2.2.const 命令

const声明一个只读的常量。一旦声明,常量的值就不能改变。

const PI = 3.1415926;
PI = 3;  //TypeError: Assignment to constant variable.

上面代码表明改变常量的值会报错。

2.3.字符串的扩展-模板字符串

传统的JavaScript语言,输出模板通常是这样写的:

<p id="result"></p>
<script>let basket = {count: 100,onSale: 80}document.getElementById('result').innerHTML ='There are <b>' + basket.count + '</b> ' +'items in your basket, ' +'<em>' + basket.onSale +'</em> are on sale!';
</script>

前面这种写法相当繁琐不方便,ES6引入了模板字符串解决这个问题

<p id="result"></p>
<script>let basket = {count:100,onSale:80}document.getElementById('result').innerHTML =`There are <b>${basket.count}</b> itemsin your basket, <em>${basket.onSale}</em>are on sale!`;
</script>

注意:ES6模板字符串中必须要使用反引号。

2.4.函数的扩展rest参数

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

function add(...values) {let sum = 0;for(var val of values) {sum += val;}return sum;
}
add(2, 5, 3) // 10

上面代码的add函数是一个求和函数,利用 rest 参数,可以向该函数传入任意数目的参数。

rest 参数中的变量代表一个数组,所以数组特有的方法都可以用于这个变量。下面是一个利用 rest 参数改写数组push方法的例子

function push(array, ...items) {items.forEach(function(item) {array.push(item);console.log(item);});
}
var a = [];
push(a, 1, 2, 3)

2.5. 函数的扩展-箭头函数

ES6允许使用“箭头”(=>)定义函数:

//ES5定义函数
var f = function(v) {return v;
};
//ES6定义箭头函数
var f = v => v

2.5.1.箭头函数的语法

  1. 如果箭头函数不需要参数或需要多个参数,就使用一个圆括号代表参数部分
let f = () => 5;
// 等同于
let f = function() { return 5 };
let sum = (num1, num2) => {return num1 + num2;
};
// 等同于
let sum = function(num1, num2) {return num1 + num2;
};
  1. 如果只有一个参数,那么圆括号就可以省略了
let f = str => {console.log(str);
}
f('hello');
  1. 如何函数体中的代码只有一句,那么大括号可以省略
let f = str => console.log(str);
f('hello');
  1. 但如果函数体中的代码只有一个return语句,那么return关键词也必须省略
//这是错误的
let sum = (num1, num2) => return num1 + num2;
//这是正确的
let sum = (num1, num2) => num1 + num2;
  1. 由于大括号被解释为代码块,所以如果箭头函数直接返回一个对象,必须在对象外面加上括号。
let getTempItem = id => ({ id:id, name:'Temp' })

2.5.2.使用箭头函数的注意点

箭头函数有几个使用注意点。

  1. 函数体内的this对象。
    函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。
    或者说:箭头函数当方法使用时没有定义this绑定,而是捕获所在上下文的 this ,作为自己的 this 。
<button id="one">one点击(使用function)</button>
<button id="two">two点击(使用箭头函数)</button>
<script>var one = document.getElementById('one');var two = document.getElementById('two');one.onclick = function (){console.log(this);   //<button id="one">one点击(使用function)</button>}two.onclick = ()=>{console.log(this);   //window}
</script>

注意:

  • 箭头函数的this永远指向其上下文的 this,任何方法都改变不了其指向,如call(), bind()等。
  • 普通函数的this指向调用它的那个对象。
  1. 不可以当作构造函数。
    也就是说,不可以使用new命令,否则会抛出一个错误。
  2. 不可以使用arguments对象。
    该对象在函数体内不存在。如果要用,可以用Rest参数代替。

2.5.3.this指向问题测试

<button>点击</button>
<script>//指向Window,因为处于Window作用域中(或者说console本身就是window对象的函数)window.console.log('script块:'+this);//指向Window,因为处于Window作用域中(或者说if是声明在window对象中的)if(true){console.log('if块:'+this);}//指向Window,因为处于Window作用域中(或者说此函数是在window对象中的)//注意:可以这样写:var fn = function(){}//     但不能这样写:let fn = function(){}var fn = function(){console.log('函数中:'+this);}window.fn();//指向Window,因为处于Window作用域中(或者说setTimeout本身就是window对象的函数)window.setTimeout(function(){console.log('setTimeout函数中:'+this);},1);//指向Button对象document.getElementsByTagName('button')[0].onclick=function(){console.log('button事件处理函数中:'+this);}/*** 测试:点击按钮后,结果为:* script块:[object Window]* if块:[object Window]* 函数中:[object Window]* setTimeout函数中:[object Window]* button事件处理函数中:[object HTMLButtonElement]*/
</script>

2.5.4.使用箭头函数简化回调函数

箭头函数的一个用处是简化回调函数

实例1:

let arr = [1,2,3];
// function函数写法
arr = arr.map(function(x) {return x * x;
});
// 箭头函数写法
arr = arr.map(x => x * x);

实例2:

let values = [5,2,8];
// function函数写法
let result = values.sort(function(a, b) {return a - b;
});
// 箭头函数写法
let result = values.sort((a, b) => a - b);

2.5.5.rest参数与箭头函数结合

let numbers = (...nums) => nums;
numbers(1, 2, 3, 4, 5)     // [1,2,3,4,5]
let headAndTail = (head, ...tail) => [head, tail];
headAndTail(1, 2, 3, 4, 5)  // [1,[2,3,4,5]]

2.6 数组的扩展

本节内容使用普通函数实现,如果已经学习过箭头函数,请同学将代码改写为箭头函数形式!

2.6.1 扩展运算符

含义

扩展运算符(spread)是三个点(...)。它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列。

console.log(...[1, 2, 3])
// 1 2 3console.log(1, ...[2, 3, 4], 5)
// 1 2 3 4 5[...document.querySelectorAll('div')]
// [<div>, <div>, <div>]

该运算符主要用于函数调用。

function push(array, ...items) {array.push(...items);
}function add(x, y) {return x + y;
}const numbers = [4, 38];
add(...numbers) // 42

上面代码中,array.push(...items)和add(...numbers)这两行,都是函数的调用,它们都使用了扩展运算符。该运算符将一个数组,变为参数序列。

扩展运算符与正常的函数参数可以结合使用,非常灵活。

function f(v, w, x, y, z) { }
const args = [0, 1];
f(-1, ...args, 2, ...[3]);

扩展运算符后面还可以放置表达式。

const arr = [...(x > 0 ? ['a'] : []),'b',
];

如果扩展运算符后面是一个空数组,则不产生任何效果。

[...[], 1]
// [1]

注意,只有函数调用时,扩展运算符才可以放在圆括号中,否则会报错。

(...[1, 2])
// Uncaught SyntaxError: Unexpected numberconsole.log((...[1, 2]))
// Uncaught SyntaxError: Unexpected numberconsole.log(...[1, 2])
// 1 2

上面三种情况,扩展运算符都放在圆括号里面,但是前两种情况会报错,因为扩展运算符所在的括号不是函数调用。

扩展运算符的应用
(1)复制数组

数组是复合的数据类型,直接复制的话,只是复制了指向底层数据结构的指针,而不是克隆一个全新的数组。

const a1 = [1, 2];
const a2 = a1;a2[0] = 2;
a1 // [2, 2]

上面代码中,a2并不是a1的克隆,而是指向同一份数据的另一个指针。修改a2,会直接导致a1的变化。

ES5 只能用变通方法来复制数组。

const a1 = [1, 2];
const a2 = a1.concat();a2[0] = 2;
a1 // [1, 2]

上面代码中,a1会返回原数组的克隆,再修改a2就不会对a1产生影响。

扩展运算符提供了复制数组的简便写法。

const a1 = [1, 2];
// 写法一
const a2 = [...a1];
// 写法二
const [...a2] = a1;

上面的两种写法,a2都是a1的克隆。

(2)合并数组

扩展运算符提供了数组合并的新写法。

const arr1 = ['a', 'b'];
const arr2 = ['c'];
const arr3 = ['d', 'e'];// ES5 的合并数组
arr1.concat(arr2, arr3);
// [ 'a', 'b', 'c', 'd', 'e' ]// ES6 的合并数组
[...arr1, ...arr2, ...arr3]
// [ 'a', 'b', 'c', 'd', 'e' ]

不过,这两种方法都是浅拷贝,使用的时候需要注意。

const a1 = [{ foo: 1 }];
const a2 = [{ bar: 2 }];const a3 = a1.concat(a2);
const a4 = [...a1, ...a2];a3[0] === a1[0] // true
a4[0] === a1[0] // true

上面代码中,a3和a4是用两种不同方法合并而成的新数组,但是它们的成员都是对原数组成员的引用,这就是浅拷贝。如果修改了引用指向的值,会同步反映到新数组。

(3)与解构赋值结合

扩展运算符可以与解构赋值结合起来,用于生成数组。

// ES5
a = list[0], rest = list.slice(1)// ES6
[a, ...rest] = list

下面是另外一些例子。

const [first, ...rest] = [1, 2, 3, 4, 5];
first // 1
rest  // [2, 3, 4, 5]const [first, ...rest] = [];
first // undefined
rest  // []const [first, ...rest] = ["foo"];
first  // "foo"
rest   // []

如果将扩展运算符用于数组赋值,只能放在参数的最后一位,否则会报错。

const [...butLast, last] = [1, 2, 3, 4, 5];
// 报错const [first, ...middle, last] = [1, 2, 3, 4, 5];
// 报错
(4)字符串

扩展运算符还可以将字符串转为真正的数组。

[...'hello']
// [ "h", "e", "l", "l", "o" ]

上面的写法,有一个重要的好处,那就是能够正确识别四个字节的 Unicode 字符。

'x\uD83D\uDE80y'.length // 4
[...'x\uD83D\uDE80y'].length // 3

上面代码的第一种写法,JavaScript 会将四个字节的 Unicode 字符,识别为 2 个字符,采用扩展运算符就没有这个问题。因此,正确返回字符串长度的函数,可以像下面这样写。

function length(str) {return [...str].length;
}length('x\uD83D\uDE80y') // 3

凡是涉及到操作四个字节的 Unicode 字符的函数,都有这个问题。因此,最好都用扩展运算符改写。

let str = 'x\uD83D\uDE80y';str.split('').reverse().join('')
// 'y\uDE80\uD83Dx'[...str].reverse().join('')
// 'y\uD83D\uDE80x'

上面代码中,如果不用扩展运算符,字符串的reverse()操作就不正确。

(5)实现了 Iterator 接口的对象

任何定义了遍历器(Iterator)接口的对象(参阅 Iterator 一章),都可以用扩展运算符转为真正的数组。

let nodeList = document.querySelectorAll('div');
let array = [...nodeList];

上面代码中,querySelectorAll()方法返回的是一个NodeList对象。它不是数组,而是一个类似数组的对象。这时,扩展运算符可以将其转为真正的数组,原因就在于NodeList对象实现了 Iterator。

Number.prototype[Symbol.iterator] = function*() {let i = 0;let num = this.valueOf();while (i < num) {yield i++;}
}console.log([...5]) // [0, 1, 2, 3, 4]

上面代码中,先定义了Number对象的遍历器接口,扩展运算符将5自动转成Number实例以后,就会调用这个接口,就会返回自定义的结果。

对于那些没有部署 Iterator 接口的类似数组的对象,扩展运算符就无法将其转为真正的数组。

let arrayLike = {'0': 'a','1': 'b','2': 'c',length: 3
};// TypeError: Cannot spread non-iterable object.
let arr = [...arrayLike];

上面代码中,arrayLike是一个类似数组的对象,但是没有部署 Iterator 接口,扩展运算符就会报错。这时,可以改为使用Array.from方法将arrayLike转为真正的数组。

(6)Map 和 Set 结构,Generator 函数

扩展运算符内部调用的是数据结构的 Iterator 接口,因此只要具有 Iterator 接口的对象,都可以使用扩展运算符,比如 Map 结构。

let map = new Map([[1, 'one'],[2, 'two'],[3, 'three'],
]);let arr = [...map.keys()]; // [1, 2, 3]

Generator 函数运行后,返回一个遍历器对象,因此也可以使用扩展运算符。

const go = function*(){yield 1;yield 2;yield 3;
};[...go()] // [1, 2, 3]

上面代码中,变量go是一个 Generator 函数,执行后返回的是一个遍历器对象,对这个遍历器对象执行扩展运算符,就会将内部遍历得到的值,转为一个数组。

如果对没有 Iterator 接口的对象,使用扩展运算符,将会报错。

const obj = {a: 1, b: 2};
let arr = [...obj]; // TypeError: Cannot spread non-iterable object

2.6.2 重要的实例方法

2.6.2.1 fill()方法

定义和用法

fill方法使用给定值,填充一个数组。

['a', 'b', 'c'].fill(7)
// [7, 7, 7]new Array(3).fill(7)
// [7, 7, 7]

上面代码表明,fill方法用于空数组的初始化非常方便。数组中已有的元素,会被全部抹去。

fill方法还可以接受第二个和第三个参数,用于指定填充的起始位置和结束位置。

['a', 'b', 'c'].fill(7, 1, 2)
// ['a', 7, 'c']

上面代码表示,fill方法从 1 号位开始,向原数组填充 7,到 2 号位之前结束。

注意,如果填充的类型为对象,那么被赋值的是同一个内存地址的对象,而不是深拷贝对象。

实例

let arr = new Array(3).fill({name: "Mike"});
arr[0].name = "Ben";
arr
// [{name: "Ben"}, {name: "Ben"}, {name: "Ben"}]let arr = new Array(3).fill([]);
arr[0].push(5);
arr
// [[5], [5], [5]]
2.6.2.2 forEach() 方法

定义和用法

forEach() 方法用于调用数组的每个元素,并将元素传递给回调函数。

注意: forEach() 对于空数组是不会执行回调函数的。

语法

array.forEach(callbackFn(currentValue, index, arr), thisValue)

参数

参数

描述

callbackFn(currentValue, index, arr)

必需。 数组中每个元素需要调用的函数。
函数参数:

参数

描述

currentValue

必需。当前元素

index

可选。当前元素的索引值。

arr

可选。当前元素所属的数组对象。

thisValue

可选。传递给函数的值一般用 "this" 值。
如果这个参数为空, "undefined" 会传递给 "this" 值

其他形式的语法格式:

// 箭头函数
forEach((element) => { /* … */ })
forEach((element, index) => { /* … */ })
forEach((element, index, array) => { /* … */ })// 回调函数
forEach(callbackFn)
forEach(callbackFn, thisArg)// 内联回调函数
forEach(function(element) { /* … */ })
forEach(function(element, index) { /* … */ })
forEach(function(element, index, array){ /* … */ })
forEach(function(element, index, array) { /* … */ }, thisArg)

实例

var arr = [1, 2, 3, 4, 5];
arr.forEach(function (item) {if (item === 3) {return;}console.log(item);
});
2.6.2.3 filter()

定义和用法

filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。

注意: filter() 不会对空数组进行检测。filter() 不会改变原始数组。

语法

array.filter(function(currentValue,index,arr), thisValue) 

参数说明

参数

描述

function(currentValue, index,arr)

必须。函数,数组中的每个元素都会执行这个函数
函数参数:

参数

描述

currentValue

必须。当前元素的值

index

可选。当前元素的索引值

arr

可选。当前元素属于的数组对象

thisValue

可选。对象作为该执行回调时使用,传递给函数,用作 "this" 的值。
如果省略了 thisValue ,"this" 的值为 "undefined"

实例

var ages = [32, 33, 12, 40];function checkAdult(age) {return age >=18 ;
}function myFunction() {console.log(ages.filter(checkAdult));
}
2.6.2.4 map() 方法

定义和用法

map() 方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。

map() 方法按照原始数组元素顺序依次处理元素。

注意: map() 不会对空数组进行检测。 map() 不会改变原始数组。

语法

array.map(function(currentValue,index,arr), thisValue) 

参数

描述

function(currentValue, index,arr)

必须。函数,数组中的每个元素都会执行这个函数
函数参数:

参数

描述

currentValue

必须。当前元素的值

index

可选。当前元素的索引值

arr

可选。当前元素属于的数组对象

thisValue

可选。对象作为该执行回调时使用,传递给函数,用作 "this" 的值。
如果省略了 thisValue,或者传入 null、undefined,那么回调函数的 this 为全局对象。

实例

var numbers = [4, 9, 16, 25];function myFunction() {x = document.getElementById("demo")x.innerHTML = numbers.map(Math.sqrt);
}

输出结果为:

2,3,4,5

2.6.2.5 reduce() 方法

定义和用法

reduce() 方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。

reduce() 可以作为一个高阶函数,用于函数的 compose。

注意: reduce() 对于空数组是不会执行回调函数的。

语法

array.reduce(function(total, currentValue, currentIndex, arr), initialValue)

参数

参数

描述

function(total,currentValue, index,arr)

必需。用于执行每个数组元素的函数。
函数参数:

参数

描述

total

必需。初始值, 或者计算结束后的返回值。

currentValue

必需。当前元素

currentIndex

可选。当前元素的索引

arr

可选。当前元素所属的数组对象。

initialValue

可选。传递给函数的初始值

实例

var numbers = [65, 44, 12, 4];function getSum(total, num) {return total + num;
}
function myFunction(item) {const sum = numbers.reduce(getSum);console.log(sum)
}
2.6.2.6 some() 方法

定义和用法

some() 方法用于检测数组中的元素是否满足指定条件(函数提供)。

some() 方法会依次执行数组的每个元素:

  • 如果有一个元素满足条件,则表达式返回true , 剩余的元素不会再执行检测。
  • 如果没有满足条件的元素,则返回false。

注意: some() 不会对空数组进行检测。some() 不会改变原始数组。

语法

array.some(function(currentValue,index,arr),thisValue)

参数

参数

描述

function(currentValue, index,arr)

必须。函数,数组中的每个元素都会执行这个函数
函数参数:

参数

描述

currentValue

必须。当前元素的值

index

可选。当前元素的索引值

arr

可选。当前元素属于的数组对象

thisValue

可选。对象作为该执行回调时使用,传递给函数,用作 "this" 的值。
如果省略了 thisValue ,"this" 的值为 "undefined"

实例

var ages = [3, 10, 18, 20];function checkAdult(age) {return age >= 18;
}function myFunction() {document.getElementById("demo").innerHTML = ages.find(checkAdult);
}
2.6.2.7 find() 方法

定义和用法

find() 方法返回通过测试(函数内判断)的数组的第一个元素的值。

find() 方法为数组中的每个元素都调用一次函数执行:

  • 当数组中的元素在测试条件时返回 true 时, find() 返回符合条件的元素,之后的值不会再调用执行函数。
  • 如果没有符合条件的元素返回 undefined

注意: find() 对于空数组,函数是不会执行的。注意: find() 并没有改变数组的原始值。

语法

array.find(function(currentValue, index, arr),thisValue)

参数

参数

描述

function(currentValue, index,arr)

必需。数组每个元素需要执行的函数。
函数参数:

参数

描述

currentValue

必需。当前元素

index

可选。当前元素的索引值

arr

可选。当前元素所属的数组对象

thisValue

可选。 传递给函数的值一般用 "this" 值。
如果这个参数为空, "undefined" 会传递给 "this" 值

实例

var ages = [3, 10, 18, 20];function checkAdult(age) {return age >= 18;
}function myFunction() {document.getElementById("demo").innerHTML = ages.find(checkAdult);
}

相关方法(略)

findIndex(),findLast(),findLastIndex()

2.6.2.8 sort() 方法

定义和用法

sort() 方法用于对数组的元素进行排序。

排序顺序可以是字母或数字,并按升序或降序。

数组的默认排序顺序为按字母升序【即使是数字数组,默认亦按此排序】。

注意:当数字是按字母顺序排列时"40"将排在"5"前面。

使用数字排序,你必须通过一个函数作为参数来调用。

函数指定数字是按照升序还是降序排列。

这些说起来可能很难理解,你可以通过本页底部实例进一步了解它。

注意: 这种方法会改变原始数组!。

语法

array.sort(sortfunction)

参数 Values

参数

描述

sortfunction

可选。规定排序顺序。必须是函数。

返回值

Type

描述

Array

对数组的引用。请注意,数组在原数组上进行排序,不生成副本。

实例

var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.sort();
// Apple,Banana,Mango,Orange

var points = [40,100,1,5,25,10];
console.log( points.sort(function(a,b){return a-b}));
//  结果:
1,5,10,25,40,100

var points = [40,100,1,5,25,10];
points.sort(function(a,b){return b-a});
// 100,40,25,10,5,1

var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.sort();
fruits.reverse();
// Orange,Mango,Banana,Apple
2.6.2.9 copyWithin() 方法(了解)

copyWithin() 方法用于从数组的指定位置拷贝元素到数组的另一个指定位置中。

语法

array.copyWithin(target, start, end)

参数

参数

描述

target

必需。复制到指定目标索引位置。

start

可选。元素复制的起始位置。

end

可选。停止复制的索引位置 (默认为 array.length)。如果为负值,表示倒数。

实例

 var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.copyWithin(2, 0);
// Banana,Orange,Banana,Orange

// 复制数组的前面两个元素到第三和第四个位置上
var fruits = ["Banana", "Orange", "Apple", "Mango", "Kiwi", "Papaya"];
fruits.copyWithin(2, 0, 2);
// Banana,Orange,Banana,Orange,Kiwi,Papaya
2.6.2.A every() 方法

定义和用法

every() 方法用于检测数组所有元素是否都符合指定条件(通过函数提供)。

every() 方法使用指定函数检测数组中的所有元素:

  • 如果数组中检测到有一个元素不满足,则整个表达式返回 false ,且剩余的元素不会再进行检测。
  • 如果所有元素都满足条件,则返回 true。

注意: every() 不会对空数组进行检测。

注意: every() 不会改变原始数组。

语法

array.every(function(currentValue,index,arr), thisValue)

参数

参数

描述

function(currentValue, index,arr)

必须。函数,数组中的每个元素都会执行这个函数
函数参数:

参数

描述

currentValue

必须。当前元素的值

index

可选。当前元素的索引值

arr

可选。当前元素属于的数组对象

thisValue

可选。对象作为该执行回调时使用,传递给函数,用作 "this" 的值。
如果省略了 thisValue ,"this" 的值为 "undefined"

实例

var ages = [32, 33, 16, 40];function checkAdult(age) {return age >= 18;
}function myFunction() {document.getElementById("demo").innerHTML = ages.every(checkAdult);
}
//  false

// 检测数组 ages 的所有元素是否都大于等于输入框中指定的数字:<p>最小年龄: <input type="number" id="ageToCheck" value="18"></p>
<button onclick="myFunction()">点我</button>
<p>是否所有年龄都符号条件? <span id="demo"></span></p>
<script>var ages = [32, 33, 12, 40];function checkAdult(age) {return age >= document.getElementById("ageToCheck").value;}function myFunction() {document.getElementById("demo").innerHTML = ages.every(checkAdult);}
</script>

2.6.3 Array扩展(了解)

2.6.3.1 from()函数 定义和用法

from() 方法用于通过拥有 length 属性的对象或可迭代的对象来返回一个数组。

如果对象是数组返回 true,否则返回 false。

语法

Array.from(object, mapFunction, thisValue)参数

实例

//  通过字符串创建一个数组 
let  myArr = Array.from("Neuedu");

// 下面的实例返回集合中包含的对象数组
var setObj = new Set(["a", "b", "c"]);
var objArr = Array.from(setObj);
objArr[1] == "b";  // true

// 下面的实例演示如何使用箭头语法和映射函数更改元素的值
var arr = Array.from([1, 2, 3], x => x * 10);
// arr[0] == 10;
// arr[1] == 20;
// arr[2] == 30;
2.6.3.2 of() 方法

定义和用法

of() 方法用于将一组值转换为数组,不考虑参数的数量或类型。

Array.of() 和 Array() 构造函数之间的区别在于对单个参数的处理:Array.of(7) 创建一个具有单个元素 7 的数组,而 Array(7) 创建一个 length 为 7 的空数组。

如果对象是数组返回 true,否则返回 false。

语法

Array.of(element0)
Array.of(element0, element1)
Array.of(element0, element1, /* … ,*/ elementN)

参数

参数

描述

element0

必需,要转换为数组的元素。

element1, /* … ,*/ elementN

可选,要转换为数组的元素。

实例

var myArr = Array.of("Runoob","Google","Taobao");Array.of(7); // [7]
Array(7); // array of 7 empty slotsArray.of(1, 2, 3); // [1, 2, 3]
Array(1, 2, 3);    // [1, 2, 3]Array.of(1);         // [1]
Array.of(1, 2, 3);   // [1, 2, 3]
Array.of(undefined); // [undefined]
2.6.3.3 flat() 方法

定义和用法

flat() 方法方法会按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。

flat() 方法返回一个包含将数组与子数组中所有元素的新数组。

语法

flat()flat(depth)

参数

参数

描述

depth

指定要提取嵌套数组的结构深度,默认值为 1。

实例

// 扁平化嵌套数组var arr1 = [1, 2, [3, 4]];
arr1.flat();
// [1, 2, 3, 4]var arr2 = [1, 2, [3, 4, [5, 6]]];
arr2.flat();
// [1, 2, 3, 4, [5, 6]]var arr3 = [1, 2, [3, 4, [5, 6]]];
arr3.flat(2);
// [1, 2, 3, 4, 5, 6]//使用 Infinity,可展开任意深度的嵌套数组
var arr4 = [1, 2, [3, 4, [5, 6, [7, 8, [9, 10]]]]];
arr4.flat(Infinity);
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

// 扁平化与数组空项
var arr4 = [1, 2, , 4, 5];
arr4.flat();
// [1, 2, 4, 5]

2.6.4 Map操作相关(了解)

2.6.4.1 entries()方法

定义和用法

entries() 方法返回带有键/值对的 Array Iterator 对象。

对于原始数组var fruits = ["Banana", "Orange", "Apple", "Mango"] 中的每一项,新的迭代对象将包含一个以索引为键,以项值为值的数组:

  • [0, "Banana"]
  • [1, "Orange"]
  • [2, "Apple"]
  • [3, "Mango"]

注释:entries() 不会更改原始数组。

语法

array.entries()

实例

// 创建一个 Array Iterator 对象,并创建一个循环来迭代每个键/值对:
var fruits = ["Banana", "Orange", "Apple", "Mango"];
var f = fruits.entries();for (x of f) {document.getElementById("demo").innerHTML += x;
}

2.6.4.2 keys()方法

定义和用法

keys() 方法用于从数组创建一个包含数组键的可迭代对象。

如果对象是数组返回 true,否则返回 false。

语法

array.keys()

实例

// 从数组 fruit 创建一个数组迭代对象, 该对象包含了数组的键:
var fruits = ["Banana", "Orange", "Apple", "Mango"];
// 
console.log(fruits.keys());
// 结果: 0,1,2,3

3.类

3.1. 类的基本语法

ES6提供了更接近面向对象(注意:javascript本质上是基于对象的语言)语言的写法,引入了Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。 基本上,ES6的class可以看作只是一个语法糖,它的绝大部分功能,ES5都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。

//定义类
class Point {constructor(x, y) {this.x = x;this.y = y;}toString() {return '(' + this.x + ', ' + this.y + ')';}
}
//创建对象
let p = new Point(1,2);
console.log(p.toString());

上面代码定义了一个“类”,可以看到里面有一个constructor方法,这就是构造方法,而this关键字则代表实例对象。也就是说,ES5的构造函数Point,对应ES6的Point类的构造方法。

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

注意:生成类的实例对象的写法,要使用new命令。如果忘记加上new,像ES5函数那样调用Class,将会报错。

// 报错
let point = Point(2,3);
// 正确
let point = new Point(2,3);

3.2.constructor方法

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

constructor() {}

注意:constructor方法默认返回实例对象(即this)

扩展:constructor方法默认返回实例对象(即this),但也可以指定返回另外一个对象。

class Point {constructor(x, y) {return new Date();//return Object.create(null);}
}
let p = new Point();   //返回为Date对象
console.log(p);

Constructor与普通构造函数的区别: 类的构造函数,不使用new是没法调用的,会报错。这是它跟普通构造函数的一个主要区别,后者不用new也可以执行。

class Point {constructor(x, y) {this.x = x;this.y = y;}toString() {return '(' + this.x + ', ' + this.y + ')';}
}
let p = Point(); //TypeError: Class constructor Point cannot be invoked without 'new'

3.3.this与class(原型)

class:类,是对象的模板。(或者叫:原型) this:当前对象。 以上定义,与java中的概念是相同的。 但是,由于javascript语言自身的特点,关于class与this,还需要做进一步说明。

注意:在javascript中,在定义类完毕之后,还可以再添加属性和方法。

3.3.1.属性与方法添加到this上

class Point {constructor() { }
}
let p = new Point();
p.username = 'zhangsan';
console.log(p.username);    //zhangsan

上面代码中,Point类定义之后,给对象 p 又添加了一个username属性。这是完全可以的。 但是要注意:此种方式,仅仅是给对象p添加一个属性,而不是给类添加一个属性。 或者说: 此种方式,仅仅是给对象p的this添加一个属性,而不是给类添加一个属性。

class Point {constructor() { }
}
let p1 = new Point();
p1.username = 'zhangsan';
console.log(p1.username);   //zhangsan
let p2 = new Point();
console.log(p2.username);   //undefined

上面例子中,只给对象p1添加了username属性,但没有给类添加属性。 所以,p2对象中并没有username属性。

3.3.2.属性与方法添加到类上

class Point {constructor() { }
}
Point.prototype.username = 'zhangsan';
let p1 = new Point();
console.log(p1.username);   //zhangsan
let p2 = new Point();
console.log(p2.username);   //zhangsan

上面代码中,使用 Point.prototype方式,给类添加属性。 这样,类的所有对象(p1、p2)就都有username属性了。

在javascript中,每一个类都有一个prototype,它就是类的原型,类的所有实例共享一个原型。如果想访问这个原型,可以使用proto指针

class Point {constructor() { }
}
let p = new Point();
console.log(p.__proto__);      //注意proto指针的写法
/*** 输出结果:* {constructor: ƒ}*  constructor: class Point  //这里证明:proto指针指向类的原型*  __proto__: Object*/
class Point {constructor() { }
}
let p1 = new Point();
let p2 = new Point();
console.log(p1.__proto__===p2.__proto__); //这里证明:类的所有实例共享一个原型

实际上,由于ES5历史原因,程序员更喜欢称之为:属性与方法添加到原型上。

3.3.3.类的静态成员

class Point {constructor() { }
}
Point.username = 'zhangsan';
let p = new Point();
console.log(p.username);       //undefined
console.log(Point.username);   //zhangsan

上面代码中,直接使用 Point.username 方式给类添加一个属性,此种方式只是添加了一个静态属性,访问时,只能通过类名才能访问。

4.ES6中的模块化编程

4.1.为什么使用模块化

历史上,JavaScript 一直没有模块(module)体系,无法将一个大程序拆分成互相依赖的小文件,再用简单的方法拼装起来。其他语言都有这项功能,比如 Ruby 的require、Python 的import,甚至就连 CSS 都有@import,但是 JavaScript 任何这方面的支持都没有,这对开发大型的、复杂的项目形成了巨大障碍。

<script src="module1.js"></script>
<script src="module2.js"></script>
<script src="libraryA.js"></script>

上面是最原始的 JavaScript 文件加载方式,如果把每一个文件看做是一个模块,那么他们的接口通常是暴露在全局作用域下,也就是定义在 window 对象中,不同模块的接口调用都是一个作用域中,一些复杂的框架,会使用命名空间的概念来组织这些模块的接口。

这种原始的加载方式暴露了一些显而易见的弊端

  1. 全局作用域下容易造成变量冲突
  2. 文件只能按照javaScripe的书写顺序进行加载
  3. 开发人员必须主观解决模块和代码库的依赖关系
  4. 在大型项目中各种资源难以管理,长期积累的问题导致代码库混乱不堪

在 ES6 之前,社区制定了一些模块加载方案,最主要的有 CommonJS 和 AMD 两种。前者用于服务器,后者用于浏览器。

在 ES6 之后,ES6 在语言标准的层面上,实现了模块功能,而且实现得相当简单,完全可以取代 CommonJS 和 AMD 规范,成为浏览器和服务器通用的模块解决方案。

4.2.ES6模块化实现

模块功能主要由两个命令构成:export和import。 export命令用于规定模块的对外接口 import命令用于输入其他模块提供的功能。

4.2.1.export 命令

export let firstName = 'Michael';
export let lastName = 'Jackson';
export let year = 1958;

上面代码中,使用export命令对外部输出了三个模块。

let firstName = 'Michael';
let lastName = 'Jackson';
let year = 1958;
export { firstName as f,   //可以使用as关键字,重命名对外接口lastName, year 
};

上面代码是export命令的另外一种写法。 在export命令后面,使用大括号指定所要输出的一组变量。它与前一种写法(直接放置在let语句前)是等价的,但是应该优先考虑使用这种写法。因为这样就可以在脚本尾部,一眼看清楚输出了哪些变量。

export function multiply(x, y) {return x * y;
};
export class Point {constructor(x, y) {this.x = x;this.y = y;}toString() {return this.x + ',' + this.y;}
};

export命令除了输出变量,还可以输出函数、类(class)。

4.2.2.import命令

  1. 使用export命令定义模块对外接口后,其他 JS 文件就可以通过import命令加载这个模块。
import { name, age, sex } from './module1.js‘
console.log(name + '\t' + age + '\t' + sex);
  1. 上面代码的import命令,用于加载module1.js文件,并从中输入变量。import命令接受一对大括号,里面指定要从其他模块导入的变量名。大括号里面的变量名,必须与被导入模块( module1.js)对外接口的名称相同。
  2. import命令可以使用as关键字,将输入的变量重命名。
import { lastName as surname } from './profile.js';
  1. import命令具有提升效果,会提升到整个模块的头部,首先执行
foo();
import { foo } from './my_module.js';
  1. 上面的代码不会报错,因为import的执行早于foo的调用。这种行为的本质是,import命令是编译阶段执行的,在代码运行之前。
  2. import是静态执行,所以不能使用表达式和变量,这些只有在运行时才能得到结果的语法结构。
// 报错
import { 'f' + 'oo' } from './my_module.js';
// 报错
let module = ‘./my_module.js';
import { foo } from module;
// 报错
if (x === 1) {import { foo } from './module1.js';
} else {import { foo } from './module2.js';
}
  1. 如果多次重复执行同一句import语句,那么只会执行一次,而不会执行多次
import './lodash.js';
import './lodash.js';
  1. 上面代码加载了两次lodash,但是只会执行一次。
  2. import语句是 Singleton 模式
import { foo } from './my_module.js';
import { bar } from './my_module.js';
// 等同于
import { foo, bar } from './my_module.js';
  1. 上面代码中,虽然foo和bar在两个语句中加载,但是它们对应的是同一个my_module实例。也就是说,import语句是 Singleton 模式。

4.2.3.完整实例

(注意:当使用本地file协议打开文件时,type="module" 会产生跨越请求,从而导致跨越失败。所以下面代码需要在服务器环境下运行。 )

  1. profile.js文件
export var firstName = 'Michael';
export var lastName = 'Jackson';
export var year = 1958;
export function jia(x, y) {return x + y;
}
export function jian(x, y) {return x - y;
}
export class Point {constructor(x, y) {this.x = x;this.y = y;}toString() {return this.x + '\t' + this.y;}
}
  1. app.js文件:
import {firstName,lastName,year,jia,jian,Point} from './profile.js'
console.log(firstName + '\t' + lastName + '\t' + year);
console.log(jia(1,2));
console.log(jian(1,2));
let obj = new Point(1,2)
console.log(obj.toString());

注意: from './profile.js' 即使是在同一个文件夹中,也必须要写 ./

  1. index.html文件:
<script src="js/app.js" type="module"></script>

4.3.模块的整体加载

除了指定加载某个输出值,还可以使用整体加载,即用星号(*)指定一个对象,所有输出值都加载在这个对象上面。

// circle.js文件
export function area(radius) {return Math.PI * radius * radius;
}
export function circumference(radius) {return 2 * Math.PI * radius;
}
//main.js整体加载
import * as circle from './circle.js';
console.log('圆面积:' + circle.area(4));
console.log('圆周长:' + circle.circumference(14));

4.4.export default 命令

使用import命令的时候,用户需要知道所要加载的变量名或函数名,否则无法加载。但是,用户肯定希望快速上手,未必愿意阅读文档,去了解模块有哪些属性和方法。

为了给用户提供方便,让他们不用阅读文档就能加载模块,就要用到export default命令,为模块指定默认输出。

// export-default.js
export default function  () {console.log('foo');
}

上面代码是一个模块文件export-default.js,它的默认输出是一个函数。

// import-default.js
import customName from './export-default.js';
customName(); // 'foo'

上面代码的import命令,可以用任意名称指向export-default.js输出的方法,这时就不需要知道原模块输出的函数名。

注意:

  1. 一个js文件中,不能有两个export default命令。
  2. import命令后面,不使用大括号。因为只能写一个模块名。

export default命令用在非匿名函数前,也是可以的:

// export-default.js
export default function foo() {console.log('foo');
}
// 或者写成
function foo() {console.log('foo');
}
export default foo;

上面代码中,foo函数的函数名foo,在模块外部是无效的。加载的时候,视同匿名函数加载。

相关文章:

HTML-ES6.0核心技术

1.ES6简介 ECMAScript 6.0&#xff08;以下简称 ES6&#xff09;是 JavaScript 语言的下一代标准&#xff0c;已经在2015年6月正式发布了。它的目标&#xff0c;是使得 JavaScript 语言可以用来编写复杂的大型应用程序&#xff0c;成为企业级开发语言。ECMAScript 和 JavaScri…...

车间调度问题数学建模与CPLEX优化

完成了这些基础研究工作&#xff0c;整理成文档以供参考 序言... i 第一章 引言... 1 1.1 车间调度问题概述... 1 1.2 车间调度问题分类表示法... 5 1.3 车间调度对制造企业的作用... 6 1.4 本章小结... 7 第二章 CPLEX基础... 8 2.1 CPLEX概述... 8 2.1.1 CPLEX简介.…...

< 基础物理 >

SI国际单位制 常见的公制单位 为什么需要单位&#xff0c;是统一衡量的标准 通过国际单位&#xff0c;以及单位的拓展&#xff0c;以及单位的组合&#xff0c;形成一系列新的测量单位 面积 m^2 速率 m/s 米每二次方秒&#xff0c;m / s, delta表示增量, 每秒移动多少米 加…...

【web开发】Spring Boot 快速搭建Web项目(三)

Date: 2024.08.31 18:01:20 author: lijianzhan 简述&#xff1a;根据上篇原文Spring Boot 快速搭建Web项目&#xff08;二&#xff09;&#xff0c;由于已经搭建好项目初始的框架&#xff0c;以及自动创建了一个启动类文件&#xff08;TestWebApplication.java&#xff09; …...

无人机之战斗机的详解!

一、高性能飞行能力 高速飞行&#xff1a;具备较高的巡航速度和最大飞行速度&#xff0c;以便快速抵达任务区域并灵活应对战场情况。 长航程&#xff1a;拥有足够的航程以执行远程任务&#xff0c;覆盖广阔的作战区域 高升限&#xff1a;能够飞行到较高的高度&#xff0c;以…...

Verilog基础:时序调度中的竞争(四)(描述时序逻辑时使用非阻塞赋值)

相关阅读 Verilog基础https://blog.csdn.net/weixin_45791458/category_12263729.html?spm1001.2014.3001.5482 作为一个硬件描述语言&#xff0c;Verilog HDL常常需要使用语句描述并行执行的电路&#xff0c;但其实在仿真器的底层&#xff0c;这些并行执行的语句是有先后顺序…...

嵌入式边缘计算软硬件开发“1+X”考证建设方案

一、引言 随着物联网、大数据、人工智能等技术的飞速发展&#xff0c;嵌入式边缘计算作为连接物理世界与数字世界的桥梁&#xff0c;其重要性日益凸显。为了适应行业对高技能人才的需求&#xff0c;推动嵌入式边缘计算技术的普及与应用&#xff0c;特制定本“1X”考证建设方案…...

ES8的Java API client 8.0 简单示例操作 Elasticsearch

1.加入依赖 <dependency><groupId>co.elastic.clients</groupId><artifactId>elasticsearch-java</artifactId><version>8.12.2</version></dependency>2.配置类 Slf4j Configuration public class ElasticSearchConfig {Valu…...

多线程CompletableFuture

最近发现同事整理了一个不错的关于CompletableFuture的文档&#xff0c;在这里记录一下&#xff0c;方便以后工作备用 CompletableFuture future CompletableFuture.supplyAsync(() -> {return "开新线程异步执行"; })result future.get(); // 线程阻塞等待结果…...

AR传送门+特定区域显示内容+放大镜 效果着色器使用

AR传送门特定区域显示内容放大镜 效果 关键词&#xff1a;Portal Mask 1、教程链接&#xff1a; AR 传送门教程 Unity - Portal Mask Implementation - Part 4_哔哩哔哩_bilibili 应用案例效果&#xff1a; 2、案例下载地址&#xff1a;使用unity 2021.3.33f1 obi 工具…...

设置Hadoop守护进程的JVM参数

一般情况下我们不去动守护进程的JVM&#xff0c;这里的守护进程说的是NameNode、DataNode等Hadoop服务自己本身的进程。但是有一些特殊情况下需要限制&#xff0c;比如工作中虽然集群中资源队列会有10%左右的预留空余&#xff0c;不过这是整个集群队列的限制&#xff0c;对于Da…...

可视化大屏

可视化大屏 是一种利用计算机图形学技术&#xff0c;将复杂的数据和信息转换为直观的可视化图形&#xff0c;以呈现数据信息的工具。它不仅在电影中常见&#xff0c;而且已经实实在在地被应用在商业、金融、制造等各个行业的业务场景中&#xff0c;成为大数据分析和展示的重要工…...

pytest框架

pytest测试框架 单元测试框架定义&#xff1a;针对软件开发最小的单元&#xff08;函数&#xff0c;方法&#xff09;进行正确性位置测试 单元测试框架&#xff1a;java&#xff08;junit&#xff0c;testing&#xff09;python&#xff08;unittest&#xff0c;pytest&#…...

基于大数据的亚健康人群数据分析及可视化系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码 精品专栏&#xff1a;Java精选实战项目…...

黄金短线交易策略:波动中的高效盈利之法

今日&#xff0c;亚市盘初&#xff0c;现货黄金就高位震荡。在昨日金价再度冲高&#xff0c;一度刷新历史高点至2685.49美元&#xff0c;收报2672.25美元。其中主要原因是美国公布了最新的核心PCE&#xff08;个人消费支出&#xff09;物价指数和初请失业金人数等经济数据&…...

西陆家政系统V1.0.1

微信小程序开发的西陆家政服务管理系统小程序 V1.0.1bug修复优化 1.修复首页轮播不能自动轮播问题;2.修复订单详情价格显示问题;3.修复在开放城市模式下,其他城市可以下单问题;4.修复个人二维码跳转小程序路径异常问题;5.修复小程序编辑我的地址选择定位后不刷新问题&#xf…...

时间安全精细化管理平台/iapp/mobile/facereg/facereg.html接口存在未授权访问漏洞

漏洞描述 登录--时间&安全精细化管理平台/iapp/mobile/facereg/facereg.html接口存在未授权访问漏洞&#xff0c;黑客可以未授权等级员工信息对平台造成影响 FOFA&#xff1a; body"登录--时间&amp;安全精细化管理平台" 漏洞复现 IP/iapp/mobile/facereg…...

自动化测试实例:Web登录功能性测试(无验证码)

&#x1f345; 点击文末小卡片 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 一、什么是自动化测试 把人为驱动的测试行为转化为机器执行的一种过程称为自动化测试。(来自百度百科)本质上来说&#xff0c;自动化测试对比起手工测试除了需要…...

【算法篇】二叉树类(3)(笔记)

目录 一、Leetcode 题目 1. 二叉树的最近公共祖先 2. 二叉搜索树的最近公共祖先 &#xff08;1&#xff09;递归法 &#xff08;2&#xff09;迭代法 3. 二叉搜索树中的插入操作 &#xff08;1&#xff09;递归法 &#xff08;2&#xff09;迭代法 4. 删除二叉搜索树中…...

基于php的律所管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码 精品专栏&#xff1a;Java精选实战项目…...

MySQL 之索引详解

想象一下&#xff0c;你正在图书馆寻找一本关于 MySQL 索引的书。图书馆里有成千上万本书&#xff0c;但没有目录。你只能一排一排、一本一本地找&#xff0c;直到找到你想要的书。这将会花费大量的时间&#xff01;数据库索引就像图书馆的目录一样&#xff0c;可以帮助数据库系…...

C#测试调用FreeSpire.PDFViewer浏览PDF文件

Free Spire.PDFViewer是商业版Spire.PDFViewer的社区版本&#xff0c;支持以控件形式打开并查看PDf文件&#xff0c;但由于是免费版本&#xff0c;存在使用限制&#xff0c;打开的PDF文档只显示前10页内容。如果日常操作的pdf文件都不超过10页&#xff0c;可以考虑使用Free Spi…...

又一挣钱副业:AI生成影视解说,半个月涨粉变现3.5W+!

这两年大家都在感叹生活不易&#xff0c;然而我想说的是&#xff0c;机会还是有的&#xff0c;但问题不在于有没有&#xff0c;而在于你是否能够认准机会&#xff0c;然后抓住它。 接触过很多咨询项目的人&#xff0c;发现很多人依旧停留在传统思维中&#xff0c;认为副业就是…...

R语言 基础 笔记 3

起因, 目的: 思考一个问题: AI 这么强,AI 什么都知道,为什么还要学习这些基础的东西, 为什么还要写这些笔记? 我觉得,大体过一遍,还是有好处的。 有个大致印象,下次查的时候,也方便一些。 几个函数 cbind() 按照列,拼接数据, 会改变某些列的数据类型。data() 查看…...

【MySQL】常见的SQL优化方式(一)

目录 1、插入数据 &#xff08;1&#xff09;批量插入 &#xff08;2&#xff09;手动提交事务 &#xff08;3&#xff09;主键顺序插入 2、主键优化 &#xff08;1&#xff09;页分裂 &#xff08;2&#xff09;页合并 3、order by 优化 &#xff08;1&#xff09;排…...

【重点】使用axios.request.put上传文件,报错分析

使用axios的put方法上传文件时&#xff0c;如果遇到错误&#xff0c;可能的原因有以下几点&#xff1a; 跨域问题&#xff1a;如果请求的URL与当前页面的域名不同&#xff0c;可能会触发跨域问题。解决方法是在服务器端设置允许跨域请求&#xff0c;如设置CORS&#xff08;跨域…...

最新最全的阿里大模型面试真题!看到就是赚到

前言 随着人工智能技术的飞速发展&#xff0c;计算机视觉&#xff08;CV&#xff09;、自然语言处理&#xff08;NLP&#xff09;、搜索、推荐、广告推送和风险控制等领域的岗位越来越受到追捧&#xff0c;掌握大型模型技术已成为这些岗位的必备技能。然而&#xff0c;目前公开…...

使用Docker快速本地部署RSSHub结合内网穿透访问RSS订阅源

文章目录 前言1. Docker 安装2. Docker 部署Rsshub3. 本地访问Rsshub4. Linux安装Cpolar5. 配置公网地址6. 远程访问Rsshub7. 固定Cpolar公网地址8. 固定地址访问 前言 今天和大家分享的是如何在本地快速简单部署Rsshub工具&#xff0c;并结合cpolar内网穿透工具使用公网地址远…...

win10系统K8S安装教程

准备工作 电脑硬件&#xff1a;支持虚拟化的CPU&#xff0c;内存最好在32G以上&#xff0c;16G也可以操作系统&#xff1a;window10 专业版 1 开启虚拟化 1.1 BIOS 由于主板和CPU的品牌不太一样&#xff0c;这里的操作仅供参考&#xff0c;以Intel的平台为例&#xff1a; …...

C#和Python共享内存技术

我这里做一个简单的示例 1.C#写入内存的方法&#xff0c;FileName是内存共享的名字 t是内存size public static void SaveGluePLYToMemory(string FileName, string msg){try{ long t 100;// SetMemorySize(msg);// 100;//# 创建内存块&#xff0c;test1,其他语言利用这个内存…...