JS必备知识点
将工作中遇到的问题记录在此
-  数据类型 null对象 值类型(基本类型):字符串(String)、数字(Number)、布尔(Boolean)、对空(Null)、未定义(Undefined)、Symbol。 
 引用数据类型:对象(Object)、数组(Array)、函数(Function)。
-  NAN数值型 NaN 即非数值(Not a Number),NaN 属性用于引用特殊的非数字值,该属性指定的并不是不合法的数字。 
 NaN 属性 与 Number.Nan 属性相同。
 提示: 请使用 isNaN() 来判断一个值是否是数字。原因是 NaN 与所有值都不相等,包括它自己。是Number中的一个值 
-  undefined和null的区别 undefined表示一个未声明的变量,或已声明但没有赋值的变量,或一个并不存在的对象属性。 nulLL定义并赋值了,只是值为nuLL 
-  数组属不属于对象 数组是一种特殊类型的对象。 在 JavaScript 中对数组使用 typeof 运算符会返回 “object”。 
-  typeof与instanceof区别是什么 typeof主要用来判断基础数据类型,instanceof则是用来判断引用数据类型。 
-  事件的绑定 三种 -  在DOM元素中直接绑定; 
-  在JavaScript代码中绑定; 
 -  3.绑定事件监听函数。 element.addEventListener() 使用removeEventListener() 方法来移除 addEventListener() 方法添加的事件句柄。 element.addEventListener(event, function, useCapture) 参数 描述 event 必须。字符串,指定事件名。注意: 不要使用 “on” 前缀。 例如,使用 “click” ,而不是使用 “onclick”。提示: 所有 HTML DOM 事件,可以查看我们完整的 HTML DOM Event 对象参考手册。 function 必须。指定要事件触发时执行的函数。 当事件对象会作为第一个参数传入函数。 事件对象的类型取决于特定的事件。例如, “click” 事件属于 MouseEvent(鼠标事件) 对象。 useCapture 可选。布尔值,指定事件是否在捕获或冒泡阶段执行。 可能值: * true - 事件句柄在捕获阶段执行 * false- false- 默认。事件句柄在冒泡阶段执行 移除 addEventListener() 方法添加的 “mousemove” 事件: // 向 <div> 元素添加事件句柄 document.getElementById("myDIV").addEventListener("mousemove", myFunction); // 移除 <div> 元素的事件句柄 document.getElementById("myDIV").removeEventListener("mousemove", myFunction);
 
-  
-  鼠标事件哪几个 七个 事件类型 说明 click 单击鼠标左键时发生,如果右键也按下则不会发生。当用户的焦点在按钮上并按了 Enter 键时,同样会触发这个事件 dblclick 双击鼠标左键时发生,如果右键也按下则不会发生 mousedown 单击任意一个鼠标按钮时发生 mouseout 鼠标指针位于某个元素上且将要移出元素的边界时发生 mouseover 鼠标指针移出某个元素到另一个元素上时发生 mouseup 松开任意一个鼠标按钮时发生 mousemove 鼠标在某个元素上时持续发生 
-  事件冒泡,事件捕获 -  事件冒泡 在 冒泡 中,内部元素的事件会先被触发,然后再触发外部元素,即: <p> 元素的点击事件先触发,然后会触发 <div> 元素的点击事件。false 
-  事件捕获 在 捕获 中,外部元素的事件会先被触发,然后才会触发内部元素的事件,即: <div> 元素的点击事件先触发 ,然后再触发 <p> 元素的点击事件。true 
 
-  
-  事件委托 事件委托,通俗地来讲,就是把一个元素响应事件(click、keydown…)的函数委托到另一个元素; 一般来讲,会把一个或者一组元素的事件委托到它的父层或者更外层元素上,真正绑定事件的是外层元素,当事件响应到需要绑定的元素上时,会通过事件冒泡机制从而触发它的外层元素的绑定事件上,然后在外层元素上去执行函数。 
-  闭包的概念 闭包是一种保护私有变量的机制,在函数执行时形成私有的作用域,保护里面的私有变量不受外界干扰。 直观的说就是形成一个不销毁的栈环境。 -  写个例子 var add = (function () { var counter = 0; return function () {return counter += 1;} })(); add(); add(); add();
 
