2020/3/8
ES6部分(其一)
var let const
- var声明可以重复声明 重新定义 属于当前的函数
if(true){
var a=1;
}
console.log(a);//编译通过
- let&conset仅在其所在代码块有效
let a=1 ;//全局
if(true){
let a=2; //局部
console.log(a);
}
console.log(a);
输出结果:2 1
for (var a = 0; a <= 2; a++) {
console.log(a)
setTimeout(function() {
console.log(a)
}, 1000)
}
输出:1 2 2 2
for (let a = 0; a <= 2; a++) {
console.log(a)
setTimeout(function() {
console.log(a)
}, 1000)
}
输出:1 2 1 2
let可以重复赋值,const不能重新复制但能改变其属性(类似Kt中的val)
Temporal Dead Zone (TDZ) 暂时性死区
不要在变量未声明前使用变量
使用规则:
- 默认使用conset
- 需要重新绑定或者更新使用let
- 尽量不适用var
箭头函数
const nums=[1,2,3,4,5,6,7]
const nums2=nums.map((number,i)=>{
console.log(`${i}:${number*2}`)
})
输出:
0:2
1:4
2:6
3:12
···
规则:去掉function,加=>
const chengkeyu = {
name: "chengkeyu",
hobbies: ['Eating', 'Sleeping'],
printHobbies: function() {
this.hobbies.map(function(hobby){
console.log(`${this.name} like ${hobby}`)
})
}
}
chengkeyu.printHobbies()
输出:like Eating
like Sleeping
name没有,因为js中,this实在运行时才绑定的此时的this.name所在的函数是一个独立函数,所以指向的是window
const chengkeyu = {
name: "chengkeyu",
hobbies: ['Eating', 'Sleeping'],
printHobbies: function() {
this.hobbies.map((hobby)=>{
console.log(`${this.name} like ${hobby}`)
})
}
}
chengkeyu.printHobbies()
输出:chengkeyu like Eating
chengkeyu like Sleeping
原因:箭头函数是词法作用域,没有自己的this,继承于父级函数
字符串模板
格式:
`文本${变量或者代码块}文本`
字符串模板允许嵌套
示例:
const objs = [{
firstName: "yang",
lastName: "weizhi"
},
{
firstName: "cheng",
lastName: "keyu"
},
{
firstName: "zhao",
lastName: "qian"
},
]
const temp=`
${objs.map(name=>`- ${name.firstName}性男子
`)}
`
document.body.innerHTML=temp
数组解构
数组对数组
const nums=[1,2,3,4]
const [one,two]=nums
console.log(one,two)
打印: 1 2
Restful的写法
const nums=[1,2,3,4]
const [one,...others]=nums
console.log(one,others)
打印:1234
注意:...仅能声明在最后,不然会报错
数组解构实现变量交换
const a=1
const b=2
[a,b]=[b,a]
默认值
const [a = 1, b] = [undefined, 2]
console.log(a, b)
const [c = 1, d] = [null, 2]
console.log(c, d)
打印:1 2
null 2
undefined表示不给值,null表示给个null值
对象解构
原则:key值对应
const Chengkeyu={
name:"陈科宇",
sex:"男",
hobbies:["羽毛球","睡觉"],
}
const {name,hobbies}=Chengkeyu
console.log(`${name}喜欢${hobbies}`)
打印:陈科宇喜欢羽毛球,睡觉
重命名
const Chengkeyu={
name:"陈科宇",
sex:"男",
hobbies:["羽毛球","睡觉"],
}
const {name:a,hobbies:b}=Chengkeyu
console.log(`${a}喜欢${b}`)
注意点:
错误写法
const Chengkeyu={
name:"陈科宇",
sex:"男",
hobbies:["羽毛球","睡觉"],
}
{name:a,hobbies:b}=Chengkeyu
console.log(`${a}喜欢${b}`)
此时会报错
报错原因:大括号内的内容{name:a,hobbies:b}
会被编译器当作代码块而非变量
所以需要加外部加括号且提前声明
拓展运算符
const nums1=[1,2,3]
const nums2=[5,6,7]
const nums3=[...nums1,4,...nums2]
const nums4=nums3
console.log(nums4)
打印: 123456
Warning:此时nums4持有的是nums3的索引,所以对nums4进行修改会导致nums3同时变化
所以正确赋值姿势应该为const nums4=[].concat(nums3)
Rest运算符(剩余参数)
function a(...nums) {
console.log(nums)
}
a(1, 23, 4, 234)
打印:(4) [1, 23, 4, 234]
nums以array的形式保存了这些参数
2020/3/10
Js的基础复习
网页的生成流程
- HTML代码转换成DOM、
- CSS代码转换为CSSOM(CSS Object Model)
- 结合DOM和CSSOM,生成渲染树,Render tree,包含各个节点的视觉信息
- 耗时操作 生成布局Layout,j将所有的渲染树的所有节点进行平面整合
- 耗时操作 将布局绘制(paint)在屏幕上
- 生成的布局flow与绘制paint合称渲染
- 网页生成之时至少渲染一次,用户访问过程中不会中断渲染
- 重新渲染包含:重排和重绘,重绘不一定要重排,重排一定会重绘
JS的组成
- ECMAScript:定义语法规范
- DOM:文档对象模型
- BOM:浏览器对象模型
arguments:
function pringArgs(){
console.log(arguments)
}
pringArgs(10,11)
此处的arguments为10,11
函数的定义方式
- 函数声明方式:function 关键字 命名函数
- 函数表达式 匿名函数
- new Function() 执行效率低,较少使用
注意:所有函数都是Function对象
作用域
- 全局变量(尽可能不要使用)
- 局部变量
- 块级作用域
- 词法作用域
JS的预解析过程
- 变量声明提升至当前作用域的最前,仅会提升声明,而不会赋值
- 把函数的声明提升到最前,仅会提升声明,而不会调用
- 先var 再function
对象存储
简单类型的存储: 会独立的存于堆内存中
复杂对象的存储:栈仅存储指针,指向堆中的对象
2020/3/11
ES6部分(其二)
标签模板
再字符串模板中加入方法名标签,使之返回我们规定要求的字符
//标签模板字符串
function hightLight(string,...values) {
debugger;
return 'laravist'
}
const user="marry"
const topic="learn to use md"
const sentence=hightLight`${user} has commend on your topic ${topic}`
console.log(sentence)
运行结果:laravist
strings为自带字符串所组成集合
values为模板字符串所组成的集合(user,topic)
新增的字符串函数
- startWith
- endWith
- includies
- repeat
示例
const id="1234567890"
const fan="I Love Sleep"
console.log(id.startsWith(234,1))//true
console.log(id.endsWith(6789,9))//true
console.log(id.includes(12,7))//第七位后是否包含12
console.log(fan.repeat(2))//重复两次
//repeat实现右对齐
function padder(string,length=25) {
return `${' '.repeat(Math.max(length-string.length,0))}${string}`
}
for of
传统的循环的缺点
- for循环语法繁琐
- for in循环会打印所有的对象而非只有数组内的对象
- for each不能中断
for of 只会获取数组内的对象,不会引入其所有内容
const fruits=['香蕉','核桃','柠檬','火龙果']
//for in会打印所有 of只会打印数组内的
for (let fruit of fruits){
console.log(fruit)
}
/**
Map
与java中的map类似
具体看示例
const people = new Map();
//添加元素
people.set("cky", 18);
people.set("ywz", 20);
people.set("zq", 22);
console.log(people);
//获取大小
people.size;
//判断有无
people.has("zq");
//删除
people.delete("zq");
//全清
people.clear();
const nums=[1,2,3,4,5,5]
//直接赋值
const fruits = new Map([['apple', 12], ['banana', 23]]);
WeakMap
weakMap不能循环,没有size,没有clear,key必须是对象
但weakMap会自动回收,可用于内存优化
week map
const strong=new Map();
const weak=new WeakMap();
Class
传统的对象,如果声明方法需要使用prototype,而且存在变量提升
例:
function User(name, email) {
this.name = name;
this.email = email;
}
const yang = new User(123, 123)
User.prototype.speak = function () {
console.log(`Hi I am ${this.name}`)
}
但在Class中,使用构造方法和直接声明方法的方式替代了原先的姿势
例:
class Book {
constructor(name, email) {
//构造函数
this.name = name
this.email = email
}
info(){
console.log(`Hi I am ${this.name}`)
}
//直接BOOK调用,示例不可调用
static desc(){
console.log("hello world")
}
}
new Book(123,123).info()
Book.desc()
值得注意的是
- class不会存在变量提升,所有要先声明在使用
- class中的静态方法,只能自身调用,自身的示例无法调用
如上示例