每个对象都有一个属性__proto__指向构造函数的原型对象,对象可以继承原型对象上的属性和方法,原型对象又有原型,可以继承原型对象上的属性和方法,这样一层一层,以此类推,这种关系称为原型链 每个函数都有一个属性prototype指向原型对象,创建一个函数的时候就创建了这个属性 new 构造函数创建的实例,内部的__proto__属性指向构造函数的原型对象,普通对象的__proto__属性指向Object.prototype,函数对象的__proto__指向Function.prototype,每个对象都有__proto__属性,除了Object,create(null)创建的对象没有原型 原型对象上有一个constructor的属性指向构造函数,因为实例对象继承了原型对象的方法,所以实例对象也可以通过constructor属性找到构造函数
有权访问函数内部变量的函数叫做闭包,创建的方式就是一个函数内部创建一个函数 闭包的两个用处:
可以访问函数内部变量,可以设计私有变量和方法可以将变量始终保存在内存中好处:实现封装和缓存,减少全局变量的污染 缺点:闭包会引用函数的作用域,增加内存用量,容易造成内存泄漏 解决方法:在退出函数之前,将不用的局部变量删除,将变量设为Null 作用域链的理解: 确保执行环境中对有权访问的变量和函数是有序的,只能向上访问,访问到window为止,不能向下访问 创建函数会创建一个作用域链(包含全局变量以及包裹他的函数活动对象),作用域链保存在内部的[[scope]]属性中
this 执行上下文对象,在函数调用时确定this的指向
默认绑定:直接使用函数引用调用的,指向window,严格模式是undefined隐式绑定:对象.方法 对象调用函数指向对象显式绑定:bind call apply 绑定thisnew创建的新对象 this指向新对象回流(Reflow):渲染树中的元素尺寸、形状、为止改变时,影响了周围元素或内部元素时,浏览器会重新渲染部分或全部文档 操作:
页面首次渲染添加或删除可见元素元素尺寸内容位置字号图片大小改变浏览器窗口resize激活css伪类(:hover)重绘(Repaint):改变颜色以及visible 性能影响:回流的代价更高 浏览器优化回流,将所有引起回流重绘的操作放入队列中,如果任务数量或时间间隔达到某一个阈值,浏览器会清空队列,进行一次批处理 但是某些方法或属性,会立即处理: clientWidth/offsetWidth/scrollWidth/width/height/getComputedStyle(elem,null).getPropertyValue(‘height’) 优化:引起少量回流或少量元素回流
避免使用table布局,因为table在变成渲染树时会经过多次计算将动画效果应用在position为absolute或fixed元素上,,使其脱离文档流,否则会引起父元素以及后续元素的回流避免使用css表达式(会增大计算量)javascript中避免回流的方法
避免频繁操作样式 style一次重写,用class2. documentFragment 文档片段 不会回流必须用到的属性 offsetHeight 缓存先display:none;操作之后再display:block;对动画使用绝对定位defer: 延迟执行引用的JS(执行之后,执行DOMContentLoaded) 载入JS文件不会影响HTML的解析,执行阶段会放到HTML解析完成之后 async: 异步引入的js 如果已经加载好,就开始执行(此时可能是HTML解析阶段,可能是在DOMContentLoaded之后);一定在load之前触发;执行会阻塞HTML解析,如果是在HTML解析阶段
src: 是下载src指向的资源应用到当前文档中,会暂停其他资源的下载和解析 href是指向网络资源所在位置,并行下载资源,不会停止对当前文档的处理
常规流(标准流): 块盒一行一行竖着排列;行内盒横着排列;float为none;position为static和relative在常规流中排列 position为relative相对定位,位置偏移,但是原有位置会在常规流中保留 BFC的效果:
创建一个独立的空间内部有个标准流处于同一个bfc的元素,可能会发生margin合并计算BFC高度是,考虑BFC的所有子元素,包括浮动元素BFC的创建
根元素float不为none,position为fixed和absolute行内块(display:inline-block)表格单元格(display:table-cell)弹性盒(display:flex/inline-flex)overflow不为 visible外边距合并: 处于同一个BFC中的块盒垂直方向上会发生margin合并 解决:给其中一个盒子加上overflow:hidden;让其不在同一个BFC中
把需要绑定的事件委托给父元素,让父元素监听事件 原理:事件冒泡 冒泡的事件可以委托 不冒泡的事件不可以委托 好处:提高性能,节约内存占用,减少事件注册 event.target是触发的对象 event.currentTarget 是绑定事件的对象
事件3个阶段:捕获(父到子)目标 冒泡(子到父) 默认触发事件的阶段是冒泡阶段 如果把addEventListener的第三个参数改为true 就是在捕获阶段触发 阻止冒泡:stopPropagation IE是 cancelBubble= true 取消默认事件: e.preventDefault IE是 e.returnValue= false
特点:同步加载模块,服务端,模块文件都在本地磁盘上,读取起来很快,所以没问题,但浏览器上限于网络原因,更合理应使用异步加载
特点:异步加载模块,模块的加载不影响后面语句的执行。所有依赖这个模块的语句都被定义在一个回调中,等待加载完成执行 requireJS主要解决的问题: (1)多个JS可能存在依赖关系,被依赖的文件要早于依赖他的文件加载 (2)JS加载,浏览器暂停页面渲染,加载文件越多,页面失去响应的时间越长
一个模块一个文件 define(function(require, exports,module){ var $= require(‘jquery.js’) $(‘div’).addClass(‘active’) }) 在文件中引入加载模块,使用时加载
AMD:依赖前置,定义模块时就下载并执行依赖模块,所有模块执行完了,才开始执行回调中的主逻辑 CMD:就近依赖,定义模块时需要把模块变成字符串遍历一遍,知道依赖了哪些模块,然后下载但不执行,只有主逻辑遇到require了才去执行依赖 AMD中的依赖放在数组中,依赖执行没有先后顺序 CMD中遇到require才去执行,执行顺序与页面书写的顺序一致 下载都是异步下载,AMD体验好,因为没有延迟,依赖模块提前执行;CMD性能好,只有用户用到才去执行
ES6 的模块不是对象,import命令会被JavaScript引擎静态分析,在编译时就引入模块代码,而不是运行时,因此不能实现条件加载
MVVM是model-view-viewmodel的缩写 model代表数据层 ,view代表是视图层, viewmodel监听数据的改变和控制视图行为、处理用户交互,简单理解就是一个同步view和model的对象,连接model和view 在MVVM架构中,view和model之间没有直接的联系,而是通过viewmodel进行交互,model和viewmodel之间的交互式双向的,因此view数据的变化会同步到model中,而model数据的变化也会立即反映到view上
beforeRouteEnter进入路由之前 beforeRouteUpdate路由改变 但该组件被复用 beforeRouteLeave 离开路由之前 afterEach 进入每个路由之后 beforeEach 进入每个路由之后
相同类型的节点:
key相同(如果没有 就是undefined == undefined)tag 标签名相同且isComment(是否为注释节点)且data是否都存在且是否都为input或不为input是异步组件 工厂函数asyncFactory相同vue的diff算法
对比新旧开始结束节点是否为相同类型的节点,是的话就原地复用,新旧开始指针向后挪一个对比新旧开始与结束或结束与开始节点是否为相同节点;是的话就用insertBefore移动节点如果新有旧没有,添加节点 这样简单的移动添加得到快速处理,待处理节点减少,缩小处理范围,性能得到提升就是在上面提到的判断节点是否为相同类型节点时,如果key相同的话就会就地复用,key的作用主要是为了高效的更新虚拟DOM