汇总

43 阅读20分钟

1.需要注意的点:

  1. 详细了解API文档怎么编写,注重里面的格式

  2. css样式选择器的使用熟悉一下

  3. 垃圾回收机制是什么?

  4. 封装XMLHttpRequest的过程,以及理解XMLHttpRequest

提醒

  1. md5加密以后记得告诉后端,后端需要解密,否则会把加密以后的密码当作原始密码。

  2. 后端问你页码的时候,如果用到element-ui,一定告诉他需要数据的总条数

  3. 多看别人封装的形式,多学习,不要盲目按自己的方式去封装

2.易错易忘点

1.对于严格模式: 严格模式

如果将"use strict";指令添加到 JavaScript 程序的第一行,则表示整个脚本都会处于严格模式。如果在函数的第一行代码中添加"use strict";,则表示只在该函数中启用严格模式。如下例所示:

<script>
        x = 'http://c.binacheng.net/';
        console.log(x);
        function sayHello(){
            'use strict';
            str = 'welcome http://c.binacheng.net/'; // 调用 sayHello() 函数在此处报错:Uncaught ReferenceError: str is not defined at sayHello (index.html:14) at index.html:17
            console.log(str);
        }
        sayHello();
    </script>

注意:"use strict";'use strict';指令只有在整个脚本第一行或者函数第一行时才能被识别,除了 IE9 以及更低的版本外,所有的浏览器都支持该指令。

2.逻辑运算符 || 和&&

1.|| (或):

a.从左到右依次计算操作数

b.处理每一个操作数时,都将其转换为布尔值。如果是true,就停止计算,返回这个操作数发的初始值。

c.如果所有的操作数都被计算过(也就是转换结果都是false),则返回最后一个操作数。

2.&&(与)

a.从左到右一次计算操作数

b.在处理每一个操作数时,都将其装换为布尔值。如果结果是false,就停止计算,返回这个操作数的初始值。

c.如果所有的操作数都被计算过(假如都是真值),则返回最后一个操作数

总的来说就是,与运算返回第一个假值,如果没有假值就返回最后一个值

3.JS的 if 中的函数声明提升 解释

img转存失败,建议直接上传图片文件

1).if里的函数声明首先会定义一个全局同名变量a=undefined

2).if里的函数赋值会提升到块作用域顶部

3).执行到函数声明语句时,会把块作用域里的a赋值到全局同名变量a

4).基于行为诡异,不同浏览器实现不同,建议在if里用函数表达式代替函数声明

4.事件冒泡、事件捕获、事件委托

1.事件冒泡 : 当触发子元素的事件的时候, 所有的父级元素‘同名事件’都会被依次触发

元素->父元素->body->html->document->window

2.事件委托 : 给父元素注册,委托子元素处理

事件委托原理 : 事件冒泡

事件委托应用场景 :

(1)实际开发最多: 给动态新增的子元素注册事件

​ (2)性能优化 : 如果所有的子元素都需要注册同名事件,只需要给父元素注册 ​

​ 事件委托注意点 : ​

​ (1)事件委托不能通过this找到子元素。 (this指向父元素) ​

​ (2)事件委托需要通过什么属性找到子元素: e.target

3.注册捕获事件 : addEventListener() 第三个参数传true

点语法 和 addEventListener() 默认都是冒泡

4.阻止冒泡或者捕获:阻止事件流动 : 阻止冒泡 + 阻止捕获

加入 e.stopPropagation() (e是function参数)后,执行完该函数后,事件将不再捕获或冒泡。


阻止默认事件,尤其a标签常用 event.preventDefault

event.currentTarget event.target 的区别

  • event.tartget 返回的是触发事件的元素
  • event.currentTarget 返回当前绑定的事件元素

5.鼠标事件

  • mouseenter:当鼠标移入某元素时触发。鼠标只要在元素内就不再触发。

  • mouseleave:当鼠标移出某元素时触发。只是移出时触发一次;

  • mouseover:当鼠标移入某元素,移入和移出其子元素时触发。鼠标在元素内移动,只要鼠标不断在其子元素间划来划去就会不断触发。
  • mouseout:当鼠标移出某元素,移入和移出其子元素时触发。鼠标在元素内移动,只要鼠标不断在其子元素间划来划去就会不断触发。

