一、新增类型定义let、const、与var的区别
let特性:
1.不存在变量提升
2.同一个作用域内,不能重复定义变量
3.有着严格的作用域
var特性:
1.变量提升
2.同一作用域也可以重复定义变量,只是后定义的会覆盖前定义的
3.没有严格的作用域,在全局范围内,会添加全局window,在全局都可以使用,在函数内,则会形成函数作用域,在函数内都可以使用
const:用于定义常量,定义时必须赋值,赋值后不能再改变
<script>
function fun() {
var n = 10;
if (true) {
var n = 100;
}
console.log(n);
}
fun(); //输出100
</script>
<script>
//实例1
var a=1;
function f(){ /* 对于使用var定义的全局变量,会导致变量提升,形参定义提升到顶层,赋值在后 */
console.log(a); //undefined
var a=2;
}
f();
let b=2;
function fn(){
let b=4;
console.log(b);
// let b=4; //let 定义会避免出现var定义出现的变量提升,因此定义必须在输出前
}
fn();
var arr=[];
for(var i=0;i<10;i++){
arr[i]=function(){
console.log(i); //每次执行i都+1,执行后i为10,与我索取的数组输出值无关
}
}
arr[1]();
for(let i=0;i<4;i++){
let i='bbb';
console.log(i); //let定义的i每个都是相对独立的 ,执行后输出4次bbb
}
</script>
二、数据类型的判断
基本数据类型:string、number、boolean、null、undefined、symbol(ES6新增)
引用数据类型:array、function、object、set(ES6新增)、map(ES6新增)
数据类型判断的方法:typeof、instanceof、constructor、Object.prototype.toString.call()
typeof:无法判断null、array、object、set、map
instanceof:使用者自行判断,并通过输出boolean值确定判断的正确性
constructor:无法判断null和undefined,其余可通过(需要判断的类型.constructor.name)的方式判断
Object.prototype.toString.call():可以判断所有类型
/*
* 方法1:使用instanceof判断,
* 需要自行判断类型,输出的值只能是boolean类型
*/
function fn(){
}
var b=null;
console.log(b instanceof Object);
console.log(typeof fn); //typeof无法判断null、array、object,null、array实际上是特殊的对象,typeof无法区分,输出都为object
/*
方法二:使用constructor
无法判断null和undefined,
* */
var arr=[];
var fc={};
var c=null;
var a=false;
var g;
var sy=Symbol();
var res=new Set();
var rt=new Map();
console.log(sy.constructor.name);
console.log(res instanceof Set);
console.log(typeof fc);
/*
* 方法三:Object.prototype.toString.call
* 可以判断所以类型
*/
console.log(Object.prototype.toString.call(rt));
三、数组对象的解构赋值
<script>
var [a,b]=[1,2];
console.log(a); //1
console.log(b); //2
var [c,d]=[1];
console.log(c); //1
console.log(d); //undefined
var [e]=[44,6];
console.log(e); //44
/*
对于数组的解构赋值,遵从左右两边类似原则,
左边定义的形参和右边的实参在位置上相对应,
实参位置的改变会为形参赋予不同的值
* */
var {x,y}={y:100,x:'123'};
console.log(x); //123
console.log(y); //100
var {log}=console; //简化写法,var console={log:console.log};
log(x);
/*
对象的解构赋值与顺序无关,遵循同名原则,
对于左边定义的形参,右边会寻找与左边定义形参的值
* */
</script>
四、字符串扩展语法(…)
<script>
var arr=[1,2,13];
var arr1=[2,6,77,61];
// Array.prototype.push.apply(arr,arr1);
// console.log(arr);
// console.log(arr.concat(arr1));
arr.push(...arr1);
console.log(arr);
</script>
五、Set和Map数据结构
1、Set
ES6新增引用类型,是一种类数组对象,传入的值具有唯一性,相同的值只会显示一个,可以使用Array.from()方法将其转化为数组。常用来使数组去重。
var se=new Set([1,2,3,2]);
var se1=new Set([2,3,5,8,5,8]);
console.log(se); //Set(3){1,2,3}值唯一
console.log(se1); //Set(4){2,3,5,8}
var set=Array.from(se); //使用Array.from可以将Set转换为Array
console.log(se.constructor.name); //Set
console.log(set.constructor.name); //Array
console.log([...se1]); //也可以通过...扩展运算符转换为数组
2、Set的方法
add()、delete()、has()、clear(),用于添加,删除,判断Set对象是否具有指定元素(true或false)、清除。
let sb1=new Set([2]);
sb1.add(3); //添加
console.log(sb1);
sb1.delete(2); //删除指定项
console.log(sb1);
console.log(sb1.has(4)); //判断Set对象是否具有指定元素(true或false)
console.log(sb1.clear()); //清除全部
此外,还可以使用for…of循环遍历Set数组。
let cbd=new Set(['red','green','blue']);
console.log(cbd);
for(let i of cbd){ //使用for...of循环遍历数组
console.log(i);
} //输出 red green blue
keys()、values()、entries()方法
keys():获取键名
values():获取值
entries():获取键值对
在省略下,key和value其实是相同的,因此,再这种情况下,
keys()与values()的输出是相同的。
let cbd=new Set(['red','green','blue']);
//keys()、values()、entries()
/*
keys():获取键名
values():获取值
entries():获取键值对
在省略下,key和value其实是相同的,因此,再这种情况下,
keys()与values()的输出是相同的。
* */
console.log(cbd.keys()); //输出 SetIterator {"red", "green", "blue"}
console.log(cbd.values()); //输出 SetIterator {"red", "green", "blue"}
console.log(cbd.entries()); //输出 SetIterator {"red" => "red", "green" => "green", "blue" => "blue"}
3、Set的数学应用
let a=new Set([1,2,3]);
let b=new Set([4,3,2]);
let unique=new Set([...a,...b]); //并集
console.log(unique);
let reter=new Set([...a].filter(x=>b.has(x))); //交集
console.log(reter);
let din=new Set([...a].filter(x=>!b.has(x))); //差集
console.log(din);
4、Map
Javascript的Object本身就是键值对的数据结构,但实际上属性和值构成的是”字符串-值“对,属性只能是字符串,如果传个对象字面量作为属性名,那么会默认把对象转换成字符串,结果这个属性名就变成”[object Object]“。
ES6提供了”值-值“对的数据结构,键名不仅可以是字符串,也可以是各种类型的(包括对象)。它是一个更完善的Hash结构。
此外,Map也拥有delete()、has()、clear()、keys()、values()、entries()方法。
let obj={
a:1,
123:'abc'
}
console.log(obj.a); //输出1
// console.log(obj.123); //报错,只接受字符串作为键
let obj1={a:1}
let obj2={b:2}
let obj3={}
obj3[obj1]=4;
obj3[obj2]=5;
console.log(obj3); //输出{[object Object]: 5},无法使用对象作为键,此外键值会覆 盖
let a=new Map();
a.set(123,'aaa');
a.set(obj,234);
console.log(a.get(123)); //输出aaa,允许所有类型作为键,此时123为键,aaa为值
console.log(a.get(obj));
console.log(a); //允许对象作为键值,并且不会覆盖
/*输出Map(2) {123 => "aaa", {…} => 234}
[[Entries]]
0: {123 => "aaa"}
1: {Object => 234}
key: {123: "abc", a: 1}
value: 234
*/
六、Symbol
Symbol特点:
1.ES6新引入基本数据类型
2.表示独一无二的值,相同参数的值也不一样
3.最大的用法是用来定义对象的唯一属性名
4.不能使用new创建,可以接受字符串作为参数
注意点:
Symbol 值作为属性名时,该属性是公有属性不是私有属性,
可以在类的外部访问。但是不会出现在 for…in 、 for…of
的循环中,也不会被 Object.keys() 、 Object.getOwnPropertyNames() 返回。
如果要读取到一个对象的 Symbol 属性,可以通过 Object.getOwnPropertySymbols()
和 Reflect.ownKeys() 取到。
<script>
let sym = Symbol('在这里');
console.log(sym);
let sym1 = Symbol('在这里');
console.log(sym === sym1);
// 作为对象属性名使用:
let sy = Symbol('key');
let obj = {};
obj[sy] = 'objkey1';
console.log(obj);
let object = Object.getOwnPropertySymbols(obj);
console.log(object);
</script>