-  
-  变量提升 解析器会先解析代码,然后把声明的变量的声明提升到最前,这就叫做变量提升。 使用 var定义的代码,声明会被提升到前面(依旧在函数内部),赋值还在原位置ES6之前我们一般使用var来声明变量,提升简单来说就是把我们所写的类似于var a = 123;这样的代码,声明提升到它所在作用域的顶端去执行,到我们代码所在的位置来赋值。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 
  console.log(v1);//undefined var v1 = 100; function foo() { console.log(v1);//undefined var v1 = 200; console.log(v1);//200 } foo(); console.log(v1); //100
-  this -  在方法中,this 表示该方法所属的对象。 
-  如果单独使用,this 表示全局对象。 
-  在函数中,this 表示全局对象。 
-  在函数中,在严格模式下,this 是未定义的(undefined)。 
-  在事件中,this 表示接收事件的元素。 
-  类似 call() 和 apply() 方法可以将 this 引用到任何对象。 
 
-  
-  getEID和getEclass区别 id只会获取一个对象 class会获取一个伪数组 
-  浏览器加载顺序 -  用户输入网址(假设是个 HTML 页面,并且是第一次访问),浏览器向服务器发出请求,服务器返回 HTML 文件; 
-  浏览器开始载入 HTML 代码,发现 <head> 标签内有一个 <link> 标签引用外部 CSS 文件; 
-  浏览器又发出 CSS 文件的请求,服务器返回这个 CSS 文件; 
-  浏览器继续载入 HTML 中 <body> 部分的代码,并且 CSS 文件已经拿到手了,可以开始渲染页面了; 
-  浏览器在代码中发现一个 < img > 标签引用了一张图片,向服务器发出请求。此时浏览器不会等到图片下载完,而是继续渲染后面的代码; 
-  服务器返回图片文件,由于图片占用了一定面积,影响了后面段落的排布,因此浏览器需要回过头来重新渲染这部分代码; 
-  浏览器发现了一个包含一行 JavaScript 代码的 <script> 标签,赶快运行它; 
-  JavaScript 脚本执行了这条语句,它命令浏览器隐藏掉代码中的某个 <div>(style.display=”none”)。杯具啊,突然就少了这么一个元素,浏览器不得不重新渲染这部分代码; 
-  终于等到了 </html> 的到来,浏览器泪流满面…… 
-  等等,还没完,用户点了一下界面中的“换肤”按钮,JavaScript 让浏览器换了一下 <link> 标签的 CSS 路径; 
-  浏览器召集了在座的各位 < div><span>< ul>< li> 们,“大伙儿收拾收拾行李,咱得重新来过……”,浏览器向服务器请求了新的CSS文件,重新渲染页面。 
 
-  
-  回调函数的理解 回调函数就是一个函数,它是在我们启动一个异步任务的时候就告诉它:等你完成了这个任务之后要干什么。这样一来主线程几乎不用关心异步任务的状态了,他自己会善始善终。 
-  数组创建 -  字面量方式(json方式) var arr1 = []; //创建一个空数组 var arr2 = [5]; //创建一个具有单个元素的数组 var arr3 = [5,6,7]; //创建一个具有多个元素的数组
-  构造函数方式 var arr1 = new Array(); //创建一个空数组 var arr2 = new Array(5); //创建一个长度为5,值为空的数组 var arr3 = new Array(5,6,7); //创建一个具有多个元素的数组
 