mousemove:鼠标在某元素上移动时触发,不管是不是在其子元素上移动。

mouseout、mouseover和mouseleave、mouseenter最大的区别,在于子元素连带触发。

3.字符串、Number、数组、对象常用方法、函数扩展

1.字符串(查找、截取、其他)

(1)第一类查找

var s = 'hello world'

  • charAt(index) 方法可返回指定位置的字符。 s.charAt(3); //l
  • indexOf() 方法可返回某个指定的字符串值在字符串中首次出现的位置。 console.log(s.indexOf("o",5)); //7 indexOf(查找的值,开始的位置)
  • lastIndexOf() 方法可返回一个指定的字符串值最后出现的位置 (从后向前搜索) console.log(s.lastIndexOf("o",3)); //-1
  • includes() 方法用于判断字符串是否包含指定的子字符串,返回布尔型 console.log(s.includes("H")); //false

(2)第二类:截取

  • slice(start, end) 方法可提取字符串的某个部分,并以新的字符串返回被提取的部分 console.log(s.slice(2,6)); //llo 不包含下标6

  • substring(start,stop) 方法用于提取字符串中介于两个指定下标之间的字符 console.log(s.substring(2,6)); //llo 不包含下标

    • slice与substring区别

      当前接的参数是负数时:

      slice 会将长度与对应的负数相加,结果为参数 console.log(s.slice(3,-4)); //lo w

      substring 直接将负数转换为0 console.log(s.substring(3,0)); //参数比较,较小的作为起始位置,较大的结束位置 console.log(s.slice(-4)); // orld

      console.log(s.substring(-4)); // hello world

  • substr(start,length) 方法可在字符串中抽取从开始下标开始的指定数目的字符 console.log(s.substr(2,6)); //llo wo参考

(3)第三类:其它

  • concat() 方法用于连接两个或多个字符串。

  • split() 方法用于把一个字符串分割成字符串数组 console.log("hello:wor:ld".split(':',2)) //[ 'hello', 'wor' ]

  • replace(searchValue,newValue) 方法用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串 console.log(s.replace("hello","hi")) //hi world

  • toLowerCase() 方法用于把字符串转换为小写

  • toUpperCase() 方法用于把字符串转换为大写

  • trim() 方法用于删除字符串的头尾空格

(4)ES6扩展

let str = 'hello world'

  • includes(): 返回布尔值,表示是否找到了参数字符串。
  • startsWith(): 返回布尔值,表示参数字符串是否在原字符串的头部。 str.startsWith('hello'); //true
  • endsWith(): 返回布尔值,表示参数字符串是否在原字符串的尾部 str.endsWith('D'); //false
  • repeat(): 返回一个新字符串,表示将原字符串重复n次。'x'.repeat(3.8); // 'xxx'
  • padStart ( 指定字符串的最小长度,补全的字符串 ) : 用于头部补全 'x'.padStart(7,'abc'); //"abcabcx" 'h'.padStart(7); // ' h'
  • padEnd(): 用于尾部补全。 'x'.padEnd(7,'abc'); //"xabcabc"

2.Number

数字

var n = 10.57834;

  • toFixed() 返回字符串值,它包含了指定位数小数的数字 console.log( n.toFixed(2)); //10.58

  • toPrecision() 返回字符串值,它包含了指定长度的数字 console.log(n.toPrecision(3)); //10.6

  • toString(x)使用x为基数,把数字转换为字符串 par.toString() // 将par转化成字符串

    • String()也可以将数据转化为字符串类型 String(par) // 将par转化成字符串

    • 不同

      1.null和undefined不能调用toString,而String可以转换null和undefined,String能够将任何类型的值转换为字符串

      2.toString可以传参,表示以多少位的格式输出结果;String方法传参无效

  • parseInt() 方法 可以转化成整数(向下取整) console.log(parseInt("10 20 30")); //10 console.log(parseInt("nihao 10 years")); // NaN

  • parseFloat() 方法 可以转换成浮点型数字 console.log(parseFloat("10.57834")); //10.57834

  • Number() 方法 可以将类型转化成 数字

    • 注意 console.log(Number("hello world")); //NaN console.log(Number(null)); //0 console.log(Number(undefined)); //NaN

