值类型key与value存储在栈中(量小)
引用类型在栈存储的引用地址,在堆中存储是数据(量大)
把引用类型赋值给一个变量,是吧变量的引用地址指向引用类型堆中地址
typeof “abc” string
typeof 123 number
typeof true boolean
typeof undefined undefined
typeof null object
typeof Symbol() symbol
typeof {} object
typeof [] object
typeof function(){} function
typeof new Map() object
typeof new Set() object
适合判断 值了与引用类型 不能判断具体引用类型
[] instanceof Array true
[] instanceof Object true
{} instanceof Array false
{} instanceof Object true
判断实例对象构造函数
[].constructor === Array true 最精确
最精确
Object.prototype.toString.call(obj).slice(8,-1)
返回数据的精确类型
扩展{...obj}
for遍历
Object.assgin()
2.1,JSON.parse(JSON.stringify(数据))
json数据类只支持 布尔,字符串,数字 null,undefined array object 会忽略函数 等其他类型数据
2.2, 通过判断类型 递归深拷贝
递归就是函数调用自己
一定要有结束条件
看符号
+
±*/ == 会尝试把其他类型转换为数字
转换失败 NaN
false 转换为 0
true 转换 1
3.<>= <= ! != == 判断与逻辑返回会尝试把其他类型转换布尔值
falsely变量转换为false “” null NaN undefined 0 转换为false
=== 判断类型和值是否都相对
应该在任何时候都使用=== (当判断是否为null或者为undefined可以为特例)
null === null true
== 判断隐式转换后的值 “100” == 100 // true null == undefined //true 0 == false //true 特例:NaN === null // false
{} == {} // false [] == {} //false 指向不同的内存地址
A||B
A为真(truely) 结果为A ,否则结果为B
A&&B
A为假(falsely) 结果为A,否则结果为B
判断对象
if(a&&a.b&&a.b.c){}
if(a?.b?.c){}
如果有a并且有a.b并且有a.b.c
if(a.b.c){}
类:(创建对象实例的模板) 本质上都是函数
构造函数 用new来执行的函数
class xxx { }
实例:由类创建的对象(本质上讲就是对象)
显示原型
类/构造函数都一个显示显示原型protype (本质是就是个对象)
每个实例都有一个隐私原型__proto__
类显示原型protype等于其创建的实例的隐式原型__proto__
查找对象实例的方法和属性时,先在自身找,找不到则沿着__proto__向上查找,__proto__形成的链条关系我们称为原型链(实现了js继承)
实现了js的继承
实现了实例的公用属性和方法
var arr = [];
arr.proto === Array.prototype
类显示原型protype等于其创建的实例的隐式原型__proto__
class Student extends People{
constructor(name,age,no){
//类中继承构造函数
super(name,age)
....
}
}
function Student(name,age,no){
People.call(this,name,age)
....
}
2.继承原型链
Student.prototype = Object.create(People.prototype)
Stuent.prototype.constructor = Student
所有数组将拥有max方法
Array.prototype.max = function(){
return Math.max(...this))
}
所有字符串将拥有 reverse 方法
String.prototype.reverse = function(){
return this.split("").reverse().join("")
}
注意:一般不要修改默认对象上的方法,扩展也谨慎
闭包就是能够读取其他函数内部变量的函数
闭包基本上就是一个函数内部返回一个函数
好处
可以读取函数内部的变量
将变量始终保持在内存中
可以封装对象的私有属性和私有方法
坏处
比较耗费内存、使用不当会造成内存溢出的问题
在js中变量和函数的声明会提升到最顶部执行
函数的提升高于变量的提升
函数内部如果用 var 声明了相同名称的外部变量,函数将不再向上寻找
匿名函数不会提升。
箭头函数this指向函数的上一层作用域的this
箭头函数不能作为构造函数,没有constructor
冒泡流
:事件由最具体的元素响应然后组件冒泡到最不具体的元素(html)
捕获流
:从最不具体的元素捕获事件
开启捕获 addEventListenter第三个参数 true
阻止事件冒泡:e.stopPropagation()
let 不会变量提升,var声明的变量会变量提升
let 不能重复声明 var可重复声明
const 声明必须赋值,值类型的值不能修改
1,重绘
简单来说就是重新绘画,当给一个元素更换颜色、更换背景,虽然不会影响页面布局,但是颜色或背景变了,就会重新渲染页面,这就是重绘
2,回流
当增加或删除dom节点,或者给元素修改宽高时,会改变页面布局,那么就会重新构造dom树然后再次进行渲染,这就是回流。
总结
重绘不会引起dom结构和页面布局的变化,只是样式的变化,有重绘不一定有回流。
回流则是会引起dom结构和页面布局的变化,有回流就一定有重绘。
不管怎么说都是会影响性能。
防抖
防抖就是指触发事件后在 n 秒内函数只能执行一次,如果在 n 秒内又触发了事件,则会重新计算函数执行时间
节流
节流就是指连续触发事件但是在 n 秒中只执行一次函数。节流会稀释函数的执行频率
构造函数 new 函数名() this执行的 new出来对象的实例
箭头函数的this上一层作用域的this
对象中的this指向对象
事件响应函数的this指向 调用者
setTimout setInterval 里面this指向window
call,apply,bind 响应的函数this指向第一个参数