JS 相关补充

JavaScript 由以下三部分组成:
  • ECMAScript(核心):JavaScript 语言基础
  • DOM(文档对象模型):规定了访问HTML和XML的接口
  • BOM(浏览器对象模型):提供了浏览器窗口之间进行交互的对象和方法
JS内置对象
  • 数据封装类对象:Object、Array、Boolean、Number、String
  • 其他对象:Function、Arguments、Math、Date、RegExp、Error
  • ES6新增对象:Symbol、Map、Set、Promises、Proxy、Reflect
一些规范
  • 代码段使用花括号{}包裹
  • 变量和函数在使用前进行声明
  • 以大写字母开头命名构造函数,全大写命名常量
  • 规范定义JSON对象,补全双引号
  • 用{}和[]声明对象和数组
高性能编写注意
  • 遵循严格模式:”use strict”;
  • 将js脚本放在页面底部,加快渲染页面
  • 将js脚本将脚本成组打包,减少请求
  • 使用非阻塞方式下载js脚本
  • 尽量使用局部变量来保存全局变量
  • 尽量减少使用闭包
  • 使用 window 对象属性方法时,省略 window
  • 尽量减少对象成员嵌套
  • 缓存 DOM 节点的访问
  • 通过避免使用 eval() 和 Function() 构造器
  • 给 setTimeout() 和 setInterval() 传递函数而不是字符串作为参数
  • 尽量使用直接量创建对象和数组
  • 最小化重绘(repaint)和回流(reflow)
最小化重绘和回流
  • 需要要对元素进行复杂的操作时,可以先隐藏(display:”none”),操作完成后再显示
  • 需要创建多个DOM节点时,使用DocumentFragment创建完后一次性的加入document
  • 缓存Layout属性值,如:var left = elem.offsetLeft; 这样,多次使用 left 只产生一次回流
  • 尽量避免用table布局(table元素一旦触发回流就会导致table里所有的其它元素回流)
  • 避免使用css表达式(expression),因为每次调用都会重新计算值(包括加载页面)
  • 尽量使用 css 属性简写,如:用 border 代替 border-width, border-style, border-color
变量提升
  • 在JavaScript中,函数声明与变量声明经常被JavaScript引擎隐式地提升到当前作用域的顶部。
  • 声明语句中的赋值部分并不会被提升,只有名称被提升
  • 函数声明的优先级高于变量,如果变量名跟函数名相同且未赋值,则函数声明会覆盖变量声明
  • 如果函数有多个同名参数,那么最后一个参数(即使没有定义)会覆盖前面的同名参数
原型原型链
  • JavaScript的所有对象中都包含了一个 [proto] 内部属性
  • 当函数对象作为构造函数创建实例时,prototype 属性值将被作为实例对象的原型 [proto]
  • 当一个对象调用的属性/方法自身不存在时,就会去自己 [proto] 关联的前辈 prototype 对象上去找
  • 如果没找到,就会去该 prototype 原型 [proto] 关联的前辈 prototype 去找。依次类推,直到找到属性/方法或 undefined 为止。从而形成了所谓的“原型链”
  • JavaScript对象是通过引用来传递的,当修改原型时,与之相关的对象也会继承这一改变(原型特点)
this对象
  • this 总是指向函数的直接调用者
  • 如果有 new 关键字,this 指向 new 出来的实例对象
  • 在事件中,this指向触发这个事件的对象
  • IE下 attachEvent 中的this总是指向全局对象Window
DOM的发展
  • DOM:文档对象模型(Document Object Model),定义了访问HTML和XML文档的标准,与编程语言及平台无关
  • DOM0:提供了查询和操作Web文档的内容API。未形成标准,实现混乱。如:document.forms[‘login’]
  • DOM1:W3C提出标准化的DOM,简化了对文档中任意部分的访问和操作。如:JavaScript中的Document对象
  • DOM2:原来DOM基础上扩充了鼠标事件等细分模块,增加了对CSS的支持。如:getComputedStyle(elem, pseudo)
  • DOM3:增加了XPath模块和加载与保存(Load and Save)模块。如:XPathEvaluator
事件委托/代理
  • 是指将事件绑定目标元素的到父元素上,利用冒泡机制触发该事件
  • 优点:
    可以减少事件注册,节省大量内存占用; 可以将事件应用于动态添加的子元素上
  • 缺点:
    使用不当会造成事件在不应该触发时触发
new操作符做了什么
  • 创建实例对象,this 变量引用该对象,同时还继承了构造函数的原型
  • 属性和方法被加入到 this 引用的对象中
  • 新创建的对象由 this 所引用,并且最后隐式的返回 this
闭包(closure)
  • 闭包是指有权访问另一个函数作用域中变量的函数,创建闭包的最常见的方式就是在一个函数内创建另一个函数,通过另一个函数访问这个函数的局部变量,利用闭包可以突破作用链域
  • 使用闭包主要是为了设计私有的方法和变量。闭包的优点是可以避免全局变量的污染,缺点是闭包会常驻内存,会增大内存使用量,使用不当很容易造成内存泄露。在js中,函数即闭包,只有函数才会产生作用域的概念
闭包的特性
  • 函数内再嵌套函数
  • 内部函数可以引用外层的参数和变量
  • 参数和变量不会被垃圾回收机制回收
内存泄漏
  • 内存泄漏指任何对象在您不再拥有或需要它之后仍然存在
  • 垃圾回收器定期扫描对象,并计算引用了每个对象的其他对象的数量。如果一个对象的引用数量为 0(没有其他对象引用过该对象),或对该对象的惟一引用是循环的,那么该对象的内存即可回收
  • setTimeout 的第一个参数使用字符串而非函数的话,会引发内存泄漏
  • 闭包、控制台日志、循环(在两个对象彼此引用且彼此保留时,就会产生一个循环)
Array.slice()
  • “读取”数组指定的元素,不会对原数组进行修改
  • arr.slice(start, end)
Array.splice()
  • “操作”数组指定的元素,会修改原数组,返回被删除的元素
  • 语法:arr.splice(index, count, [insert Elements])
  • index 是操作的起始位置
  • count = 0 插入元素,count > 0 删除元素
  • [insert Elements] 向数组新插入的元素