1. var和let/const的区别
-
var 、 let 用以声明变量,const 用于声明只读的常量;
-
var 声明的变量,不存在块级作用域,在全局范围内都有效,let 和 const 声明的,只在它所在的块级作用域内有效;
-
let 和 const 不存在像 var 那样的 “变量提升” 现象,所以 var 定义变量可以先使用,后声明,而 let 和 const 只可先声明,后使用;
-
let 声明的变量存在暂时性死区,即只要块级作用域中存在 let,那么它所声明的变量就绑定了这个区域,不再受外部的影响。
-
let 不允许在相同作用域内,重复声明同一个变量;
-
const命令两个注意点: const 声明之后必须马上赋值,否则会报错
const 简单类型一旦声明就不能再更改,
复杂类型(数组、对象等)指针指向的地址不能更改,内部数据可以更改。。
2. 块级作用域
为什么需要块级作用域?
ES5只有全局作用域和函数作用域,没有块级作用域。 这带来很多不合理的场景:
(1)内层变量可能覆盖外层变量
(2)用来计数的循环变量泄露为全局变量
let
//ES6
var me = 'l';
(function (me) {
var hello = function () {
return '你好'
}
console.log(`${hello()}!${me}`)//你好!l
var me = 'f'
console.log(`${hello()}!${me}`)//你好!f
function hello() {
return 'hello'
}
})(me);
const
const A = {a:1,b:4}
const B ={b:2}
const C = {c:3}
const D = Object.assign(A,B,C)
//合并三个对象的值,后面重复属性覆盖前面的,把合并结果返回A,A被修改。
console.log(D)//{ a: 1, b: 2, c: 3 }
D.d = 4
console.log(D)//{ a: 1, b: 2, c: 3, d: 4 }
console.log(A)//{ a: 1, b: 2, c: 3, d: 4 }
2 箭头函数和普通函数的区别?
箭头函数的this指向规则:
- 箭头函数没有prototype(原型),所以箭头函数本身没有this
- 箭头函数的this指向在定义的时候继承自外层第一个普通函数的this。
- 如果箭头函数外层没有普通函数,严格模式和非严格模式下它的this都会指向window(全局对象).
- 箭头函数本身的this指向不能改变,但可以修改它要继承的对象的this。
箭头函数的arguments:
1 箭头函数的this指向全局,使用arguments会报未声明的错误。
2 箭头函数的this指向普通函数时,它的argumens继承于该普通函数
箭头函数没有constructor:
使用new调用箭头函数会报错,因为箭头函数没有constructor
箭头函数不支持new.target
箭头函数不支持重命名函数参数,普通函数的函数参数支持重命名
箭头函数相对于普通函数语法更简洁优雅
箭头函数的注意事项及不适用场景
箭头函数的注意事项:
箭头函数一条语句返回对象字面量,需要加括号
箭头函数在参数和箭头之间不能换行
箭头函数的解析顺序相对||靠前
不适用场景:箭头函数的this意外指向和代码的可读性。
var myObject = {
myName : 'JULY',
func:function () {
var self = this
console.log(this.myName)//JULY
console.log(self.myName);//JULY
(function () {
console.log(this.myName)//undefined
console.log(self.myName)//JULY
}());
(()=>{
console.log(this.myName
)//JULY
console.log(self.myName)//JULY
})();
}
}
myObject.func()
3 模板字符串
//模板字符串
let name = 'july'
let str1 = '这是一个字符串'
let str3 = `这是一个${name}字符串`
console.log(str3)//这是一个july字符串
4 结构赋值和扩展运算符
结构赋值
import {add,sum} from 'common.js'//相对于将common.js中两个方法,总结为两个变量add,sum,供我使用。
let arr = [1,2,3]
/*let a = arr[0]
let b = arr[1]
let c = arr[2]*/
//结构赋值
let [a,b,c] = [1,2,3]
const obj = {
name:'july',
age:14
}
/*
let name = obj.name
let age = obj.age
*/
//结构赋值
let {name,age} = obj
扩展运算符
let arr1 = [1,2,45,6,7]
let arr2 = [...arr1,7,8,9]
console.log(arr2)//[1, 2, 45, 6,7, 7, 8, 9]
function demo(...args) {
console.log(args)//[ 1, 24, 6, 8 ]
}
demo(1,24,6,8)
5 Class: 类 和 类的继承
//声明类
class Person1 {
constructor(name,age,gender) {
this.name = name
this.age = age
this.gender = gender
}
say(){
console.log(this.name)
console.log(this.age)
console.log(this.gender)
}
}
class Student extends Person1{
constructor(name,age,gender,school) {
super(name,age,gender);
this.school = school
}
study(){
console.log(this.school)
}
}
const s = new Student('tom',23,'male','清华大学')
console.log(s)//Student { name: 'tom', age: 23, gender: 'male', school: '清华大学' }
s.say()
s.study()//清华大学
6 JSON序列化和反序列化
let pp = JSON.stringify(p)
console.log(pp)//{"name":"sam","age":10,"gender":"male"}
let o = JSON.parse(pp)
console.log(o.name)//sam
7 模块化编程
//one.js
let name = 'sam'
let age = 20
function add(x,y) {
return x+y
}
export {name,age,add}//部分导出
export class Person {//一个导出
constructor() {
}
say(){
console.log('test')
}
}
//index.js
import {add} from "./one"
import {add as mul} from "./two"
console.log(add(10,30))
console.log(mul(2,4))
import {Person} from "./one";//一个导入
const p = new Person()
p.say()
import * as one from "./one"//一起导入
console.log(one.add(2,5))