1 ES5新增的内容
forEach
概念:就是将数组循环遍历,数组中有多少项,这个函数就执行多少回
格式:真数组.forEach(function(item,index,arr){})
item是元素 index是下标 arr数组
var arr = [1, 2, 3, 4]; arr.forEach(function (item, index, arr) { console.log(item);//1 2 3 4 })
特殊例子:要是dom集合nodelist就可以直接forEach
要是遍历伪数组,就要前面加一个Array.from()转变成真数组
map
概念:跟forEach差不多,都是循环遍历,只不过多了一个返回值 return
**格式:数组.map(function(item,index,arr){})
**返回值: 一个新的数组
例子:
var arr = ['a', 'b', 'c'] //arr数组 //这个地方var newArr必须定义一个变量,返回值能被接收 var newArr = arr.map(function (item, index, arr) { return item + '11' //这个地方要添加item带着 }) console.log(newArr) // ["a11", "b11", "c11"]
filter
概念:将数组遍历一遍,然后进行筛选,按照要求进行数组里面【所有】符合内容过滤出来
格式:数组.filter(function(item,index,arr){}) 例子:var arr = [1, 2, 3, 4, 5]
var newArr = arr.filter(function (item, index, arr) { // 函数内部的三个参数和 forEach 一样 // 我们把我们的条件 return 出去 return item > 2 }) console.log(newArr) // [3, 4, 5]
find
概念:将数组遍历一遍,然后进行筛选,按照要求进行数组里面符合内容的【第一个】过滤出来
格式:数组.filter(function(item,index,arr){}) 例子:var arr = [1, 2, 3, 4, 5]
var newArr = arr.filter(function (item, index, arr) { // 函数内部的三个参数和 forEach 一样 // 我们把我们的条件 return 出去 return item > 2 }) console.log(newArr) // [3]
***find跟filter的区别:find只执行一次
eval
概念:json数据就是给对象来上‘’eval就是可以去掉那个引号 但是eval没有返回值 只能就是定义一个变量,带引号 eval("var a")
断言方法(every,some)
every概念:当判断数组里面每个元素是否都满足条件,如果全部满足,则返回true some概念:只要判断数组里面只要有一个true,则返回true 格式:数组.every/some(function(item,index,arr){}) 例子: var arr=['a','b','c'] var res = arr.every(function(item) { return item >= 'a'; }); console.log(res);
总结:当有return值的时候,一定要定义一个变量去接收
2 JSON 方法
注意:!!! var jsonObj = '{ "name": "Jack", "age": 18, "gender": "男" }' 1 必须是对象存储,不需要方法function那个匿名函数 2 里面的属性值一定要是“” “”双引号,nonono'' ''单引号 3 本质是以字符串类型存储数据
JSON.parse(方法一)
概念:将js格式字符串转换成js的对象或者数组 例子: var jsonObj = '{ "name": "Jack", "age": 18, "gender": "男" }' var obj = JSON.parse(jsonObj);//这个括号里面填写要改变的变量名 console.log(obj);//输出的是一个对象
JSON.stringify(方法二)
概念:将JSON格式的数组或者对象转换成js的字符串 例子:var arr = [ { name: 'Jack', age: 18, gender: '男' }, { name: 'Jack', age: 18, gender: '男' }, { name: 'Jack', age: 18, gender: '男' } ] var jsonObj=JSON.stringify(obj) //括号里面添加对象或者数组 console.log(jsonObj) //返回一个字符串 [{"name":"Jack","age":18,"gender":"男"},{"name":"Jack","age":18,"gender":"男"},{"name":"Jack","age":18,"gender":"男"}]
3 This 的指向问题
1 全局定义的函数直接调用,this => window //全局作用域中 console.log(this)//window a =1; console.log(this.a) //相当于window.a 1 //普通函数中 function fn(){ console.log(this) } fn()//window ---------------- 2 对象内部的方法调用,this => 调用者 var name="a" var obj ={ name:'b', fn:function () { console.log(this.name) } } obj.fn() //b var fn=obj.fn fn() //a ------------------ 3 定时器的处理函数,this => window 01.在外部函数中将一个this存为一个变量,回调函数中使用该变量 var name = 'my name is window'; var obj = { name: 'my name is obj', fn: function () { var that = this; var timer = null; clearInterval(timer); timer = setInterval(function () { console.log(that.name); //my name is obj }, 1000) } } 02.bind返回一个新的函数,它会创建一个与原来函数主体相同的新函数,新函数中的this指向传入的对象 bind(this) var name = 'window'; var obj = { name: 'obj', fn: function () { var timer = null; clearInterval(timer); timer = setInterval(function () { console.log(this.name); //obj }.bind(this), 1000) } } 03.箭头函数没有自己的this,它的this继承自外部函数的作用域。 var name = 'my name is window'; var obj = { name: 'my name is obj', fn: function () { var timer = null; clearInterval(timer); timer = setInterval(() => { console.log(this.name); //my name is obj }, 1000) } } ---------------- 4 事件处理函数,this => 事件源 --------------- 5 自调用函数,this => window --------------- 6.闭包中的this指向window --------------- 某一个对象去借用另外对象的方法,这就是修改this指向 this很多时候是不断发生变化的,所以我们可以手动的去改变this指向
4 call 和 apply 和 bind
概念:可以忽略函数本身 改变this指向(强行改变this指向)
call
格式:函数名(要改变this指向的<名字>,要给函数传递的参数1,要给函数传递参数2,...) 例子:var obj = { name: 'Jack' } function fn(a, b) { console.log(this) console.log(a) console.log(b) } fn(1, 2) fn.call(obj, 1, 2) //第一个参数要改变的函数内部的this指向 //第二个及后面参数就是一次向函数传递参数
apply
格式:函数名.apply(要改变的 this 指向,[要给函数传递的参数1, 要给函数传递的参数2, ...]) //第二个参数传递的是一个数组 例子:var obj = { name: 'Jack' } function fn(a, b) { console.log(this) console.log(a) console.log(b) } fn(1, 2) fn.apply(obj, [1, 2]) //第一个参数要改变的函数内部的this指向 //第二个参数就是一个数组,数组里面每一项依次向函数传递的参数
bind
概念:跟call跟apply不同的是,bind不会立即执行函数调用,而是返回一个已经改变了this指向的函数 格式:var newFun=函数名.bind(要改变的this指向); newFun(传递参数); 例子:var obj = { name: 'Jack' } function fn(a, b) { console.log(this) console.log(a) console.log(b) } fn(1, 2) var newFn = fn.bind(obj) newFn(1, 2) //bind调用的时候,不会执行fn这个函数,而是返回一个新的数组 //这个新的函数就是一个改变了this指向以后的fn函数 //fn(1,2)的时候this指向window //newFun(1,2)的时候执行一个跟fn一模一样的函数,不过这个时候this指向改成了obj
5 伪数组转为真数组
三种方法: 1 静态方法Array.from(对象) => 2 Array.prototype.slice.apply/call(要改变this指向的元素)=> 3 [可迭代]的伪数组对象,可以使用[...伪数组]转化成真数组
6 严格模式
概念:将代码放在一个非常规范的范围里执行 方法用法:"use strict" 注意:1 必须要有var 声明 2 不能给只读属性赋值,不然会报错 例子:var o = Object.defineProperty({}, "foo", { value:"foo", writable:false //不可以写 }) o.foo="bar"; // TypeError: Cannot assign to read only property 'foo' console.log(o);//foo: "foo" 3 禁止this指向全局 function h() { console.log(this); // undefined } h(); 4 eval可以使用,但是打印不能在外部实现,只能在eval里面打印、
二 ES6新增内容
1 三点 ...方法
1 剩余参数 把多个参数 凝聚到集合 格式: function f(a(形参), ...arg(剩余的存储)) { console.log(arg); // [2, 3] } f(1,2,3); //当第一个数传给形参a,其他的数存到arg里面 2 展开数值 展开运算 把集合 展开成一个个的成员 例子:Math.max(...arr(展开数组的数));
...三点运算 【数组】 1 展开数组: 例子: const arr=["a","b","c"]; console.log(...arr); //a,b,c 2 插入已有的 例子: const arr=["a","b","c"]; console.log(1,...arr,10);//1,a,b,c,10 3 合并新数组 例子: const arr1=["a","b","c"]; const arr2=["d","e"] console.log(...arr1,...arr2);//a b c d e
...三点运算 【对象】 例子1: 展开对象可枚举属性 const o = { 0: "a", 1: "b", 2: "c", } console.log({...o});//{0: "a", 1: "b", 2: "c"} 例子2: 合并对象 const o = { 0: "a", 1: "b", 2: "c", } const a={ duty:"qianduan", } console.log({...o,...a}); //{0: "a", 1: "b", 2: "c", duty: "qianduan"} 其实跟数组的方法差不多,只是[]{}的区别
2 Let方法跟const方法
概念:都有块级作用域{} 外部访问不到 let 1 声明的时候可以不赋值 2 let的变量只能声明一次,不能重复 3 let 必须先声明,后赋值 const 1 声明的时候必须赋值 2 const定义的常量不能改变(不然会报错) 3 引用类型定义一般就是const
3 delete
概念:删除变量,对象属性,数组成员 如果带了var 就删除不掉. 删除的是变量名,里面的值删除不掉 例子: var arr=[1,2]; delete arr[0]; console.log(arr); =>[empty,2] 虽然删除了但是位置保留下来 *跟数组截取方法不同的是这个保留了位置,值未删掉,但是数组截取直接删除
4 解构赋值
解构:将数组或者对象,提取(解构)多个属性或元素 赋值:分别赋值给对应的变量 //注意:解构赋值跟平时赋值的方式不一样,平时赋值都是 let a(变量)=1(值),但是解构函数里面不一样,反过来 let 1(值)=a(变量);
解构赋值【数组】 例子1:先声明后赋值 var arr=[1,2] var[foo,bar]=[1,2] //foo=1,bar=2 例子2:使用剩余参数 let[foo,...args]=[1,2,3] //foo=1,args=2,3 例子3:添加默认值,默认值放在后面 let[foo,bar=2]=[1] //foo=1,bar=2
解构赋值【对象】 例子1:先声明后赋值 let a,b; => //这个地方如果没有;系统不会补全,所有要加;{}会被理解成对象,所以这个地方要用()包括表达式 ( {foo:a,bar:b}={foo:"hello",bar:"world"}; ) //这个foo值是放在左边的,变量a是放在右边的 例子2:如果变量名相同的话,简写方法 let a,b; ( {foo,bar}={foo:"hello",bar:"hello"}; ) 例子3:使用默认值 (跟数组一样) let a,b; ( {foo,bar="world"}={foo:"hello"}; )
5 模版字符串
1 反引号 `` 2 ${表达式} 注意:*支持多行 例子:`hello world` *支持嵌入式写法 例子:return `大家好,我是${this.name}` 3 例子: console.log(`1+1=${1+1}`); 1+1=2 console.log(`5>3=${5>3}`); 5>3=true console.log(`${[1,2,3]}的最大值是:${Math.max(...[1,2,3])}`); // 1,2,3的最大值是3
6箭头函数
1替代function声明 var a=function(){} => var a=()=>{} *括号里面如果形参只有一位,括号就可以直接省略 *括号里面如果超过一位,就不能省略括号 *如果function里面只有一条语句,可以直接省略{}以及return 2箭头函数和声明函数 **【箭头函数没有自己的this指向,只有借助外部的this】 **没有arguments伪数组 **箭头函数不能作为构造函数
7 迭代器
*可迭代器[Symbol.iterator] 概念:很多可迭代都是伪数组对象,但是不一定可迭代就是伪数组 只是很多伪数组对象内部自带迭代器,可以直接迭代 1 格式: const iterator={ //1必须要拥有next方法,每次迭代的时候要调用的方法 next(){ //2必须要有一个返回值 //3必须要有两个字段,done(表示是否完结true跟false)跟 value(表示本次返回的值 当done为false的时候才有意义) return{ done:false, value:1, } } } // 2、伪数组对象不一定是可迭代对象 // 伪数组对象如果没有内置迭代器(Symbol.iterator),它就不是可迭代对象 const arrayLike = { 0: 'a', 1: 'b', 2: 'c', length: 3 } // arrayLike is not iterable for (let item of arrayLike) {}
1 手动创建一个迭代器(比较重要!)
1 创建一个伪数组 const obj={ 0: 'a', 1: 'b', 2: 'c', length: 3, } 2 给伪数组创建一个迭代器 //[Symbol.iterator这个就是迭代器的意思] obj[Symbol.iterator]=function(){ //1 先定义下标 let index=0; //2开始进行返回值的运算 return { //3里面必须要有一个next方法,用来迭代返回值 next:()=> { //4 这个地方用个箭头函数好改变this指向 //5先进行判断 if(index<this.length) { //6进行返回值 return{ done:false, =>未完结 value:this[index++], } }else{ return{ done:true, =>完结 } } } } } //7开始进行遍历 for (let value of o) { console.log(value); //a,b,c }
7 for...in, for , for...of
例题: for..of与for..in的区别: 1 for … of遍历获取的是对象的键值,for … in 获取的是对象的键名 2 for … in会遍历对象的整个原型链,性能非常差不推荐使用,而for … of只遍历当前对象不会遍历原型链 3 对于数组的遍历,for … in会返回数组中所有可枚举的属性(包括原型链上可枚举的属性),for … of只返回数组的下标对应的属性值 4 **当数组要是再次手动添加属性属性值for in除了length其他都能遍历出来 例子: var a = ['A', 'B', 'C']; a.name = 'Hello'; for (var x in a) { console.log(x); // '0', '1', '2', 'name' } **而for of只能遍历它自身元素 var a = ['A', 'B', 'C']; a.name = 'Hello'; for (var x of a) { console.log(x); // 'A', 'B', 'C' } 5 for of支持break退出
1 for of 如果内置对象也有封装函数(迭代器Symbol.iterator),就是一些伪数组对象,String、arguments、dom集合(NodeList)、Map和Set 可以直接for of遍历 2 for(var item of obj)=>遍历数组的元素 3 for就是用来循环遍历