let 和 const 声明 变量和常量 var
0 - 作用声明变量
1 - let 使用注意
01 - 作用域只局限于当前代码块
js:{
//es6
if(true){
var a = 1;
let b = 2;
}
console.log(a,b)//b is not defined
if(1){
let b = 2;
console.log(b)//2
}
console.log(b)//b is not defined
//es5
var a = 1;
function(){
console.log(a)//此时 a是全局变量
}
//es5
var a = 1;//全局变量
function(){
var b = 2;
console.log(b)局部变量
}
}
02 - 使用let申明的变量作用域不会被提升
{
console.log(str)
var str = '张三'
// 原理解析
var str;
console.log(str)
str = '张三'
}
03 - 在相同的作用域下不能申明相同的变量
04 - for循环体现let的父子作用域 (互不影响)
经典案例 5个btn点击分别对应btn的index
js:{
var btns = document.querySelectorAll('button')
for(var i = 0; i < btns.length; i++){
btns[i].onclick = function(){
alert('点击了第' + i + '个按钮')
}
}
//结果都是5; 原因: for是同步的, 事件触发是异步事件
//以前是用的闭包的方式进行解决的。
var btns = document.querySelectorAll('button')
for(var i = 0; i < btns.length; i++){
//得到一个封闭的作用域 里面的得到i 与外面没有关系了。
(function(i){
btns[i].onclick = function(){
alert('点击了第' + i + '个按钮')
}
})(i)
}
//es6
let btns = document.querySelectorAll('button')
for(let i = 0; i < btns.length; i++){
btns[i].onclick = function(){
alert('点击了第' + i + '个按钮')
}
}
for(let i = 0;i < 5;i++){
let i = 20 // if(注释){该作用域会找父作用域,1,2,3,4,5,}else{该作用域有了i,所以 20,20,20,20,20}
console.log(i)
}
}
2 - const 使用注意
01 - 只在当前的代码块中有效
02 - 使用const申明的变量作用域不会被提升
03 - 不能被重复申明
04 - 申明的常量必须赋值
js:{
//单纯的赋值是不行的
const name = 'lisi'
name = 'zhangsan'
//对象另说, 对象在堆中,修改了堆中对象。这是OK的
const obj = {name:'lisi'}
obj.name = 'zhangsan'
}
解构赋值
0 - Es6允许按照一定模式从数组和对象中提取值对变量进行赋值,这被称为解构(Destructuring)
1 - 基本用法
js:{
let name = '张三', age = 18, sex = '男';
let [name,age,sex] = ['李四', 18, '男'];//基本用法
name = 'hhh'
console.log(name)
console.log(age)
console.log(sex)
}
2 - 对象的解构赋值
js:{
//解构赋值 key要一一对应
let {name,age,sex,friends,pet} = {name:'张三', age:18, sex:'男', friends:['王五','赵四'], pet:{style:'pig', weight: 180}}
console.log(name)
console.log(age)
console.log(sex)
console.log(friends)
console.log(pet)
}
3 - 数组的解构赋值
js:{
let [arr,[arr2,arr3,[arr4,arr5]]] = [1,[2,3,[4,5]]]
//不能取到,就返回undefined
}
4 - 基本类型的解构赋值
js:{
let [a,b,c,d] = '清风明月'
console.log(a,b,c,d) // 若赋值为字符串OK, 若1234 就会提示没有构造器
}
数据集合 - set
0 - 特点
01 - 类似于数组 没有重复的元素(唯一的)
02 - 开发中用于去除重复数据
03 - key 和 value 是相等的
js:{
//1.创建一个集合
let set = new Set() //创建一个空的set
let set1 = new Set(['张三', '李四', '王五'])//创建一个有值的set
}
1 - 一个属性
js:{
console.log(set1.size)
}
2 - 四个方法
01 - add
set.add('刘德华').add('流星')//添加内容 支持链式调用(调用方法返回一个对象)
02 - delete
console.log(set.delete('张三'))// 返回true
console.log(set)//删除了一个项
03 - has
set.has('张三') //集合中是否有 返回true/false
04 - clear
set.clear() //清除所有。 无返回值 undifend
补 - keys values //输出两个构造器SetIterator
console.log(set.keys())
console.log(set.values())
3 - 实例:
let a = new Set([1, 2, 3]);
let b = new Set([4, 3, 2]);
//并集
let union= new Set([...a,...b])
console.log(bing)
//交集
let intersect = new Set([...a].filter(x => b.has(x)))
console.log(jiao)
//差集
let difference = new Set([...a].filter(x => !b.has(x)))
console.log(cha)
//遍历
let set = new Set(['red', 'green', 'blue']);
for (let x of set) {
console.log(x);
}
数据集合 - map
0 - 特点 (自带去重)
01 - 类似于对象本质上是键值对的集合
js:{
let obj1 = {a:1}, obj2 = {b:2}, obj = {}
obj.name = '张三'
obj[obj1] = 'sky'
obj[obj2] = 'sea'
console.log(obj) // 发现obj {name:'张三',[object,object]:sea}
//以上的原因是 对象当作键时候 做个事儿 obj1.toString()
console.log(obj1.toString() == obj2.toString())
}
02 - '键'不局限于字符串,各种类型的值(包括对象)都可以当作键
js:{
//1.创建一个Map
let obj1 = {a:1}, obj2 = {b:2}
//个人感觉有点儿类似于二位数组 arr[0][0] => key, arr[0][1] => values
const map = new Map([
['name','张三'],//arr[0][0] => key, arr[0][1] => values
[obj1,'sky'],//arr[1][0] => key, arr[1][1] => values
[obj2,'sea'],//arr[2][0] => key, arr[2][1] => values
[[1,2],'happe']
])
}
03 - 对象"字符串-值",Map"值-值",是一种更加完善的Hash结构实现
1 - 常用属性
01 - size 长度
console.log(map.size)
2 - 常用方法
01 - set和get
js:{
//set 参数1 是key ,参数二 是 value
map.set('friends',['peter','jion']).set(['dog'],'flower')
//get 得到key的对应值
map.get('friends')
}
02 - delete
js:{
//delete 参数key 返回Boole
map.delete('frends')
}
03 - has
js:{
console.log(map.has('friends')
}
04 - clear
js:{
map.clear()
console.log(map)
}
05 - keys(),values(),entries()
js:{
//keys()键值 values()值 entries()
//entries() 键值 值
console.log(map.keys(),map.values(),map.entries(),map)
}
7 - 遍历
js:{
map.forEach((value,index)=>{
console.log(index + ' ' + value)
})
//注意事项
map.set({},'哈哈哈哈')
map.set({},'呵呵呵呵')
console.log(map) // 两个都有没有去重,这是对的虽然都是空对象,但是对象是存在堆中不同的地址
//验证 {} !== {}
console.log({} !== {})
}
Symbol
0 - 场景
01 - ES5的对象属性名都是字符串,容易造成属性名冲突
02 - ES6引入新的原始数据类型Symbol,表示独一无二的值
1 - 对象的属性名可以有两种类型
01 - 字符串
02 - Symbol类型 独一无二不会与其他属性名冲突
js:{
//1.定义
let str1 = Symbol()
let str2 = Symbol()
console.log(str1 == str2) //false 证明确实独一无二
conosle.log(typeof str1) // 类型 Symbol
//2.描述
let str3 = Symbol('name')
//3.常用在对象的属性名
const obj = {}
obj[Symbol('name')] = '张三'
obj[Symbol('name')] = '李四'
}
Class的基本运用
0 - 新增加的一个语法糖作用在于让对象原型的写法更加清晰/更像面向对象的编程方式
js:{
//es5构造函数
function Person(name,age){
this.name = name
this.age = age
}
//方法放在原型中
Person.prototype = {
constructor:Person,//指向钩子函数
print(){
console.log(`我叫${this.name},今年${this.age}岁`)
}
}
let person = new Person('张三',19)
console.log(person)
person.print()
}
1 - 构造函数的另一种写法
js:{
class Person{
//属性放在构造器中
constructor(name, age){
this.name = name,
this.age = age
}
//方法
print(){
console.log(`我叫${this.name},今年${this.age}岁`)
}
}
//创建对象
let person = new Person('张三', 19)
console.log(person)
person.print()
}
2 - 类的继承demo
窗口中,鼠标进入不断产出新的小球。 //todo:: 自我补充 random,以及canvas,addEventListener
html:{
}
内置对象扩展
0 - 模板字符串 ``
js:{
let name = "DosLT"
let html_str = `
您好,我叫什么${name}
`
}
1 - 数组的扩展
01 - Array.from 将伪数组或者集合其他非正式数组,转成正式数组
js:{
let allLis = document.querySelecotorAll('li');
console.log(allLis)//打印看到 伪数组
console.log(Array.isArray(allLis)) // 辨别是不是真的数组 返回false
console.log(Array.from(allLis))
console.log(Array.isArray(Array.from(allLis)))
}
02 - Array.of 将零零散散的 统一转成数组
js:{
console.log(Array.of(1,2,3,4))
console.log(Array.of('张三','李四','王五'))
}
2 - 对象的扩展
01 - key 和 value 是一样的,写一个就够了
js:{
let name = 'DosLT', sex:'男';
let abj = { name:name,sex:sex } === let obj = { name, sex }
}
02 - Object.assign() 多对象合并为一个整合对象
js:{
let obj1 = { name:'张三' }
let obj2 = { age:18 }
let obj3 = { sex:'男' }
let obj4 = { firends:'李四' }
let person = {}
Object.assign(person,obj1,obj2,obj3,obj4) // 这样person 就有了其他所有的属性
}
03 - 延展操作符 ...
js:{
//可以直接将字符 弄成 数组
let str = '今天天气很好'
let strArr = [...str]
//模板中
let student = {
name : '张三',
age : 18,
sex : '男'
}
//去重数组
let myArr = [1,2,10,'张三',20,2,1]
console.log(new Set(myArr));
[...new Set(myArr)]
}
函数扩展
0 - 形参设置默认值
js:{
//函数若不传参设置默认
function sum(num=0,num1=0){
console.log(num+num1)
}
sum()
}
1 - 参数形式 延展操作符
js:{
//es5
function sum(){
let result = 0
for(let value of arguments){
result += value
}
return result
}
console.log(sum(10,20,30)
//es6
function sum(name,...nums){
let result = 0
console.log(name)
for(let value of nums){
result += value
}
return result
}
console.log(sum('张三',10,20,30)
}
箭头函数 ()=>{}
js:{
let nameArr = [1,2,3,4]
nameArr.forEach((value,index)=>{
console.log(index + ' ' + value)
})
//还有个好处就是处理this
function demo(){
setTimeout(function(){
console.log(this)
},1000)
setTimeout(()=>{
console.log(this)
},1000)
}
let obj = {}
demo.call(obj)
//我们知道,call 方法的第一个参数是作为函数上下文的对象,这里把 obj 作为参数传给了 func,此时函数里的 this 便指向了 obj 对象。此处 func 函数里其实相当于
demo.call(obj) === function func() {
console.log(obj.name);
}
[link](https://github.com/lin-xin/blog/issues/7)
}