-  
-  数组的方法 方法名 对应版本 功能 原数组是否改变 concat() ES5- 合并数组,并返回合并之后的数据 no join() ES5- 使用分隔符,将数组转为字符串并返回 no pop() ES5- 删除最后一位,并返回删除的数据 yes shift() ES5- 删除第一位,并返回删除的数据 yes unshift() ES5- 在第一位新增一或多个数据,返回长度 yes push() ES5- 在最后一位新增一或多个数据,返回长度 yes reverse() ES5- 反转数组,返回结果 yes slice() ES5- 截取指定位置的数组,并返回 no sort() ES5- 排序(字符规则),返回结果 yes splice() ES5- 删除指定位置,并替换,返回删除的数据 yes toString() ES5- 直接转为字符串,并返回 no valueOf() ES5- 返回数组对象的原始值 no indexOf() ES5 查询并返回数据的索引 no lastIndexOf() ES5 反向查询并返回数据的索引 no forEach() ES5 参数为回调函数,会遍历数组所有的项,回调函数接受三个参数,分别为value,index,self;forEach没有返回值 no map() ES5 同forEach,同时回调函数返回数据,组成新数组由map返回 no filter() ES5 同forEach,同时回调函数返回布尔值,为true的数据组成新数组由filter返回 no every() ES5 同forEach,同时回调函数返回布尔值,全部为true,由every返回true no some() ES5 同forEach,同时回调函数返回布尔值,只要由一个为true,由some返回true no reduce() ES5 归并,同forEach,迭代数组的所有项,并构建一个最终值,由reduce返回 no reduceRight() ES5 反向归并,同forEach,迭代数组的所有项,并构建一个最终值,由reduceRight返回 no 链接:https://www.jianshu.com/p/7e160067a06c 
-  ==与===的区别 ===绝对相等,类型数值 ==类型可自动转化 
-  计时器 1.在JavaScript中,我们可以在设定的时间间隔之后来执行代码,而不是在函数被调用后立即执行。 2.计时器类型: (1)一次性计时器:仅在指定的延迟时间之后触发一次。 (2)间隔性触发计时器:每隔一定的时间间隔就触发一次 3.方法描述 setTimeout() 指定的延迟时间之后来执行代码 clearTimeout() 取消setTimeout的设置 setInterval() 每隔指定的时间执行代码 clearInterval() 取消setInterval的设置 
-  正则表达式 -  一、正则表达式概述 
-  二、正则表达式的创建 两种方式: 
-  三、正则表达式内容具体含义 因为我也是初学者,就 尽可能用通俗的语言去写,没有使用倒专业名词,请见谅。 边界符(一般用于精准匹配) 量词符 括号总结 常见的字符简写形式 i 执行对大小写不敏感的匹配。 g 执行全局匹配(查找所有匹配而非在找到第一个匹配后停止)。 m 执行多行匹配。 元字符 描述 \d 查找数字。 \s 查找空白字符。 \b 匹配单词边界。 \uxxxx 查找以十六进制数 xxxx 规定的 Unicode 字符。 [abc] 查找方括号之间的任何字符。 [0-9] 查找任何从 0 至 9 的数字。 (x|y) 查找任何以 | 分隔的选项。 
-  四、常见的正则验证代码 验证字母:/^[a-zA-Z]+$/ 验证长度为3的字符:/^.{3}$/ 验证由26个英文字母组成的字符串:/^[A-Za-z]+$/ 验证日期YYYY-MM-DD:/^(\d{1,4})(-|\/)(\d{1,2})\2(\d{1,2})$/ 验证邮编:/^\d{6}$/ 验证整数:/^[-+]?\d*$/ 验证小数:/^[-+]?\d+(.\d+)?$/ 验证中文:/^[\u0391-\uFFE5]+$/ 验证邮箱:/^\w+([-+.]\w+)@\w+([-.]\w+).\w+([-.]\w+)*$/ 验证手机号:/^1[3456789]\d{9}$/ 验证身份证:/^\d{6}(18|19|20)?\d{2}(0[1-9]|1[12])(0[1-9]|[12]\d|3[01])\d{3}(\d|X)$/ 
-  五、js中常用的正则表达式 // 验证输入的内容是否是空 isNull:function(idStr){ var str = document.getElementById(idStr).value.trim(); var regex = /\S/; if(!regex.test(str)){ alert("文本框不能为空,请输入内容!"); } } // 验证输入的字符是否是英文字母 isLetter:function(idStr){ var str = document.getElementById(idStr).value.trim(); var regex = /^[a-zA-Z]+$/; if(!regex.test(str)){ alert("请输入正确的英文字母!"); } } // 验证日期格式是否为YYYY-MM-DD格式 isDate:function(idStr){ var str = document.getElementById(idStr).value.trim(); var regex = /^(\d{1,4})(-|\/)(\d{1,2})\2(\d{1,2})$/; var r = str.match(regex); // 使用match方法获取指定字符串的值 if(r==null){ alert("请输入正确的日期格式!"); } } // 验证日期格式是否为YYYY-MM-DD hh:mm:ss格式 isDateTime:function(idStr){ var str = document.getElementById(idStr).value.trim(); var regex = /^(\d{1,4})(-|\/)(\d{1,2})\2(\d{1,2}) (\d{1,2}):(\d{1,2}):(\d{1,2})$/; var r = str.match(regex); // 使用match方法获取指定字符串的值 if(r==null){ alert("请输入正确的日期格式!"); } } // 验证整数 isInteger:function(idStr){ var str = document.getElementById(idStr).value.trim(); var regex = /^[-+]?\d*$/; if(!regex.test(str)){ alert("请输入正确的整数!"); } } // 验证双精度 isDouble:function(idStr){ var str = document.getElementById(idStr).value.trim(); var regex = /^[-+]?\d+(.\d+)?$/; if(!regex.test(str)){ alert("请输入正确的小数!"); } } // 验证中文 isChinese(idStr){ var str = document.getElementById(idStr).value.trim(); var regex = /^[\u0391-\uFFE5]+$/; if(!regex.test(str)){ alert("请输入正确的中文!"); } } // 验证邮箱 isEmail(idStr){ var str = document.getElementById(idStr).value.trim(); var regex = /^\w+([-+.]\w+)*@\w+([-.]\w+)*.\w+([-.]\w+)*$/; if(!regex.test(str)){ alert("请输入正确的邮箱格式!"); } } // 验证手机号 isPhone(idStr){ var str = document.getElementById(idStr).value.trim(); var regex = /^1[3456789]\d{9}$/; if(!regex.test(str)){ alert("请输入正确的手机号!"); } } // 验证身份证 isIdCard(idStr){ var str = document.getElementById(idStr).value.trim(); var regex = /^\d{6}(18|19|20)?\d{2}(0[1-9]|1[12])(0[1-9]|[12]\d|3[01])\d{3}(\d|X)$/; if(!regex.test(str)){ alert("请输入正确的身份证号码!"); } } //注:正则表达式里面不许要加引号,不管是字符串型还是数字型
 
