基础
数组
let arr = [数据1,数据2,...数组n]
使用数组
数组名[索引]
数组长度
arr.length
操作数组
arr.push() 尾部添加一个,返回新长度
arr.unshift() 头部添加一个,返回新长度
arr.pop() 删除最后一个,并返回该元素的值
shift 删除第一个单元
数组的尾部有点像栈顶,头部像栈底
所以,push的时候,在尾部添加,pop的时候再尾部删除
shift,unshift操作的就是栈底的东西,也就是头部
数组进阶用法
map() 遍历
<script>const arr = ['red', 'blue', 'pink']const newArr = arr.map((ele,index) => {console.log(ele);console.log(index);return ele;})console.log(newArr);</script>
map有返回值,forEach没有返回值
map里边的函数,ele,index不是必须要写的
但是只有一个参数的话,看作是element
join()
有点像java中的合并数组
<script>const arr = ['red', 'blue', 'pink']let a = arr.join();console.log(a);let a1 = arr.join("");console.log(a1);let a2 = arr.join("|");console.log(a2);</script>
空则就是逗号分隔
forEach
加强版for
被遍历的数组.forEach(function(当前数组元素,当前元素索引号){//函数体
})
element必须写,index可选
filter
array.filter(function(element, index, arr), thisValue)
除了element是必须,其他都是可选
- index索引
- arr当前数组
- thisValue 传this给回调函数,因为作用域不同
filter函数就是遍历加筛选,然后返回一个数组
sort
arr.sort((a,b) => {
return a - b;
)
a - b 就是降序
b - a 就是升序
reduce
累加
数组名.reduce(function(上一次值,当前值){ },起始值)
有初始值,就加上初始值
这里的当前值,就是当前数组的元素
from
Array().from()
把伪数组转成真数组
块级作用域和函数作用域
{} 花括号里边就是块级作用域
一般为了块级作用域里边的数据不和外边的干扰,里边的变量用let
函数作用域
函数里边的作用域
let const var
前两个是ES6
const 是常量,必须初始化,不能再被赋值
但是引用变量里的值可以修改,毕竟引用变量实际上是地址
let 声明于块级作用域的变量,和var相比有更小的的作用域范围,只在块级作用域里边有效,不会提升到函数作用域
<script>if(true) {let i = 0;}console.log(i); </script>
var是ES5
var 现在一般不使用,毛病多
可以先使用再声明,且可以重复声明
<script>var i;console.log(i);i = 10;var j = 1;var j = 2;console.log(j);</script>
var声明的变量有点像全局变量,所以在块级作用域里边的时候,会被提升到外部函数作用域
<script>if(true) {var i = 0;}console.log(i); </script>
模版字符串
``
有点类似于php中的字符串,可以写变量,写表达式,写多行字符串
const name = 'jjking';const msg = `Hello,${name}`;const a = 10;const b = 5;const msg1 = `${a + b}`;const msg2 = `hhellddd`console.log(msg);console.log(msg1);console.log(msg2);
注意事项
- 要输出 `反引号 得用 \
- 换行会被保留 直接写 \n
- 可以嵌套模版字符串
- 兼容性可能不好,要兼容低版本浏览器,用插件
箭头函数
ES6引入
(argument1, argument2, ...) => {// 函数体
}
有点像java里边的lambda
返回的如果是一个对象,得加一个括号
<script>const fun = () => ({name:'jjking'});console.log(fun());</script>
特点
- 没有this,继承父级作用域的this
- 没有arguments对象
- 没有Constructor,无法new fun()
- 没有prototype
箭头函数和普通函数的转换
- 只有一个参数,可以省略括号
- 只有一行的话,可以省略return,和{}
类似于java中的lambda
this指向
全局作用域的this
严格模式下,this是undefined
非严格,浏览器是window,node.js是global对象
一般函数this
指向的是自己
箭头函数的this
指向的父类的作用域
不适合箭头函数的场景
- 构造函数
- 需要this获取自身对象
- 需要使用arguments
解构赋值
数组的解构赋值
按照索引位置进行赋值
// 基本用法
const [a, b, c] = [1, 2, 3];
console.log(a); // 输出: 1
console.log(b); // 输出: 2
console.log(c); // 输出: 3// 使用默认值
const [x, y, z = 0] = [4, 5];
console.log(x); // 输出: 4
console.log(y); // 输出: 5
console.log(z); // 输出: 0(默认值)
把右边的值,一个一个赋值给左边,左边的可以有默认值
函数的解构赋值
按照属性名字进行赋值
// 基本用法
const {name, age} = {name: "Alice", age: 20};
console.log(name); // 输出: "Alice"
console.log(age); // 输出: 20// 使用别名
const {name: personName, age: personAge} = {name: "Bob", age: 25};
console.log(personName); // 输出: "Bob"
console.log(personAge); // 输出: 25// 使用默认值
const {firstName = "Unknown", lastName = "Unknown"} = {firstName: "Charlie"};
console.log(firstName); // 输出: "Charlie"
console.log(lastName); // 输出: "Unknown"(默认值)
注意
- 对于已经声明的变量进行解构赋值,必须在圆括号里边进行
let x, y;// 错误的写法:解析为代码块
{x, y} = {x: 1, y: 2};// 正确的写法:圆括号中进行解构赋值
({x, y} = {x: 1, y: 2});console.log(x,y); // 输出: 1 2
js会把{} 看做是代码块,所以会有歧义
其他的解构赋值
字符串
const [a, b, c] = 'abc';
console.log(a); // 输出: 'a'
console.log(b); // 输出: 'b'
console.log(c); // 输出: 'c'
数值和布尔值的解构赋值:会先将数值和布尔值转换为对应的包装对象类型(Number、Boolean),然后再进行解构赋值。
const {toString: numToString} = 123;
console.log(numToString === Number.prototype.toString); // 输出: trueconst {valueOf: boolValueOf} = true;
console.log(boolValueOf === Boolean.prototype.valueOf); // 输出: true
undefined 和 null 的解构赋值:在解构赋值时,如果源值是 undefined 或者 null,则会使用默认值
const [x = 0, y] = [undefined, 2];
console.log(x); // 输出: 0(默认值)
console.log(y); // 输出: 2const {z = 'default'} = {z: null};
console.log(z); // 输出: null(原始值)
模块化
概念
按照一定规则拆分成多个文件,这种编码方式是模块化编程
拆分出来的文件,是隔离的,所以模块中的数据是私有的,如果外边想知道的话,export暴露出去
为什么需要模块化
全局污染问题
依赖混乱问题
数据安全问题
模块化规范
CommonJS 服务端
AMD
CMD
ES6 模块化 浏览器端
导入导出概念
导出,就是公开一些接口
导入,就是导入别人公开的接口
CommonJS
index.js
const school = require('./school.js')
console.log(school);
school.js
const name = 'shanggui'
const slogan = '然天下没有南徐的技术'function getTel() {return '010-3333'
}function getCities() {return ['北京','上海']
}
此时运行index.js 输出为空
原因是,在school.js中,他有一个对象也就是{},我们没有给他加入东西进去
使用exports
const name = 'shanggui'
const slogan = '然天下没有南徐的技术'function getTel() {return '010-3333'
}function getCities() {return ['北京','上海']
}exports.name = name;
exports.slogan = slogan;
exports.getTel = getTel;
index.js运行
两种方式
module.exports = value
exports.name = value
const name = 'shanggui'
const slogan = '然天下没有南徐的技术'function getTel() {return '010-3333'
}function getCities() {return ['北京','上海']
}// exports.name = name;
// exports.slogan = slogan;
// exports.getTel = getTel;module.exports = {name,slogan,getTel}
注意
:
每个模块的内部 this,exports,module.exports 在初始化的时候,都指向的是同一个空对象
无论如何修改导出对象,最终导出的都是module.exports的值
不能使用exports = value的形式导出数据,这就是赋值
可以用module.exports = xxx
导入
我们在student.js,school.js 暴露
school.js
const name = 'shanggui'
const slogan = '然天下没有南徐的技术'
function getTel() {return '010-3333'
}
function getCities() {return ['北京','上海']
}
module.exports = {name,slogan,getTel}
student.js
const name = 'jjking'
const motto = '相信明天会更好'
function getTel() {return '13816666666'
}
function getHobby() {return ['抽烟','喝酒']
}
module.exports = {name,motto,getTel}
index.js
const {name,slogan,getTel} = require('./school.js')
const {name,motto,getTel} = require('./student.js')
console.log(name);
我们在导入的时候,可以用解构赋值但是如果这里的导入可能会有重名问题
为了解决重名,我们另外取名字
const {name,slogan,getTel} = require('./school.js')
const {name:stuName,motto,getTel:stuGetTel} = require('./student.js')
console.log(name);
扩展理解
意思是,实际上,在js中,他已经包了一层函数给我们,函数的参数是exports,require,module…
所以数据是隔离的
浏览器端运行
Node.js默认支持CommonJS,但是浏览器不行
<!DOCTYPE html>
<html lang=""><head><meta charset="UTF-8"><link rel="icon" href="/favicon.ico"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Vite App</title></head><body><script src="./index.js"></script></body>
</html>
const {name,slogan,getTel} = require('./school.js')
const {name:stuName,motto,getTel:stuGetTel} = require('./student.js')console.log(name);
运行的话,会报错
所以我们需要安装一个依赖
ES6 模块化
服务器端,浏览器端都适配
初步体验
school.js
export const name = 'shanggui'
export const slogan = '然天下没有南徐的技术'
export function getTel() {return '010-3333'
}
function getCities() {return ['北京','上海']
}
index.js
import * as school from './school.js'
console.log(school);
index.html
<!DOCTYPE html>
<html lang=""><body><script type="module" src="./index.js"></script></body>
</html>
这里必须type写成module,不然用不了import
Node.js运行
在js包下,写一个配置
package.json
{"type": "module"
}
运行index.js
导出
分别导出
export const name = 'shanggui'
export const slogan = '然天下没有南徐的技术'
export function getTel() {return '010-3333'
}
function getCities() {return ['北京','上海']
}
统一导出
const name = 'shanggui'
const slogan = '然天下没有南徐的技术'
function getTel() {return '010-3333'
}
function getCities() {return ['北京','上海']
}
export {name,slogan,getTel}
注意,这里导出的不是对象,只是类似对象的东西
默认导出
const name = 'shanggui'
const slogan = '然天下没有南徐的技术'
function getTel() {return '010-3333'
}
function getCities() {return ['北京','上海']
}
export default {name,slogan,getTel}
这里导出的是对象,且他会在对象上写一个default,里边使我们要导出的对象
导入
导入全部
import * as school from './school.js'
命名导入
适用于分别导出,统一导出
school.js
const name = 'shanggui'
const slogan = '然天下没有南徐的技术'
function getTel() {return '010-3333'
}
function getCities() {return ['北京','上海']
}
export {name,slogan,getTel}
index.js
import {name as schoolName,slogan,getTel} from './school.js'
console.log(school);
命名导入,我们可以取别名
默认导入
对于默认导出,我们用默认导入的话,我们可以直接用一个变量来接
school.js
const name = 'shanggui'
const slogan = '然天下没有南徐的技术'
function getTel() {return '010-3333'
}
function getCities() {return ['北京','上海']
}
export default {name,slogan,getTel}
index.js
import school from './school.js'
console.log(school);
这样是最快的
默认导入和命名导入混合
两个是可以一起用的
school.js
const name = 'shanggui'
const slogan = '然天下没有南徐的技术'
function getTel() {return '010-3333'
}
function getCities() {return ['北京','上海']
}
export {name,slogan}
export default {getTel}
index.js
import getTel,{name,slogan} from './school.js'
console.log(getTel);
console.log(name);
console.log(slogan);
动态导入
index.js
const btn = document.getElementById("btn")
btn.onclick = async () => {const stu = await import('./student.js');console.log(stu);
}
index.html
<!DOCTYPE html>
<html lang=""><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Vite App</title></head><body><button id="btn">点击</button><script type="module" src="./index.js"></script></body>
</html>
动态不知道体现在哪,但在就是我们可以使用import当函数
数据引用问题
es6中,我们import出来的东西是一个常量,但是index.js(左边) 的sum和右边导出的sum是公用一个空间的,恰巧此时右边的sum是let,我们可以修改他的值
所以,我们在index.js中,修改了sum的值,也就会修改我们自己import的num,最后会变成3
总结来看,es6中,我们导出的东西,能用const就用const,不要用let