ES6全集基础总结(上)
一:let和const和var function
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<ul id="ListA">
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<ul id="ListB">
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<ul id="ListC">
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
</body>
<script type="text/javascript">
// 作用域一旦形成,先进行变量提声,先找到var或者function
// var变量提声 function即声明又定义
//使用var和function声明的变量会给window增加属性(全局作用域)
console.log(a); //undefined
var a = 1;
console.log(window.a);
console.log(getA); //function getA()
function getA() {}
// let没有变量提声,不可以重复声明,不会给window增加属性
// console.log(b); //b is not defined
let b;
b = 1;
// const没有变量提声,不可以重复声明,不会给window增加属性
// const定义常量,不可以重新赋值;一旦声明必须赋值
const c = 1;
//块级作用域{}:一个{}就是一个块级作用域
//块级作用域下var和function声明的变量是全局的
//块级作用域下let和const声明的变量是私有的
console.log(d);//undefined
{
var d = 0;
function getD() {}
let e = 0;
}
console.log(d); //0
getD();
// console.log(e);//e is not defined
// -----块级使用1: -----对象{}
let obj = { //{}如果想表示为对象,不可以放在行首,放一个定义
name: "yaoyao",
age: 10
};
({
name: "yaoyao",
age: 10
}) //{}想表示对象,用()包起来
//字符串变表达式用eval
console.log(eval('({name:"yaoyao",age:10})')) //{name: "yaoyao", age: 10}
console.log(eval(' o={name:"瑶瑶",age:20}')) //{name: "瑶瑶", age: 20}
console.log(o); //{name: "瑶瑶", age: 20}
//-----块级使用2: ------for(){};
let ListA = document.getElementById("ListA").getElementsByTagName("li");
for (var i = 0; i < ListA.length; i++) {
ListA[i].onclick = function() {
alert(i); //无论点谁都是3,因为最后触发i已经为3了。想要每一项,用下面那种
}
}
console.log(i); //3
let ListB = document.getElementById("ListB").getElementsByTagName("li");
for (var i = 0; i < ListB.length; i++) {
ListB[i].index = i;
ListB[i].onclick = function() {
alert(this.index); //此时点击每一项是他自己的索引下标,但是麻烦。
}
}
console.log(i)//3
let ListC = document.getElementById("ListC").getElementsByTagName("li");
for (let i = 0; i < ListC.length; i++) {
ListC[i].onclick = function() {
alert(i); //用let声明最简单有效。
}
}
console.log(i)//3
//-----块级使用3: ------if(){};
//if(){}中的function只会提前声明不会定义,当条件成立先给函数赋值,代码再执行。
if (0) {
var f = 1;
function getF() {}
}
</script>
</html>
二:结构赋值
1:对象
`<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
</body>
<script type="text/javascript">
// 如果变量名和属性名一样,可以直接省略写法 。即name->name,age->age
let {
name,
age
} = {
name: "瑶瑶",
age: 10
}
console.log(name, age); //瑶瑶 10
//默认值。特别注意:如果属性的内容不为undefined,还是赋值覆盖默认值。
let {
a,
b = 0,
c = 10
} = {
a: "瑶瑶",
b: undefined,
c: 20
}
console.log(a, b, 20); //瑶瑶 0 20
//嵌套。
let {
x,
y = 0,
list: [l1, l2, l3]
} = {
x: "瑶瑶",
y: undefined,
list: ["js", "node", "vue"]
}
// console.log(x,y,list);//错误!!!因为list是属性名,要变量
console.log(x, y, l1, l2, l3); //瑶瑶 0 js node vue
// 表示对象时{}一定不能放在行首,{}要表示对象一定要()包起来!!!!
//{}放在行首表示块级作用域
let x1, x2;
({
x1,
x2
} = {
x1: 1,
x2: 2
});
console.log(x1, x2); //1,2
</script>
</html>
2:函数
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
</body>
<script>
//省略赋值
function getA([a, b, c, ...d]) {
console.log(a, b, c, d); //1 2 3 [4,5,6]
}
getA([1, 2, 3, 4, 5, 6])
//函数赋值大于默认值,没有默认值为undefined,有默认值为默认值
function getB({name = "爱学习",age,sex}) {
console.log(name, age, sex); //瑶瑶 10 undefined
}
getB({name: "瑶瑶",age: 10});
function getC({name,age} = {}) {
console.log(name, age); //大壮 10
}
getC({name: "大壮",age: 10});
// function getD({name:"丹妹",age:8}){
// console.log(name,age);//报错 ,相当于赋的undefined,如果传的空用如下方法
// }
// getD();
function getD({name = "丹妹",age = 8} = {}) {
console.log(name, age); //丹妹 8;其中只要赋了值,就不会走到等号右边{}赋值
}
getD();
function getE({name,age} = {name: "啊妹",age: 12}) {
console.log(name, age); //啊妹 12
}
getE();//区别E和F就在方法中赋值{}时为赋值undefined
function getF({name,age} = {name: "萍姐",age: 9}) {
console.log(name, age); //undefined undefined
}
getF({});
</script>
</html>
3:其他
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
</body>
<script type="text/javascript">
//使用数组的解构赋值的形式。如果等号右边不是一个数组 默认将其转换为类数组(类似数组的对象 必须有一个length属性)
let [x1, x2] = "123";
console.log(x1, x2) //1 2
let [x3, x4] = "1";
console.log(x3, x4); //1 undefined
// 使用对象的结构赋值的形式。如果等号右边不是对象,默认转为对象,再进行赋值
let {a} = 1;
console.log(a); //undefined
// 因为console.log(Object(1)); //{} ->{_proto_:},所以如下:
let {
__proto__: b
} = 1;
console.log(b); //Number {0, constructor: ƒ, toExponential: ƒ, toFixed: ƒ, toPrecision: ƒ, toString: ƒ, …}
//再如
let {length:c}="1234";
console.log(Object(c));//{}
console.log(c);//4 length作为属性名,c作为值,拿到“1234”的length赋值;
</script>
</html>
4:数组
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
</body>
<script type="text/javascript">
let [x, y, m, n] = [1, 2, 3, 4]; // 等价于let arr=[1,2,3,4];let x=arr[0]....;
let [a, b] = [1, 2, 3]; //a为1,b为2,剩余的不影响
// 设置默认值,特别注意:只有后面结构的值是undefined时才会走默认值!!!
let [x1, x2 = 0] = [1, 2]; //x1为1,x2为2。赋值大于默认值
let [y1, y2 = (function() {
console.log("hh");
return 10
})] = [1, undefined];
console.log(y1, y2); //1 function () {console.log("hh");return 10}
// 省略赋值。
let [, , z1] = [1, 2, 3];
console.log(z1); //3
// 不定参数。将后面的项放在一个数组中赋值给m3
let [m1, m2,...m3] = [1, 2, 3, 4, 5];
console.log(m1,m2,m3); //1 2 [3,4,5]
</script>
</html>
三:字符串的扩展
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
</body>
<script>
// 常用字符串新增属性方法示例
console.log(String.prototype); //字符串的所有属性
//includes:判断有没有指定字符("指定字符",开始查找的位置(可选,null为0)) 返回布尔值 true/false
let str = "ABC"
console.log(str.includes("A", null));
//startWith:判断字符串是不是以指定字符开头(“指定字符”,开始查找的位置(可选) endswith
console.log(str.startsWith("A", 2));
//endswith:判断字符串是不是以指定字符结尾(“指定字符”,num(可选,从前num个查看))
console.log(str.endsWith("C", 1));
//repeat(num):将字符串重复num次,其中num取整不可以是负数或者infinty
console.log(str.repeat(2.2))
//padStart padEnd :按照指定字符不全字符串的指定长度(长度length,指定字符)
let str1 = "ab";
console.log(str1.padStart(7, "ss"));
console.log(str1.padEnd(7, "ss"));
//模板字符串
let str2 = `哈哈`;
console.log(str2);
let class1 = "box",name = "瑶瑶";
document.body.innerHTML += '<h1 class="' + class1 + '">' + name + '</h1>'
//等价于
document.body.innerHTML += `<h1 class="${class1}" >${name}</h1>`
</script>
</html>
四:数组的扩展
1:类上的扩展
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<!-- ul#list>li*4 -->
<ul id="List">
<li></li>
<li></li>
<li></li>
</ul>
</body>
<script>
console.dir(Array); //数组的属性
//array 类是一个函数 返回一个数组;Array(x,y,z)返回【x,y,z】;
console.log(Array(1, 2, 3)) //[1,2,3];
console.log(Array("1")) //["1"]
console.log(Array(7)) //[empty x 7]//参数为数字时,返回n个空位的数组
//array.of();同array,区别在参数为数字时返回任意一个只有一项的数组
console.log(Array.of(7))//[7]
// array.from(数组/类数组);返回一个数组
console.log(Array.from([1, 2, 3])); //【1,2,3】
console.log(Array.from("123")); //【"1","2","3"】
// console.log(Array.from(List.getElementsByTagName("li")); //【1,2,3】
</script>
</html>
2:数组空位
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
</body>
<script type="text/javascript">
// 数组的空位 数组的某个索引位置没有任何值 注:undefined不是空位
//判断一个数组中的某一个位置是不是空位用in
//in:判断数组索引位置上有没有值
let arr = [, , , , undefined];
console.log(arr.length); //5
console.log(1 in arr); //false
console.log(0 in arr); //false
// es5中数组方法一般直接跳过空位
for (let key in arr) {
console.log(key);//4,打印索引下标
}
//es6中数组方法将空位处理为undefined
for (let key of arr) {
console.log(key);//undefined undefined undefined undefined undefined
}
</script>
</html>
3:数组原型上的扩展
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
</body>
<script type="text/javascript">
console.log(Array.prototype)
//copyWithin:从原数组中读取内容 替换数组指定位置的内容 如果数组超出就截取掉保证原数组长度不变
// (替换目标的起始位置,查找的起始位置[,查找结束的位置)默认到结尾)
let ary1 = [1, 2, 3, 4, 5, 6, 7, 8];
console.log(ary1.copyWithin(4, 1, 4)); //(8) [1, 2, 3, 4, 2, 3, 4, 8]
//遍历数组的方法 参数是一个函数,这个函数中的this是window,我们可以通过第二个参数改变函数中的this
//reduce 和reduceRight中的函数不可以改this
//fill:按照指定字符换填充数组("指定字符",替换位置【n,m)可选)
console.log(ary1.fill("瑶瑶", 2, 5)); // (8) [1, 2, "瑶瑶", "瑶瑶", "瑶瑶", 3, 4, 8]
//filter:根据返回值过滤原数组
let ary2 = ["瑶瑶", 1, 2, 3, "yaoyao"];
console.log(ary2.filter(function(item, index) {
// true:留下当前项;false:不留下当前项
console.log(this);//更改this,下面函数加的ary2即改变this
return typeof item === 'number'; //[1,2,3]
}), ary2)
//find:遍历数组 一旦参数函数返回true 停止查找 返回当前项
let a = ary2.find(function(item) {
return typeof item === 'string';
})
console.log(a); //1
//findindex:同上,异:返回索引下标
//includes:判断数组中有没有某一项("指定的内容",开始位置(可选))
console.log([1, 2, 3].includes(1)); //true
//every:遍历数组。如果遍历每一项都true,返回true,有一个false结果就为false
console.log([1, 2, 3, 4, "瑶瑶"].every(function(item) {
return typeof item === 'number' //false
}))
//some:遍历数组。如果遍历,有一个true结果就为true
//reduce:迭代
let ary3 = [1, 2, 3, 4, 5];
ary3.reduce(function(prev, item) {
// prev:前一项的返回值;item:当前项
console.log(prev);
return prev;
}, 10) //给prev一个初始值
//reduceRight:迭代。同上,只是顺序从右开始
//keys:遍历。每一项索引的接口 使用for+of遍历
let ary4 = ["a", "b", "C", 4];
// for (let key of ary4.keys()) {
// console.log(key) //0 1 2 3 遍历的索引
// }
// for (let key of ary4) {
// console.log(key) //a b c 4 遍历每一项
// }
// for (let key in ary4) {
// console.log(key) //0 1 2 3 遍历索引
// }
for (let item of ary4.entries()) {
console.log(item) //[0,"a"][1,"b"] [2,"c"][3,4]
}
//以上遍历常用结构赋值
for (let [index, item] of ary4.entries()) {
console.log(index, item) //0 "a" 1 "b" 2 "c" 3 4
}
</script>
</html>
五:函数的扩展
1:参数的默认值
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
</body>
<script type="text/javascript">
//参数默认值
function fn(x = "瑶瑶", y = "ES6") {
// x = x || "学习";
// y = y || "认真";
console.log(x, y);
}
fn(0);
// 使用解构赋值 当不传值时。示例fn1,fn2,fn3
function fn1({name = "yy",age = "20"}={}) {
// {name = "yy",age = "20"}={}
console.log(name, age) //yy 20
}
fn1();
function fn2({name = "yy",age = "20"}) {
// {name = "yy",age = "20"}={}
console.log(name, age) //yy 20
}
fn2({});
function fn3({name,age} = {name: "瑶瑶",age : "20"}) {
console.log(name, age)//undefined undefined 未实例化报错
}
fn3({});
//解构赋值>默认值,有默认值为默认值,没有默认值为undefined
function fn4({name,age,height}) {
console.log(name, age,height)//大壮 10 undefined
}
fn4({name:"大壮",age : "10"});
//length属性,形参的个数,如果形参有默认值情况length就会失真变成没有默认值形参的个数
function fn5(x,y=10){
}
fn5(1,2);
console.log(fn5.length);//1 因为y有默认值,所以length变成没有默认值的形参的个数X
//参数默认值位置:一般参数的默认值放在最后边
function fn6(x=10,y=20){
}
// fn6(,1)会报错
//arguments 类数组
function fn7(){
console.log(arguments);
}
fn7(1,2,3,4,5);// [1,2,3,4,5]
function fn71(...arg){
console.log(arg)
}
fn71(1,2,3,4,5);//[1,2,3,4,5]
function fn72(){
console.log([...arguments]);
}
fn72(1,2,3,4,5);//[1,2,3,4,5]
// 参数作用域 ,赋值>全局作用域Let>私有作用域里let|var;
//函数执行的时候先给形参赋值,形参也是私有变量 如果给形参的默认值是一个变量先看是不是自己的私有变量,不是自己的在找全局中是否有这个变量,没有就报错
let a=1,b=2;
function fn8(x1=a,x2=b){
console.log(x1,x2);//1,2
var a="瑶瑶";//let也是
var b="爱学习";//let也是
}
fn8();//函数和var是提声变量,而且函数有定义,他是先进行的。
let r=100;
function fn81(r,y=r){
console.log(y);//1 赋值>默认值
}
fn81(1);
</script>
</html>
2:函数name问题
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
</body>
<script type="text/javascript">
function fn() {}
console.log(fn.name); //fn
console.log((function() {}).name); //fn
//特殊情况
// 1:通过bind方法得到一个新的函数name是“bound 原来函数的名字”
let fn1 = fn.bind(null);
console.log(fn1.name); //bound fn
//2:通过构造函数方式创建一个函数,名字都叫anonymous(匿名函数)
// new Function(“形参”,“函数体”)
// new Function(“函数体”)
// function fn(形参){函数体}
let fn2=new Function("x,y","console.log(x,y);return x+y");
console.log(fn2(10,100));//110
console.log(fn2.name);//anonymous
let str='[{"name":"瑶瑶"},{"age":"10"}]';
let arr=(new Function("return " +str))();
console.log(arr);//[{"name":"瑶瑶"},{"age":"10"}]
</script>
</html>
3:箭头函数
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
</body>
<script type="text/javascript">
//function fn(x,y){}
//箭头函数是匿名函数
// let fn=(形参)=>{函数体}
// 形参:形参只有一个的时候可以省略()
// 函数体:只有一行代码时, return可以省略{}和return
//基础示例 let fn = x => x + 1等价于 let fn=(x)=>{return x+1}
//1:通常函数当做参数的时候使用箭头函数
let ary = ["瑶瑶", 1, 2, 3];
console.log(ary.filter(item =>
typeof item == "number"
)); //[1,2,3]
// 不省略的()和{return XXX}写法如下
console.log(ary.filter((item) => {
return typeof item == "number"
})); //[1,2,3]
//2:箭头函数的特点
//(1):箭头函数没有this指向 里面的this是上一级作用域下的this,依次往上找到不是箭头函数的作用域
let obj = {
fn: function() {
let f = () => {
console.log(this); //箭头函数的this为上一级
}
f();
}
}
obj.fn(); // {fn: ƒ}即{"fn":"function (){let f=()=>{console.log(this);f();}"}
//(2):箭头函数没有arguments
// let f1=()=>{
// console.log(arguments);//arguments is not defined
// }
// f1();
let f2=(...arg)=>{
console.log(arg);//[1,2,3,4]
}
f2(1,2,3,4)
//(3):箭头函数不可以用作构造函数,因为不可以使用new执行
function FF(){}
new FF;
let F=()=>{};
// console.log(new F);// F is not a constructor
</script>
</html>
4:扩展运算符
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<ul id="List">
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
</body>
<script type="text/javascript">
// 扩展运算符 ...
// 1:将非数组变成数组 (类数组 length)
let str = "123";
console.log([...str]); // ["1", "2", "3"]
console.log(document.getElementById("List").getElementsByTagName("li")); //HTMLCollection(3) [li, li, li]
// console.log([...List.getElementsByName("li")]);
function fn() {
console.log(arguments); //[1,2,3,4]
}
fn(1, 2, 3, 4);
function fn1(...arg) {
console.log(arg); //[1,2,3,4]
}
fn1(1, 2, 3, 4);
function fn2() {
console.log([...arguments]); //[1,2,3,4]
}
fn2(1, 2, 3, 4);
// 2:将数组变成非数组
let arr1 = [1, 2, 3, 4];
let arr2 = [10, 20, 30, 40];
console.log(arr1.concat(arr2)); //[1,2,3,4,10,20,30,40]
console.log([...arr1, ...arr2]); //[1,2,3,4,10,20,30,40]
//求数组的最大值
let ary = [1, 23, 53, 46, 322, 2];
console.log(Math.max.apply(null, ary)); //322
console.log(eval("Math.max(" + ary + ")")); //322
console.log(Math.max(...ary));//322
</script>
</html>