ES6

  • ES6中给parseInt、parseFloat放到Number方法中 :Number.parseInt('12.231') Number.parseFloat('123.3$')

  • Number.isInteger()用来判断一个数值是否为整数。 Number.isInteger(12.00); //true


    ES5

  • Math.ceil() 返回大于或等于一个给定数字的最小整数 (向上取整) Math.ceil(3.01) //4

  • Math.floor() 返回小于或等于一个给定数字的最大整数(向下取整) Math.floor(3.7) //向下取整 3

  • Math.round() 返回一个数字四舍五入后最接近的整数 (四舍五入)


    ES6

  • Math.trunc() 用于去除一个数的小数部分,返回整数部分。

    • 传入数字就是去除小数 Math.trunc(-3.0001) //-3

    • 传入非数字使用Number方法转为数值

      Math.trunc("12.12") //12 Math.trunc(true) //1 Math.trunc(undefined) //NaN

  • Math.sign() 方法用来判断一个数到底是正数、负数、还是零。对于非数值,会先将其转换为数值。 返回五种值:

    • 参数为正数,返回 1
    • 参数为负数,返回 -1
    • 为0 返回 0
    • 为-0 返回 -0 Math.sign(-0); // -0
    • 其它值 返回NaN Math.sign('') // 0

    指数运算符 (**)

    2**3 // 2*2*2

    a**=3 // a = a*a*a

3.数组

(1)第一类:添加删除

  • unshift() 方法(在开头)向数组添加新元素

  • push() 方法(在数组结尾处)向数组添加一个新的元素

  • pop() 方法从数组中删除最后一个元素

  • shift() 方法会删除首个数组元素,并把所有其他元素“位移”到更低的索引


var arr = ['red','blue','yellow','green'];

  • splice(开始位置,删除个数,要替换元素) 方法可删除从 index 处开始的零个或多个元素,并且用参数列表中声明的一个或多个值来替换那 些被删除的元素。原数组会改变。 arr.splice(1,2,'orange','black'); // 原数组:[ 'red', 'orange', 'black', 'green' ] arr.splice(1,2); //返回一个新数组[ 'red', 'green' ]
  • slice(start , end )返回一个新的数组,包含从 start 到 end (不包括该元素)的元素。原数组不会改变 console.log(arr.slice(1,3)); //['blue','yellow'] console.log(arr.slice(1,-1)); //===arr.slice(1,3)
  • concat() 方法用于连接两个或多个数组 console.log([1,2,3].concat([4,5,6])) // [ 1, 2, 3, 4, 5, 6 ]

(2)第二类:类型转换

var arr = ['red','blue','yellow','green'];

  • toString() 把数组转换为数组值(逗号分隔)的字符串。 var arr2 = arr.toString(); //red,blue,yellow,green
  • join() 方法也可将所有数组元素结合为一个字符串 console.log(arr.join(":")) //red:blue:yellow:green

