1 ES5与ES6转换 babel==browser.js script type=text/babel
2. var ,let , const 的区别:
-
不存在变量提升
- var 命令会发生
变量提升
现象,即变量可以在声明之前使用,值为undefined
。 - let 和 const 则没有变量声明提升的功能,必须要先声明才能使用
- var 命令会发生
-
不允许重复声明
- var命令能重复声明,后者覆盖前者
- let 和 const不允许在相同作用域内,重复声明同一个变量
-
作用域
- var 的作用域是以函数为界限
- let 和 const 的作用域是块作用域,块级作用域指
{ }
内的范围 - var 可以定义全局变量和局部变量,let 和 const 只能定义局部变量
- const 的声明的常量不能被修改,但对于引用类型来说,堆内存中的值是可以被改变的。
-
变量作为全局属性
- 定义的变量会作为window对象的属性,let不会
定义:
全局变量: 在函数外部声明的变量/在函数内部直接赋值的变量
局部变量: 在函数内部声明的变量
李子0:
{
var a=10;
console.log(a)//10
}
console.log(a)// 10 a是全局变量,只是在{}中,并不在函数中
函数体内部可以读取到函数外的变量,而函数外不能读取到函数内的变量!如果函数外部想要读取函数内部的变量,可以使用闭包。
函数的作用域链:当前函数对象-->上一层函数对象...-->window全局对象
相互转换:
局部变量和全局变量重名时,局部变量会覆盖全局变量
变量提升:
出现的情况:变量先使用后声明时
提升方式:变量的声明(var y)提升,初始化赋值(y=7)不会。会显示未定义undefined
提升存在范围:代码块指的是function的一个{},通常的if、while、for的{}中变量不会提升。
JS引擎的工作方式:先获取所有被声明的变量再逐一执行,所有变量的声明语句都会被提升到当前代码块的头部’。
李子1:
Var a=10;
(function (){
Console.log(a) //undefined,存在变量提升,就是相当于var a;但赋值 a=10,未提升,全局变量和局部变量机制都一样
Var a=10;// 局部变量覆盖全局变量,a 变成局部变量
Console.log(a) //10
})()
李子2:
Console.log(b);var b=20;//undefined存在变量提升,就是相当于
Var b;console.log(b); b=20;//undefined
李子3:
var a=2;
(function show(){
console.log(a);//2
a=3;//还是全局变量(可以被函数内部访问—本来就是这样的),重新赋值,覆盖了原来的值,并且之前声明过了,属于先声明后使用,不存在变量提升
console.log(a)//3
})();
es6 let
1 不能重复声明
2 不存在变量提升现象(一定要先声明后使用,否则会直接报错)--->typeof
不再是一个百分之百安全的操作
3出现代码块级作用域 {代码块}
4允许在块级作用域之中声明函数,----块级作用域之中,函数声明语句的行为类似于let
,在块级作用域之外不可引用。----环境差异大,避免在块级作用域内声明函数
例子3:
var a=1;
if(true){
console.log(a);//1
(function fn(){ var a=2;console.log(a);})();//2
console.log(a);//1
};
console.log(a);//1
作用域有4种:全局 函数 eval(es5的严格模式下) 块级{}
var :函数作用域 可重复声明 存在变量提升(先使用后声明 undefined)可修改
let:块级作用域 不可重复声明 不存在变量提升(报错)可修改
例子1:
const:块级作用域 不可修改 不存在变量提升 常量用大写
tip: 修改数组和对象里面的值 不算修改常量(地址没有变)
=>可修改数组和对象里面的值
块级作用域的经典案例:
先循环后调用回调函数
3函数
定义方法
(1)参数扩展(必须试最后一个参数) function(a,b,...args)
适用场景:入参个数不确定
扩展:
1)展开数组(类似于直接放数组)
2) 拼接数组(1 concat 2遍历3push+扩展4 push+apply)
var a=[1,2,3];
var b=[4,5,6];
var c=[...a,...b];
console.log(c)
//[1, 2, 3, 4, 5, 6]
var arr = ['tom', 'jerry']; var arr2 = [1, 2]; arr.push(...arr2); console.log(arr)
var arr = ['tom', 'jerry']; var arr2 = [1, 2]; arr.push.apply(arr, arr2); console.log(arr)
(2)默认参数 function(a,b=2,c=8)
(3)箭头函数
(this 函数声明时所在的作用域下的this的值)
1修正this指向
2 不适用与this有关的回调(vue的钩子函数不能使用)
3 只有一个参数 可将()省略
4只有return 一个参数 可将 {} 省略
5只有一条语句 此时语句执行的结果必须试函数的返回值 可将 return {} 省略
4 结构赋值
满足的条件:1 左右两边的数据类型必须一致 2 右边必须是合法的数据类型 3声明和赋值必须一起
例子:
6生成器 generator
定义:function *a(){}
调用:let ab=a();
ab.next();//往下走
说明: yield 类似于墙 隔开函数(断点)暂停键
function getUser(){
setTimeout(()=>{
var data='用户';
gen.next(data);
},1000)
}
function getInfo(){
console.log(a)
setTimeout(()=>{
var data='订单';
gen.next(data);
},1000)
}
function getNum(){
console.log(b)
setTimeout(()=>{
var data='数量';
gen.next(data);
},1000)
}
var a,b,c;
function * ab(){
a=yield getUser();
console.log(a)
b=yield getInfo();
console.log(b)
c=yield getNum();
console.log(c)
}
var gen= ab();
gen.next();
next 一边将data反馈出来 一边推进执行
7 基本数据类型7种
USONB
undefined
string symbol
number null
object
boolean
8 Set();
似于数组,但它的一大特性就是所有元素都是唯一的,没有重复。
可以利用这一唯一特性进行数组的去重工作。
let list=new Set([1,1,2,3,4])
(1)添加元素 add
let list=new Set();
list.add="1"
list.add(2)
(2)删除元素 delete
let list=new Set([1,2,3,4])
list.delete(2)//true
(3).判断某元素是否存在 has
let list=new Set([1,2,3,4])
list.has(2)//true
(4)清除所有元素 clear
let list=new Set([1,2,3,4])
list.clear()
(5)遍历 values()
let list=new Set(['a','b','c'])
for(let value of Set.values()){
console.log(value)//a,b,c
}
(6)遍历 forEach()
let list=new Set(['4','5','hello'])
list.forEach(function((item){
console.log(item)
})
(7)数组转Set
let set2 = new Set([4,5,6])
let set3 = new Set(new Array(7, 8, 9))
(8)Set转数组
let set4 = new Set([4, 5, 6])
console.log('set to array 1:', [...set4])
console.log('set to array 2:', Array.from(set4))
(9)实现并集、交集、差集
let a = new Set([1,2,3]);
let b = new Set([4,3,2]);
let union = new Set([...a, ...b]);//并集
console.log(union);
let intersect = new Set([...a].filter(x => b.has(x)));//交集
console.log(intersect);
let difference = new Set([...a].filter(x => !b.has(x)));//差集
console.log(difference);
数组的交集差集并集 filter+includes
9 高阶函数: 一个函数可以接收另一个函数作为参数
map 映射
- map和forEach等遍历方法不同,在forEach中return语句是没有任何效果的,
- 而map则可以改变当前循环的值,返回一个新的被改变过值之后的数组(map需return),一般用来处理需要修改某一个数组的值。
let arr1=[1,2,3,4];
let arr2 = arr1.map((value,index) => {
return value * value;
});
console.log(arr2)
// [1, 4, 9, 16]
fliter 过滤
let arr1=[1,2,3,4];
let arr2 = arr1.filter((item,index) => {
return item>2
});
console.log(arr2)
// [3,4]
reduce 汇总(有中间值) 相加 相减 计算平均值
let arr1=[1,2,3,4];
let sum = arr1.reduce((sum1,n) => {
return sum1+n
},0);// 0 可加可不加
console.log(sum)
// 10
11.字符串遍历
let str = "hello";
//1.for遍历
for (let i = 0; i < str.length; i++) {
console.log(i, str[i]); //i 索引 数值类型
}
//2.数组->for->for in
let arr = [1, 2, 3];
for (let i in arr) {
console.log(i, arr[i]); //i 索引 字符串类型
}
//3.for... of
for(let i of str){
console.log(i); //数据
}
//4.解构----需要只要字符串的长度
let [a, b, c, d ,e] = str;
console.log(a, b, c, d ,e);
可以取字符串的第一位
let [a] = str;
console.log(a);
//字符串新增方法:
方法 返回值 作用
includes('str') boolean 判断字符串中包含子串
endWith('str') boolean 判断字符串以"str"结尾
startWith('str') boolean 判断字符串以"str"开头
repeat(n) 重复拼接自身 重复n次输出字符串 repeat + repeat
//不全方法: 达不到length的长度就补全字符串长度
str=
str.padStart(length, 's'); 字符串开头补全
str=
str.
endStart(length, 's'); 字符串末尾补全
12 set 和数组相互转换3种方式
let set = new Set();
set.add(1).add(2).add(3).add(2);
// 1.Array.from();
var arr = Array.from(set);
console.log(arr);
// 2.遍历set然后push
var arr = [];
set.forEach(i=>{
arr.push(i);
});
console.log(arr);
// 3.扩展运算符
var arr = [...set];
console.log(arr);
map、对象和字符串之间转化
let map = new Map();
map.set('name', 'jack').set('age', 22).set('tel', 151);
// 1.map -> 对象 -> String
var obj = {};
map.forEach((v,k)=>{
obj[k] = v;
})
console.log(obj);
var str = JSON.stringify(obj);
console.log(str);
// 2.String -> 对象 -> map
var obj1 = JSON.parse(str);
var map1 = new Map();
for(let i in obj1){
map1.set(i,obj1[i]);
}
console.log(map1);