面向对象
概念:更加注重参与事情的对象的一种高级编程思想。
如何定义对象、给对象添加属性、方法 是最棒的?
定义对象使用自定义构造函数:
function 构造函数名称(形参, ...) {
this.属性 = 形参
}
var 对象 = new 构造函数(实参, ...)
new的时候发生了什么?
- 创建一个空对象
- 将this指向他
- 执行函数中代码
- 返回这个对象
添加属性:利用构造函数调用的实参和形参的传递,构造函数中的this代表new出来的对象
添加方法:将方法添加在原型上 - 构造函数.prototype
原型:
任何对象天生自带属性
__proto__
对应的值是一个对象 - 原型任何函数天生自带属性prototype对应的值是一个对象 - 原型
原型的作用:原型上的属性和方法默认就能被对象使用
原型链:
对象一定会有原型,原型也是一个对象,所以原型也有原型,...,这样形成的一条链式结构 - 原型链
原型链的作用:当访问对象的属性和方法的时候,先在自己上找,自己没有就去原型上找,原型上没有,就去原型的原型上找。。。直到顶级原型(Object对应的原型),顶级原型也没有,就返回undefined
回流和重绘
浏览器的渲染过程:解析html结构形成DOM树,同时解析css形成CSS树,两棵树合并为渲染树,计算标签的大小和位置,涂颜色,显示在浏览器。
如果我们对标签进行了大小和位置的操作,就需要重新计算大小和位置,再涂颜色,然后显示 - 造成了回流/重排
如果我们对标签进行了颜色的改变,就需要重新涂颜色,显示 - 造成了重绘
回流和重绘都是浪费性能的。
提高性能:
合并样式修改
① 将
标签.style.css键 = 值
改成标签.style.cssText = 'css键:值;css键:值;'
② 样式通过操作标签的style属性完成
③ 将多个样式写在类名中,进行类名操作
节点操作
① 利用文档碎片
② 将标签隐藏 => 操作 => 显示
③ 将标签克隆 => 操作 => 替换原标签
尽量减少定时器中对节点的操作
动画时,将定时中获取标签的大小、位置 这些操作都放在定时器外面
深浅克隆
深浅克隆针对引用数据类型的,将数据复制一份新的出来,要保障新的数据跟原数据不共享共一个数据地址。
浅克隆:只能克隆最外层数据,内层数据还会共享共一个数据地址。
深克隆:外层数据和内层数据完全不共享地址。
对象浅克隆:
- 遍历原对象将所有键值对放在新对象中
- 利用Object.assign(新对象, 原对象)
- var 新对象 = {...原对象}
数组浅克隆:
- 遍历原数组将所有数据放在新数组中
- 利用Object.assign(新数组, 原数组)
- var 新数组 = {...原数组}
- 利用数组的slice方法,将开头到结尾都截取出来赋值给新数组
- 利用数组的concat方法,将原数组跟空气(什么也不合并)进行合并形成新数组
深克隆:
- 利用json数据转换:var 新数据 = JSON.parse(JSON.stringify(原数据))
手写递归
function deepClone(data) { if(Object.prototype.toString.call(data) === '[object Object]') { var newData = {} } else if(Object.prototype.toString.call(data) === '[object Array]') { var newData = [] } else { return data } for(var key in data){ if(Object.prototype.toString.call(data[key]) === '[object Object]' || Object.prototype.toString.call(data[key]) === '[object Array]') { newData[key] = deepClone(data[key]) } else { newData[key] = data[key } } return newData }
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。