(3)第三类:循环遍历

  • forEach() 方法用于调用数组的每个元素,并将元素传递给回调函数。

  • filter()对数组的每一项都运行给定的函数,返回 结果为 ture 的项组成的数组

  • map()方法通过对每个数组元素执行函数来创建新数组


  • every()对数组的每一项都运行给定的函数,每一项都返回 ture,则返回 true

  • some()方法用于检测数组中的元素是否满足指定条件,如果有一个元素满足条件,则表达式返回true , 剩 余的元素不会再执行检测, 如果没有满足条件的元素,则返回false。

  • arr.reduce((previousValue, item, index, arr) => {}, initialValue) 方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。

    • previousValue:第一次执行回调函数时,若initialValue有值,则使用initialValue,若initialValue没有值,则使用数组的第一个元素 。从第二次执行回调函数开始,每次的值都是上一次调用回调函数时的返回值
    • item:第一次执行回调函数时,若initialValue有值,则使用数组的第一个元素,之后每次执行回调函数都使用下一个数组元素。若initialValue没有值,则使用数组的第二个元素,之后每次执行回调函数都使用下一个数组元素
    • index:item在数组中的下标
    • arr:调用reduce()方法的数组
    • initialValue:【可选】初始值(若initialValue有值,则第一次调用回调函数时会传给 previousValue )
  • sort ((a,b) => { return a-b }) 排序

  • reverse() 方法用于颠倒数组中元素的顺序

