这几篇笔记是经过大前端学习所做的一些总结,针对自己的理解,将基础知识做一个简要的概括总结,以及自己所碰到的一些误区做的一些理解加深记忆
1 关于let const var的理解
1.1 const声明的变量是只读的,不可更改,用const声明的对象是可以修改内部属性的
const age = 11
age = 12
// Assignment to constant variable
1.2 let声明的变量有块级作用域,不会发生变量提升,变量只有在声明前才能使用
console.log(age)
let age = 10
//age is not defined
1.3 var声明的变量会发生变量提升
console.log(name) //undefined
var name = 'peculiar'
2 解构
2.1 array的解构
conat arr = [1,2,3]
const [id1,id2,id3] = arr //id1,id2,id3用于接收数组相应的元素
const [, , x] = arr //用x接收指定位置的参数
const [a,...rest] = arr //用rest接收剩余参数只能放在最后,返回的类型是一个数组
const [b] = arr //默认从数组的起始位置提取数组元素(解构元素小于数组元素)
const [c1,c2,c3,c4] = arr //返回undefined(解构元素大于数组元素)
const [c1,c2,c3,c4 = 'default'] = arr //c4返回default(默认元素添加)
2 .2 object解构
const obj = { name:'peculiar'}
const name = 'odd'
const { name:other } = obj //解构的变量别名other接收obj中name的值
const { name:other = 'init' } = obj //解构的变量别名other默认值添加
3 函数参数默认值
function fullName(first,last='buy'){
return first + last
}
const name = fullName('book')
console.log(name) //bookbuy
//关于默认参数的length
function test(a, b, c) { console.log(test.length) //默认参数前面的参数个数 console.log(arguments.length) //实际传入的参数个数}test('a', 'b')// 3 2
4 关于. . .操作符
//剩余参数的使用,args返回数组类型,es5用argument来获取传入的参数
function foo(...args){
console.log(args)
}
//展开运算符
let arr = [1,2,3]
console.log(...arr) => console.log.apply(console,arr) //1,2,3
//数组去重
const arr = [1, 3, 5, 5]
const clear = Array.from(new Set(arr)) => [...new Set(arr)]
//数组的拷贝
const copy = [...arr]
5 this
关于this几点总结
- 沿着作用域链查找最近一个function(不是箭头函数),看最终这个函数怎样执行
- this的指向取决于function调用而不是定义的时候
调用方式
-
函数调用foo()指向全局对象(不考虑严格模式)在浏览器指向window
-
作为方法调用foo.bar(),foo.bar.baz(),指向最终调用这个方法的对象
-
作为构造函数调用new Foo()
-
显式的返回以下值:undefined,null, boolean, number等基础类型,并不会代替 new 式调用的默认行为
-
但显式返回以下值:{},[],RegExp, Date, Function,均会代替 new 调用的默认返回值 this
function Foo() { return function () { console.log(this) } } let res = new Foo() res() //window -
特殊调用 call,apply,bind
-
找不到所属function就是全局对象window
var length = 10function fn() { console.log(this.length)}const obj = { length: 5, method(fn) { fn() arguments0 }}obj.method(fn, 1, 2) //输出结果10 3 //obj.method传入形参fn,1,2,执行fn()相当于函数调用this指向window,打印出10 //argements[0]表示传入的参数第一个值这里是fn,这里的this指向arguments,打印3
6 创建对象属性
如果对象的key是一个表达式可以利用[ ]来表示key值,这里的[]叫做计算属性值
const foo = 'foo'
const obj = {
[1+1]:value,
foo
}
//如果对象的key和value相等则只写一个
7 Obeject.assign(target,source)
利用这个方法实现的是对象的浅拷贝,如何封装一个函数实现对象深拷贝
const obj = {
age: 10,
family: {
mom:'jasia'
}
}
const obj1 = Object.assign({}, obj)
obj1.family.mom = 'linda'
console.log(obj.family.mom) //linda 深浅拷贝与对象是否相等没有必然联系
//深拷贝函数封装,不考虑循环嵌套
function deepClone(obj) {
if (typeof obj !== 'object' || obj == null){
return obj
}else{
//初始化返回结果
const result
if(obj instanceof Array){
result = []
} else {
result = {}
}
for (let key in obj) {
if (obj.hasOwnProperty(key)){
result[key] = deepClone(obj[key])
}
}
return result
}
}
8 作用域
一般情况分为函数作用域和全局作用域
变量的查找一般在当前作用域查找,如果当前作用域没有会沿着作用域链查找,如果都没查找到会报错
function foo() {
console.log(a) // 2
}
function bar() {
var a = 3
foo()
}
var a = 2
bar()
//函数预解析直接解析函数本体,var申明的变量会变成undefined,然后按照js执行顺序依次执行,此时a变成2
//执行foo()结果为2