-  
-  原型原型链  
-  JS异步同步 JavaScript 中的异步操作函数往往通过回调函数来实现异步任务的结果处理。 Promise学习异步时,对函数里面的 resolve() 不太理解,后来上网查了查,知道了他的作用: 
 Promise 对象代表一个异步操作,有三种状态:Pending(进行中)、Resolved(已完成,又称 Fulfilled)和 Rejected(已失败)。
 通过回调里的 resolve(data) 将这个 promise 标记为 resolverd,然后进行下一步 then((data)=>{//do something}),resolve 里的参数就是你要传入 then 的数据。new Promise(function (resolve, reject) { var a = 0; var b = 1; if (b == 0) reject("Divide zero"); else resolve(a / b); }).then(function (value) { console.log("a / b = " + value); }).catch(function (err) { console.log(err); }).finally(function () { console.log("End"); });
-  DOM对象获取 -  通过 id 找到 HTML 元素 var x=document.getElementById("intro");
-  通过标签名查找 HTML 元素 var x=document.getElementById("main"); var y=x.getElementsByTagName("p");
-  通过类名找到 HTML 元素 var x=document.getElementsByClassName("intro");
 
-  
-  伪数组 1,function内的arguments 。 2,通过document.forms,Form.elements,Select.options,document.getElementsByName() , document.getElementsByTagName() ,childNodes/children 等方式获取的集合(HTMLCollection,NodeList)等。 3,特殊写法的对象 ,如 Js代码 收藏代码 var obj={}; obj[0] = “一”; obj[1] = “二”; obj[2] = “三”; obj.length = 3; 它们不具有数组的一些方法如push, pop, shift, join等。有时候需要将这些伪数组转成真正的数组,这样可以使用push, pop等方法。 function log(){ var args = Array.prototype.slice.call(arguments); //为了使用unshift数组方法,将argument转化为真正的数组 args.unshift('(app)'); console.log.apply(console, args); };
-  ES6 -  let、const和block作用域 let创建块级作用域 const创建块级作用域,声明常量 
 -  let 关键词声明的变量不具备变量提升(hoisting)特性 
-  let 和 const 声明只在最靠近的一个块中(花括号内)有效 
-  当使用常量 const 声明时,请使用大写变量,如:CAPITAL_CASING 
-  const 在声明时必须被赋值 
 
-  
-  箭头函数 去掉function在括号后面添加=> var getPrice = function() { return 4.55; }; // Implementation with Arrow Function var getPrice = () => 4.55;
-  函数参数默认值 传入参数时就可以设置默认值 let getFinalPrice = (price, tax=0.7) => price + price * tax; getFinalPrice(500); // 850
-  Spread/Rest操作符( …Arr) 将数组展开 function foo(...args) { console.log(args); } foo( 1, 2, 3, 4, 5); // [1, 2, 3, 4, 5]
-  对象词法扩展 function getCar(make, value) { return { // 简写变量 make, // 等同于 make: make value, // 等同于 value: value // 属性可以使用表达式计算值 ['make' + make]: true, // 忽略 `function` 关键词简写对象函数 depreciate() { this.value -= 2500; } }; } let car = getCar('Barret', 40000); // output: { // make: 'Barret', // value: 40000, // makeBarret: true, // depreciate: [Function: depreciate] // }
-  二进制和八进制字面量 数字前面添加 0o 或者0O 即可将其转换为八进制值 let oValue = 0o10; console.log(oValue); // 8 let bValue = 0b10; // 二进制使用 `0b` 或者 `0B` console.log(bValue); // 2
-  对象和数组解构 function foo() { return [1,2,3]; } let arr = foo(); // [1,2,3] let [a, b, c] = foo(); console.log(a, b, c); // 1 2 3 function bar() { return { x: 4, y: 5, z: 6 }; } let {x: x, y: y, z: z} = bar(); console.log(x, y, z); // 4 5 6
-  对象超类(没看懂) ES6 允许在对象中使用 super 方法: var parent = { foo() { console.log("Hello from the Parent"); } } var child = { foo() { super.foo(); console.log("Hello from the Child"); } } Object.setPrototypeOf(child, parent); child.foo(); // Hello from the Parent // Hello from the Child
-  模板语法和分隔符 -  ${ … } 用来渲染一个变量 
-  ` 作为分隔符 
 let user = 'Barret'; console.log(Hi ${user}!); // Hi Barret!
-  
-  for…of VS for…in for…in:遍历键名,会遍历对象的整个原型链,性能差。 for…of:后者遍历键值,只遍历当前对象不会遍历原型链,将异步循环变成同步循环。 
-  Map 和 WeakMap -  Map -  Map 的特点 -  Map 默认情况下不包含任何键,所有键都是自己添加进去的。不同于 Object原型链上有一些默认的键。
-  Map 的键可以是「任意类型」数据,就连函数都可以。 
-  Map 的键值对个数可以「轻易」通过 size属性获取,Object需要手动计算。
-  Map 在频繁增删键值对的场景下「性能」要比 Object好。
 
-  
-  什么时候用 Map -  要添加的键值名和 Object上的默认键值名冲突,又不想改名时,「用 Map」
-  需要 String和Symbol以外的数据类型做键值时,「用 Map」
-  键值对很多,有需要计算数量时,「用 Map」 
-  需要频繁增删键值对时,「用 Map」 
 
-  
-  Map 实例属性和方法 -  set set方法设置键名key对应的键值为 value,然后会返回整个Map结构,如果设置的key已经存在,则会更新value值,否则会新生成该键方法一: const dataMap = new Map(); dataMap.set('name','小黑');方法二: const longMap = new Map().set(1,'a').set(2,'b'); console.log(longMap);
-  get 通过get方法读取key对应的键值,如果传入的键值不存在,则会返回 undefinedconst dataMap = new Map(); dataMap.set('name','小黑'); console.log(dataMap.get('name'));
-  has 判断传入的键是否存在当前 Map对象中,该方法返回一个布尔值const dataMap = new Map(); dataMap.set('name','小黑'); console.log(dataMap.has('name')); //true console.log(dataMap.has('sex')); // false
-  delete 删除传入的键,返回 true,如果删除失败,则返回falseconst dataMap = new Map( ); dataMap. set( 'name' ,'小黑' ); //在删除之前查询是否存在该键 console.log(dataMap.has('name'));// true //删除该键 dataMap.delete('name') //再次查看是否存在该键,发现已移除 console.log( dataMap.has('name'));// false
 
-  
-  遍历方法 可以采用for…of循环和forEach两种方法。由于Map实例会维护键值对的插入顺序,因此可以根据插入顺序进行遍历采用「for…of」 -  keys():返回键名的遍历器 
-  values():返回键值的遍历器 
-  entries():返回键值对的遍历器 
-  forEach():使用回调函数遍历每个成员 
 
-  
-  Map类型转化 Map 转为数组 let map = newMap() let arr = [...map]数组转为 Map let map = newMap(arr)Map 转为对象 let obj = {} for (let [k, v] of map) { obj[k] = v } //对象转为 Map for( let k ofObject.keys(obj)){ map.set(k,obj[k]) }
 
-  
-  WeakMap WeakMap是 ES6 中新增的一种集合类型,叫做“弱映射”。它和Map是兄弟关系,与Map的区别就在于这个「弱字」,API 还是Map的那套(只有set get has delete)这其实描述的是 JS 中「垃圾回收」程序对待“弱映射”中键的方式 -  WeakMap的特点 -  WeakMap 只能将对象作为键名 
-  WeakMap 的键名引用的对象是弱引用 
-  不可遍历 
 
-  
 
-  
-  Map 和 WeakMap 的区别 -  Map 的键可以是任意类型,WeakMap 只接受对象作为键(null除外),不接受其他类型的值作为键 
-  Map 的键实际上是跟内存地址绑定的,只要内存地址不一样,就视为两个键;WeakMap 的键是弱引用,键所指向的对象可以被垃圾回收,此时键是无效的 
-  Map 可以被遍历, WeakMap 不能被遍历 
 
-  
 详解 Map 和 WeakMap 区别以及使用场景_javascript技巧_脚本之家 (jb51.net) 
-  
-  Set 和 WeakSet -  Set Set是ES6 提供的新的数据结构。它类似于数组,只有属性值,并且成员的值都是唯一的,没有重复的值。 
-  WeakSet WeakSet 结构与 Set 类似,weakSet的成员值是唯一的,并且 WeakSet 的成员只能是对象,而不能是其他类型的值 
-  传递参数的讲究 Set、WeakSet传递的参数必须具备迭代接口,比如:数组,字符串,arguments等,迭代接口就是指在原型上有:Symbol(Symbol.iterator) 
-  Set 与 WeakSet 之间的区别 -  与Set相比,WeakSet 只能是对象的集合,而不能是任何类型的任意值。 
-  WeakSet持弱引用:集合中对象的引用为弱引用。 如果没有其他的对 WeakSet中对象的引用,那么这些对象会被当成垃圾回收掉。 这也意味着WeakSet中没有存储当前对象的列表。 WeakSet 是不可枚举的。 
 
-  
 ES6之深入Set 与 WeakSet的知识讲解_huangyangquan3的博客-CSDN博客_weakset和set区别 
-  
-  类 类是用于创建对象的模板。 我们使用 class 关键字来创建一个类,类体在一对大括号 {} 中,我们可以在大括号 {} 中定义类成员的位置,如方法或构造函数。 每个类中包含了一个特殊的方法 constructor(),它是类的构造函数,这种方法用于创建和初始化一个由 class 创建的对象。 class ClassName { constructor() { ... } }使用类定义好类后,我们就可以使用 new 关键字来创建对象: class People { constructor(name, sex) { this.name = name; this.sex = sex; } } let site = new People("小黑", "男");创建对象时会自动调用构造函数方法 constructor()。 类表达式类表达式是定义类的另一种方法。类表达式可以命名或不命名。命名类表达式的名称是该类体的局部名称 // 未命名/匿名类 let People = class { constructor(name, sex) { this.name = name; this.sex = sex; } }; console.log(People.name); // output: "People" // 命名类 let People = class People2 { constructor(name, sex) { this.name = name; this.sex = sex; } }; console.log(People.name); // 输出: "People2"构造方法构造方法是一种特殊的方法: -  构造方法名为 constructor()。 
-  构造方法在创建新对象时会自动执行。 
-  构造方法用于初始化对象属性。 
-  如果不定义构造方法,JavaScript 会自动添加一个空的构造方法。 
 JavaScript 类(class) | 菜鸟教程 (runoob.com) 
-  
-  Symbol 什么是Symbol JavaScript标准中规定对象的key只能是 String 或 Symbol 类型,区别在于 String 类型的key可以重复而 Symbol 类型的key是唯一的。Symbol 的本质是表示一个唯一标识。每次创建一个Symbol,它所代表的值都不可能重复,该值的内部实现可以视为一段数字(类似:3423498431987719455…)。所以理论上 Symbol 的存在只有一个意义:用于必须使用唯一值的场景。 创建Symbol 创建 Number、String等基本类型的实例有两种方法:通过构造函数(或者叫工厂函数)和文字语法糖。比如: 显然使用语法糖更加简洁。但是 Symbol 只能通过构造函数 Symbol() 进行创建: const sym = Symbol();或者,我们可以传入一个字符串参数(descriptor)用于描述该Symbol: const sym = Symbol('cat');注意:传入的参数对 Symbol 值的产生并无影响,因为就算每次传入的参数都一样,生成的Symbol值也是不等的。该参数的作用仅用于描述被创建的Symbol,以便debug时可以识别出Symbol的含义。 所以,下列等式结果为 false: 和 Symbol() 类似,Symbol.for(key) 也可以创建一个Symbol,不一样的是:创建的 Symbol 是全局的(在全局Symbol表中注册),而如果全局已经存在相同 key 的Symbol,则直接返回该Symbol。所以,下列等式结果为 true: Symbol.for('cat') === Symbol.for('cat') // true如何使用Symbol 其实 Symbol 本身很简单,但是如何把它用好、且用的恰到好处却使人困惑,因为在平常工作中并没有多少非Symbol不用的场景。但是用对了Symbol会对你的代码质量有不少提升。 
-  迭代器(Iterators) 简介迭代器是一种设计模式,可在容器对象 如 链表、数组上遍历,无需关心容器对象的内存分配的实现细节。简单的理解就是可以一个一个的依次拿到其中的数据,类似一个移动的指针,但是会告诉我们什么时候结束。 js 中的迭代器是什么样子的在javascript 中迭代器是一个特殊对象,这个迭代器对象有一个next()方法,每次调用都返回一个对象(结果对象)。结果对象有两个属性:一个是value,表示下一个将要返回的值;另一个是done,它是一个布尔类型的值,如果已经迭代到序列中的最后一个值,则它为 true。迭代器还会保存一个内部指针,用来指向当前集合中值的位置,每调用一次next()方法,都会返回下一个可用的值,类似下面这个对象的结构。 { next: function () { return { value:'', done: true / false } } }迭代协议随着javascript 语言的能力进一步提升,新增了一些新的数据类型 如 Map、Set、WeakMap 等,为了这些不同的数据结构,可以统一的迭代,es6 增加了迭代协议这个东西。 迭代协议并不是新的内置实现或语法,而是协议。这些协议可以被任何遵循某些约定的对象来实现。 迭代协议具体分为两个协议:可迭代协议和迭代器协议。 简单的理解就是在js 中任何对象只要满足迭代协议就可以遍历 可迭代协议要成为可迭代对象, 一个对象必须实现 @@iterator 方法。这意味着对象(或者它原型链上的某个对象)必须有一个键为 @@iterator 的属性,可通过常量 Symbol.iterator 访问该属性: 简单的理解,你想让一个东西可以遍历,那么这个东西要有一个 @@iterator ,这个属性可以通过Symbol.iterator 访问 属性 值 [Symbol.iterator] 一个无参数的函数,其返回值为一个符合迭代器协议的对象。 迭代器协议迭代器协议定义了产生一系列值(无论是有限个还是无限个)的标准方式。当值为有限个时,所有的值都被迭代完毕后,则会返回一个默认返回值。 只有实现了一个拥有以下语义(semantic)的 next() 方法,一个对象才符合迭代器协议: 属性 值 next 一个无参数函数,返回一个应当拥有以下两个属性的对象: done(boolean) next() 方法必须返回一个对象,该对象应当有两个属性: done 和 value,如果返回了一个非对象值(比如 false 或 undefined),则会抛出一个 异常(“iterator.next() returned a non-object value”)。 迭代过程当一个对象需要被迭代的时候(比如被写入一个 for…of 循环时),首先,会不带参数调用它的 @@iterator 方法( 此时返回的是结构是这样的 { next: function () {}}),然后使用此方法返回的迭代器获得要迭代的值(其实就是不断的调用这个next()方法) 迭代总结迭代协议可以总结为,一个东西要遍历,必须满足可迭代协议跟迭代器协议 -  可迭代协议:这个对象必须有@@iterator,可以通过Symbol.iterator 访问 
-  迭代器协议:是一个对象,这个对象的next() 函数返回一个对象,这个对象包括两个属性,一个是value,一个是done(boolean,是否是最后一个元素,done 为 true 时 value 可省略) 
 也就是说 迭代器对象本质上,就是一个指针对象。通过指针对象的next(),用来移动指针。 自定义迭代对象是没有实现迭代器,所以不能遍历对象,为了可以实现对象的遍历,我们需要在对象上实现上面说的迭代器,通常有两种写法,一种是传统的写法,这种需要自己去控制内部的状态,另外一种是利用生成器函数返回的Generator的迭代器来实现,代码如下: -  传统写法 let obj = { name: 'joel', adress: 'gz', [Symbol.iterator]: () => { // 这里不要用this, 因为是return fn, this 会丢失 let index = -1, atrrList = Object.keys(obj); const objIterator = { next: () => { let result = '' index++ if (index < atrrList.length) { result = { value: atrrList[index], done: false } } else { result = { done: true } } return result } } return objIterator } } for (const item of obj) { console.log('atrrs:' + item + ',value:' + obj[item]) }
-  生成器函数写法 // 为不可迭代的对象添加迭代器 let obj = { a: 1, b: 2 } obj[Symbol.iterator] = function* () { let keys = Object.keys(obj); //取到key值的长度 let len = keys.length; //定义循环变量 let n = 0; //条件判断 while (n <= len - 1) { yield { k: keys[n], v: obj[keys[n]] }; n++ } } //返回的是个对象的key和value for (let { k, v } of obj) { console.log(k, v); }
 学会javascript之迭代器_javascript技巧_脚本之家 (jb51.net) 
-  
-  Generators 什么是生成器?生成器是在函数内部运行的一些代码 -  返回值后,它会自行暂停, 
-  调用程序可以要求取消暂停并返回另一个值 
 这种“返回”不是传统的从函数 return。所以它被赋予了一个特殊的名称——yield。 在 javascript 中,如果想要使用生成器,则需要: -  定义特殊的生成器函数 
-  调用该函数创建一个生成器对象 
-  在循环中使用该生成器对象,或直接调用其 next 方法 
 // File: sample-program.js //function 后面的 * 告诉 javascript 这是一个生成器函数。 function *createGenerator() { for(let i=0;i<20;i++) { yield i } } const generator = createGenerator() console.log(generator.next()) console.log(generator.next())如果运行这段代码,则会得到以下输出: Javascript生成器(Generator)的介绍与使用_javascript技巧_脚本之家 (jb51.net) 
-  
-  Promises 什么是 Promise Promise 是抽象的异步处理对象,以及对其进行各种操作的组件。 Javascript 为什么要引入 Promise 有了Promise对象,就可以将异步操作以同步操作的流程表达出来。 这样在处理多个异步操作的时候还可以避免了层层嵌套的回调函数。 此外,Promise对象提供统一的接口,必须通过调用 Promise#then和Promise#catch这两个方法来结果,除此之外其他的方法都是不可用的,这样使得异步处理操作更加容易。基本用法 三种办法创建 Promise 实例(对象) -  构造方法 let promies = new Promise((resolve, reject) => { resolve(); //异步处理 });
-  通过 Promise 实例的方法,Promise#then 方法返回的也是一个 Promise 对象 promise.then(onFulfilled, onRejected);
-  通过 Promise 的静态方法,Promise.resolve(),Promise.reject() var p = Promise.resolve(); p.then(function(value) { console.log(value); });
 Promise 的状态 Fulfilled: has-resolved, 表示成功解决,这时会调用 onFulfilled. Rejected: has-rejected, 表示解决失败,此时会调用 onRejected. Pending: unresolve, 表示待解决,既不是resolve也不是reject的状态。也就是promise对象刚被创建后的初始化状态.  Javascript Promise用法详解_javascript技巧_脚本之家 (jb51.net) 
-  
 
-  
-  函数和方法的区别 函数(function)是一段代码,需要通过名字来进行调用。它能将一些数据(函数的参数)传递进去进行处理,然后返回一些数据(函数的返回值),也可以不返回数据。 方法(method)是通过对象调用的javascript函数。也就是说,方法也是函数,只是比较特殊的函数。 当将函数和对象和写在一起时,函数(function)就变成了方法(method)。只能对象里方法形式,方法里在函数形式写法,不能对象里函数,正确写法: 结果:这是一个 this指向的问题,第一个:{m: ƒ} ,第二个:window var o={ //对象 m:function(){ //方法 console.log(this); f(); //方法里可以函数 f:function f(){ console.log(this) } } } o.m(); //对象o的m方法,this作为方法被调用,指向调用它的对象。 //作为函数调用指向window,或undefined(严格模式)
-  模块开发 -  commons js 模块化开发 exports导出 (module.exports={ … 导出方法 …}) require 导入 (const m = require(‘./路径’)) 
 
-  