(4)ES6数组扩展

  • Array.of() 定义:用于将一组值,转换为数组 Array.of(1,2,3); //[1, 2, 3]

    Array.from() 定义:用于将类数组转换为数组 Array.from('Matt') //['M','a','t','t']

  • isArray 数组校验 console.log(Array.isArray([1, 2, 3]); //true

  • copyWithin() 定义:将指定位置的成员复制到其他位置(会覆盖原有成员),然后返回当前数组(会修改当前数组)

    ​ 接受三个参数copyWithin(target, start , end)

    • target(必需):从该位置开始替换数据。如果为负值,表示倒数。[1, 2, 3, 4, 5].copyWithin(1, 3) ; //[1,4,5,4,5];
    • start(可选):从该位置开始读取数据,默认为 0。如果为负值,表示从末尾开始计算。 [1, 2, 3, 4, 5].copyWithin(1, 3, 4) ; // [1, 4, 3, 4, 5]
    • end(可选):到该位置前停止读取数据,默认等于数组长度。如果为负值,表示从末尾开始计算。 [1, 2, 3, 4, 5].copyWithin(0, -2, -1) ; // [4, 2, 3, 4, 5]
  • find(function(当前的值,当前的位置,原数组){}) find()用于找出第一个符合条件的数组成员。它的参数是一个回调函数,,所有数组成员依次执行该回调 函数,直到找出第一个返回值为true的成员,然后返回该成员。如果没有符合条件的成员,则返回 undefined。

  • findIndex() findIndex方法的用法与find方法非常类似,返回第一个符合条件的数组成员的位置,如果所有成员都不符合条件,则返回-1

  • fill(value, start, end) 定义:用于将一个固定值替换数组的元素。

    • value(必需):填充的值。

    • start(可选):开始填充位置。

    • end(可选):停止填充位置 (默认为 array.length)。

      let color2 = ["red","green","blue","yellow","orange"];
      color2.fill("hello",2); // ["red", "green", "hello", "hello", "hello"]  2以及它之后全部替换
      color2.fill("hello",2,3); // ["red", "green", "hello", "yellow", "orange"
      
  • includes() 定义:方法返回一个布尔值,表示某个数组是否包含给定的值,与字符串的 includes 方法类似 ``var arr = ["blue", "Orange", "red", "green"]; arr.includes('blue'); //true`

    • 该方法的第二个参数表示搜索的起始位置,默认为0。如果第二个参数为负数,则表示倒数的位置,如果 这时它大于数组长度(比如第二个参数为-4,但数组长度为3),则会重置为从0开始。 [1, 2, 3].includes(3, -1); // true [1, 2, 3].includes(3, 3); // false
  • flat(数字或者Infinity) 定义:用于将嵌套的数组“拉平”,变成一维的数组。

    • 不加参数只会将元素第一层是数组的元素变成最开始的元素[1,2,[3,[4,5]],[6,7]].flat() //[1,2,3,[4,5],6,7];
    • 加入参数表示第n层的元素变成最开始的元素 [1,2,[3,[4,5]],[6,7]].flat(2) //[1, 2, 3, 4, 5, 6, 7]
    • ==如果不确定几层,可以用 Infinity(意为无穷),则多维数组变成一维数组== [1,2,[3,[4,[5,[8,[9]]]]],[6,7]].flat(Infinity) //[1, 2, 3, 4, 5, 8, 9, 6, 7]

4.对象

var o = {id:1,name:"o" };

  • hasOwnProperty() 该方法可以判断对象的自有属性是否存在 console.log(o.hasOwnProperty("name")); //true 如果检测属性包含返回true,反之返回false

  • in 运算符 检测属性是否存在于某个对象中,自有属性和继承属性都返回true console.log("name" in o); //true "name"是否在o对象中

    • 区别

      in :自有属性和继承都返回true

      hasOwnProperty: 自有属性返回true,继承返回false

  • 遍历属性 for in for(var key in object) //获取键名

  • Object.keys(object) 返回一个给定对象自己的所有可枚举属性的数组 var arr2 = Object.keys(o); //["id", "name"]

  • Object.values(object) 返回一个给定对象自己的所有可枚举属性值的数组 var arr3 = Object.values(o); // values();

  • Object.entries(object) 返回一个给定对象自身可枚举属性的键值对数组 var arr3 = Object.entries(o); //[["id",1],["name":"o"]]

  • JSON.stringify() 方法是将一个JavaScript值(对象或者数组)转换为一个 JSON字符串;

  • JSON.parse() 方法用于将一个 JSON 字符串转换为对象。

  • assign(源对象,目标对象) 该方法主要用于对象的合并

  • defineProperties()直接在一个对象上定义新的属性或修改现有属性,并返回该对象。 Object.


  • object instanceof constructor //object:某个实例对象;constructor:某个构造函数 用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。

    • 语法: object instanceof constructor 检测 constructor.prototype 是否存在于参数 object 的原型链上,是则返回 true,不是则返回 false。 注:instanceof 只能用来判断对象类型,则后面一定要是对象类型,且大小写不能错。
  • Object.getPrototypeof(object)表示返回给定对象的原型。如果没有继承属性,则返回 null

    • var a = '你好'
      console.log(Object.getPrototypeOf(a) === String.prototype)  // true
      var b = 5
      console.log(Object.getPrototypeOf(b) === Number.prototype)  // true 
      var c = false
      console.log(Object.getPrototypeOf(c) === Boolean.prototype) // true 
      var d = {}
      console.log(Object.getPrototypeOf(d) === Object.prototype)  // true
      var e = null
      console.log(Object.getPrototypeOf(e))   // TypeError: Cannot convert undefined or null to object
      var f = undefined
      console.log(Object.getPrototypeOf(f))   // TypeError: Cannot convert undefined or null to object 
      var g = Symbol('g');
      Object.getPrototypeOf(g) === Symbol.prototype;  // true
      
      
  • object.isPrototypeOf(o)

    • 参数 o 任意对象。

    • 返回值: 如果object是o的原型,则返回true。如果o不是对象,或者object不是o的原 型,则返回false。

    • var o = new Object(  );                          // 创建一个对象
      Object.prototype.isPrototypeOf(o)                // true: o 是一个对象
      Function.prototype.isPrototypeOf(o.toString);    // true: toString 是一个函数
      Array.prototype.isPrototypeOf([1,2,3]);          // true: [1,2,3] 是一个数组
      
  • Object.defineProperty(参数1,参数2,参数3)是给一个对象添加属性 1.属性所在的对象 2.属性的名字 3.一个描述符对象 第三个参数除了可以是数据属性,也可以是访问器属性(四个属性,get,set,enumerable,configurable)。

    • /*描述符对象  (以下是数据类型的四个属性)
      1.configurable(可配置的):表示能否通过delete删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性,默认值为false。
      2.enumerable(枚举):表示能否通过for in循环访问属性,默认值为false
      3.writable(可写的):表示能否修改属性的值。默认值为false。
      4.value:包含这个属性的数据值。默认值为undefined。
      */
      
      var student = {};
      Object.defineProperties(student,{
          name:{
              writable:false,
              value:"lisi"
          },
          age : {
              writable:true,
              value : 16,
          },
          sex:{
              configurable:true,
              enumerable:falseget(){
                  return '男';
              },
              set(v){
                  p1.sex = v
              }
          }
      })
      p1.sex = "男";
      console.log(student.name + ":" + student.age);
      console.log(p1.sex); // 男
      student.sex = "女";
      console.log(student.sex); //男
      console.log(p1.sex); // 女
      
  • Object.defineProperties 方法直接在一个对象上定义 一个或多个 新的属性或修改现有属性

    • 该方法有 两个 Object.defineProperties(obj, props)

      • obj: 在其上定义或修改属性的对象。
      • props: 要定义其可枚举属性或修改的属性描述符的对象
    • let obj = {}
      Object.defineProperties(obj, {
          username: {
              value: '小明',
              configurable: false,
              writable: true
          },
          password: {
              value: '***',
              configurable: true,  // true可以使用delete删除,false删不掉
              enumerable: true
          }
      })
      
  • Object.create(proto[,propertiesObject]) proto 创建对象的原型,表示要继承的对象;propertiesObject(可选 ) 也是一个对象,用于对新创建的对象进行初始化

    • //创建一个Obj对象
        var Obj ={
          name:'mini',
          age:3,
          show:function () {
            console.log(this.name +" is " +this.age);
          }
        }
        //MyObj 继承obj, prototype指向Obj
        var MyObj = Object.create(Obj,{
          like:{
            value:"fish",        // 初始化赋值
            writable:true,       // 是否是可改写的
            configurable:true,   // 是否能够删除,是否能够被修改
            enumerable:true      //是否可以用for in 进行枚举
          },
          hate:{
            configurable:true,
            get:function () { console.log(111);  return "mouse" }, 
            // get对象hate属性时触发的方法
            set:function (value) {                                 
            // set对象hate属性时触发的方法 
              console.log(value,2222);
              return value;
            }    
          }
        }); 
        console.log(MyObj.age);  //3  Myobj的原型是obj,age继承自obj
      

​ ES6 扩展

  • 属性名表达式

    • var obj = {};
      obj.id = 1;
      obj['name'] = 'abc';
      obj['get'+'name'] = 'xyz';
      另一种写法
      var a = 'name';
      let obj2 = {
         [a]: 'abc',
         ['get' + a]: 'xyz'
      };
      
      
  • 链判断运算符 编程实务中,如果读取对象内部的某个属性,往往需要判断一下该对象是否存在。比如,要读取 message.body.user.firstName,安全的写法是写成下面这样。

    • // 错误的写法
       const firstName = message.body.user.firstName;
      // 正确的写法
       const firstName = (message
         && message.body
         && message.body.user
         && message.body.user.firstName) || 'default';
      
    • 这样的层层判断非常麻烦,引入了“链判断运算符” ?.,简化上面的写法。

      const firstName = message?.body?.user?.firstName || 'default';
      
    • ?.运算符常见形式,以及不使用该运算符时的等价形式。

      a?.b
       // 等同于
       a == null ? undefined : a.b
       a?.[x]
       // 等同于
       a == null ? undefined : a[x]
       a?.b()
       // 等同于
       a == null ? undefined : a.b()
       a?.()
       // 等同于
       a == null ? undefined : a()
      

5.ES6函数扩展

  • 函数默认参数

    可以在形参加入=,传递默认值

    ES5
    function fun(x,y){   
         y = y || '10';
         console.log(x,y);
    };
    fun(123);
    ES6
    function fun(x,y ="10"){   
         console.log(x,y);
    };
    fun(123);
    
  • rest参数

    ES6 引入 rest 参数(形式为 ...变量名 ),用于获取函数的多余参数,这样就不需要使用 arguments 对 象了。

    rest 参数搭配的变量是一个数组,该变量将多余的参数放入数组中。
    function fun(...values){    
         console.log(values);   //[1, 2, 3, 4, 5]
    };
    fun(1, 2, 3, 4, 5);
    获取具体参数值可以通过values[2]
    

    ==注意:==rest 参数之后不能再有其他参数(即只能是最后一个参数),否则会报错。function fun(a,...b,c){} //报错

  • 箭头函数

    如果箭头函数函数体只有一句话,那么这个句话可以不带大括号,而且这句话就是返回值(可以不用写return)

    let f = (n1,n2) => n1+n2;

    注意:如果返回一个对象,则不能直接写对象,因为 JavaScript 引擎会将{ }理解成一个代码块,从而发生语法错误。只有不将大括号写在行首,避免 JavaScript 将其解释为代码块,才能解决这个问题。

    • 必须使用圆括号括起来 let f = (n1,n2) => ({name:n1,age:n2})

    箭头函数与标准函数中的this指向

    • 在标准函数中,this引用的是把函数当成方法调用的上下文对象。
    • 在箭头函数中,this引用的是定义箭头函数的上下文

    箭头函数有几个使用注意点

    	//1、 箭头函数不能当作构造函数,不可以使用new命令
        var Fun = name =>{
            this.name = name
        };
        var f = new Fun();  //Fun is not a constructor
    
        //2、箭头函数没有原型对象
        function f(){};
        f.prototype;  //  constructor:f f()
        //ES6 箭头函数
        var f = () =>{};
        f.prototype
    
        //3、不可以使用arguments对象,替代 rest参数
        let f = () =>{
            console.log(arguments.length);  //arguments is not defined
        };
        f(1,2,3,4,5);
    
        //rest 参数
        function f(n1,n2,...value){
            return value
        };
        f(1,2,3,4,5,6);
        let f = (n1,n2,...value)=>value;
    
        //4、this指向 由于箭头函数不绑定this,它会捕获其所在上下文的this的值,作为自己的this值
    	var str = "global"; 
        var obj = {
            str: "private",
            getStr:function(){
                console.log(this);
                console.log(this.str);
            }
        };
        obj.getStr();  //this 指向 obj
        var f = obj.getStr;
        f(); // 没有调用者  this.str = window.str;  
    
        //箭头函数
        var str = "global"; 
        var obj = {
            str: "private",
            getStr:()=>{
                console.log(this);
                console.log(this.str);
            }
        };
        obj.getStr(); //先在自己所在函数上下文找this,由于箭头函数不绑定this,所以箭头函数就会通过作用域链访问外部上下文,寻找this,此时 箭头函数的外部上下文就是全局上下文(每个上下文都可以到上一级上下文中去搜索变量和函数,但任何上下文都不能通过下一级上下文中搜索)
    自己的理解:上下文是代码所处的环境,在上下文中的作用域链包含了函数和变量(函数和变量也就是变量对象)
    

4.ES6新增数据结构:Set 和 Map

方法Map(类似对象)Set(类似数组)
添加某个值,返回 Set 结构本身。(可以链式添加)set(key, value)add(value).add(value)
删除某个值,返回一个布尔值,表示删除是否成功。(不可以链式删除)delete(value)delete(value)
返回一个布尔值,表示该值是否为 Set 的成员has(key)has(value)
清除所有成员,没有返回值。clear()clear()
返回 set结构的成员总数sizesize
快速添加new Map([['name','jack'],['a',34],[{'age':69},59]]) new Set([1,3,4,'name'])
类型转换使用扩展运算符... 和Array.from()转换成数组使用扩展运算符... 和Array.from()转换成数组
循环遍历
for...of 循环可以使用的范围包括数组、Set 和 Map 结构、某些类似数组的对象(比如 arguments 对象、DOM NodeList 对象)、 Generator 对象,以及字符串。
const m1 = new Map([['a',1],['b',2],['c',3]]);
for(let k of m1.keys()){
console.log(k) // a,b,c
}
for(let v of m1.values()){
console.log(v) // 1,2,3
}
for(let [k,v] of m1){
console.log(k,v)
};
const set = new Set([2,3,52,3,4,43,3]);
for(let v of set){
console.log(v)
}
set.forEach((v,i)=>{
console.log(v) // v和i都是元素
});