ES5和ES6我们所说的ES5和ES6其实只是js语法发展过程中的一个版本。比如我们用的最早版本的微信,是没有支付功能的。随着时间的推移,后来出现了一个版本,这个版本里面有支付功能。ECMAScript是js的语法。以前的版本没有一些功能。ES5版本增加了一些功能,ES6版本增加了一些功能,因为浏览器是浏览器厂商生产的。ECMAScript发布了新版本。未来,浏览器厂商需要让他们的浏览器支持这些功能。这个过程需要时间。所以到现在为止,基本上大部分浏览器都可以支持的比较好,但是有些浏览器还是不能全部支持。兼容性问题就出现了,所以我们在写代码的时候,一定要考虑是ES5还是ES6的方法,看浏览器是否支持ES5增加的数组方法。数组方法forEachforEach用于遍历数组,for循环遍历数组原因语法之一:Array.forEach(function(item,index,arr){})vararr=['a','b','c']//forEach是遍历数组,数组中有多少item,那么这个函数就会执行多少次arr.forEach(function(item,index,arr){//这个函数里面//item是eachiteminthearray//index是每个item对应的index//arr是原数组console.log(item)console.log(index)console.log(arr)})上面的代码相当于vararr=['a','b','c']for(vari=0;i2})console.log(newArr)//[3,4,5]新数组满是大于2的数,相当于vararr=[1,2,3,4,5]varnewArr=[]for(vari=0;我2}console.log(newArr)JSON方法json是一个特殊的字符串,本质是一个字符串varjsonObj='{"name":"Jack","age":18,"gender":"Male"}'varjsonArr='[{"name":"Jack","age":18,"gender":"Male"},{"name":"Jack","age":18,"gender":"Male"},{"name"":"Jack","age":18,"gender":"Male"}]'是对象内部用双引号包裹的字符串(必须是双引号)(必须是双引号)JSON两种方法我们有两个JSON.parseJSON.stringify的使用方法是将js对象或数组转为json格式字符串JSON.parseJSON.parse是将json格式字符串转为js对象或数组varjsonObj='{"name":"Jack","age":18,"gender":"Male"}'varjsonArr='[{"name":"Jack","age":18,"gender":"Male"},{"name":"Jack","age":18,"gender":"Male"},{"name":"Jack","age":18,"gender":"Male"}]'varobj=JSON.parse(jsonStr)vararr=JSON.parse(jsonArr)console.log(obj)console.log(arr)obj是我们的js对象arr是我们的js数组JSON.stringifyJSON。parse是将json格式的字符串转成js的对象或数组varobj={name:'Jack',age:18,gender:'male'}vararr=[{name:'Jack',age:18,性别:'男'},{姓名:'杰克',年龄:18,性别:'Male'},{name:'Jack',age:18,gender:'Male'}]varjsonObj=JSON.stringify(obj)varjsonArr=JSON.stringify(arr)console.log(jsonObj)console.log(jsonArr)jsonObj是一个json格式的对象字符串jsonArr是一个json格式的数组字符串this关键字每个函数都有一个关键字,我们可以直接使用:函数内部的this只是和函数调用方法相同与函数的定义方式无关。函数内部的this指向谁取决于调用函数的方式。直接调用全局定义的函数,this=>windowfunctionfn(){console.log(this)}fn()//此时this指向window对象内部的方法调用,this=>callervarobj={fn:function(){console.log(this)}}obj.fn()//此时this指向obj定时器处理函数,this=>windowsetTimeout(function(){console.log(this)},0)//此时定时器处理函数中的this指向窗口事件处理函数,this=>eventsourcediv.onclick=function(){console.log(this)}//当你点击div,this指向div自调用函数,this=>window(function(){console.log(this)})()//此时this指向windowcall,apply和bind,就是刚才说的是函数基本调用方法中的this指向。我们还有另外三个方法可以忽略函数本身的this指向,指向其他地方。这三个方法是call/apply/bind。强行改变this指向的方法。call方法在函数调用之后使用,函数本身的this指向语法可以忽略:函数名.call(thispointtobechanged,parameter1tobepassedtothefunction,parameter2tobepassedtothefunction,...)varobj={name:'Jack'}functionfn(a,b){console.log(this)console.log(a)console.log(b)}fn(1,2)fn.call(obj,1,2)fn(),函数里面的this指向windowfn.call(obj,1,2)此时函数内部的this指向obj。当对象使用call方法时,函数会立即执行。第一个参数是你要改变的函数内部。this指向第二个参数,参数依次传递给函数。函数调用后使用applyapply方法,函数本身的this指向语法可以忽略:函数名.apply(this指向要改变,[要传递给函数的参数1,要传递给函数的参数2函数,...])varobj={name:'Jack'}functionfn(a,b){console.log(this)console.log(a)console.log(b)}fn(1,2)fn.call(obj,[1,2])fn(),函数内部this指向windowfn.apply(obj,[1,2]),this对象使用apply方法时函数内部this指向obj执行函数的第一个参数是你要改变的函数的内部this。第二个参数是一个数组,数组中的每一项都是依次传递给函数的参数。bindbind方法在函数调用之后使用,可以忽略函数本身的this点与call/apply不同,即不会立即执行函数,而是改变了this点的函数语法:varnewFn=functionname.bind(这点要改);newFn(传递参数)varobj={name:'Jack'}functionfn(a,b){console.log(this)console.log(a)console.log(b)}fn(1,2)varnewFn=fn.bind(对象当调用)newFn(1,2)bind时,函数fn不会被执行,而是返回一个新的函数。这个新函数是一个fn函数,它将this更改为future。当fn(1,2)this指向windownewFn(1,2)时执行的函数和fn一模一样,只是里面的this点改成了objES6的新内容,之前的内容是ES5内容.接下来说说ES6let的内容我们以前都是用var关键字来声明变量,用const关键字。在ES6中,也多了两个关键字let和const来声明变量,但与var有一些区别。let和const不允许重复。Declarevariables//使用var时可以重复声明变量,但是后面会覆盖之前的varnum=100varnum=200//使用let重复声明变量时会报错letnum=100letnum=200//这里会报错//使用const重复声明变量会报错constnum=100constnum=200//这里会报错let和const声明的变量不会被解析duringpre-parsing(即没有变量提升)//因为有预解析(变量提升),前面有这个变量,但是没有赋值console.log(num)//undefinedvarnum=100//因为let不会预解析(变量提升),所以直接报错console.log(num)//undefinedletnum=100//因为const不会预解析(变量提升),所以报错直接报console.log(num)//undefinedconstnum=100leta声明的变量ndconst会被所有代码块限制//只有函数可以限制var声明的变量的范围,其他不能限制if(true){varnum=100}console.log(num)//100//变量由let声明,除了可以限制函数外,所有代码块都可以限制它们的范围(if/while/for/...)if(true){letnum=100cconsole.log(num)//100}console.log(num)//error//const声明的变量,除了函数可以限制,所有代码块都可以限制它们的范围(if/while/for/...)if(true){constnum=100console.log(num)//100}console.log(num)//let和const的区别let声明的变量的值是可以改变的,声明的变量的值byconst是不能改变的letnum=100num=200console.log(num)//200constnum=100num=200//这里会报错,因为const声明的变量值是不能改变的(我们也叫常量)声明let时不赋值,声明const时必须赋值letnumnum=100console.log(num)//100constnum//这里会报错,因为声明const时箭头函数必须赋值箭头函数是ES6中简写函数的一种语法方法重要提示:箭头函数只能简写函数表达式,不能简写声明函数functionfn(){}//不能简写constfun=function(){}//可以简写constobj={fn:function(){}//可以简写}语法:(lineparametersofthefunction)=>{codeto在函数体中执行}constfn=function(a,b){console.log(a)console.log(b)}//可以使用箭头函数写成constfun=(a,b)=>{console.log(a)console.log(b)}constobj={fn:function(a,b){console.log(a)console.log(b)}}//箭头函数可以写成constobj2={fn:(a,b)=>{console.log(a)console.log(b)}}箭头函数的特殊性箭头函数内部没有this,箭头函数的this就是上下文的this//在定义箭头函数的位置往上数,这一行可以打印出this//因为this这里是window//所以箭头函数里面的this是windowconstobj={fn:function(){console.log(this)},//这个位置是箭头函数的上一行,但是thisfun:()=>{//箭头函数里面的this是箭头函数的上一行,可以打印出this的位置console.log(this)}}obj.fn()obj.fun()根据我们之前的this指向判断,两者都应该指向obj但是因为fun是箭头函数,所以this不指向obj,但是它指向的是fun外层,也就是window箭头函数内部是没有参数的。参数集constobj={fn:function(){console.log(arguments)},fun:()=>{console.log(arguments)}}obj.fn(1,2,3)//会打印apseudo-array[1,2,3]obj.fun(1,2,3)//当函数只有一行参数不能写时会直接报错()其他情况,你mustwriteconstobj={fn:()=>{console.log('没有参数,必须写括号')},fn2:a=>{console.log('一行参数,可以不写blank写括号')},fn3:(a,b)=>{console.log('两个或多个参数必须写在括号里')}}当函数体只有一行代码时,你不需要写{},会自动返回constobj={fn:a=>{returna+10},fun:a=>a+10}console.log(fn(10))//20console.log(fun(10))//20函数传参时的默认值当我们定义一个函数的时候,有时候我们需要一个默认值来出现当我不传参数时,我使用默认值,如果我传参数,我使用传入的参数functionfn(a){a=a||10console.log(a)}fn()//不传参时,函数内的a为10fn(20)//传参20时,函数内的a为20在ES6中,我们可以直接在函数的行参数位置写默认值functionfn(a=10){console.log(a)}fn()//不传参数时,函数内部的a为10fn(20)//当传入一个参数20时,函数内部的a默认值为20箭头函数也可以使用constfn=(a=10)=>{console.log(a)}fn()//没有参数时passed,ainsidethefunctionis10fn(20)//当传入参数20时,函数内部a为20注意:如果需要使用箭头函数的默认值,还需要写()解构参数赋值,这是一种从对象或数组中快速提取成员的语法方式。Getmemberinobject//ES5方法获取对象中的成员constobj={name:'Jack',age:18,gender:'male'}letname=obj.nameletage=obj.ageletgender=obj.gender//通过解构赋值从对象中获取成员constobj={name:'Jack',age:18,gender:'Male'}//前面的{}表示我要从对象obj中获取成员//nameagegendermustbeamemberofobj//obj必须是对象let{name,age,gender}=obj解构数组快速获取数组成员//ES5方式获取数组成员constarr=['Jack','Rose','Tom']leta=arr[0]letb=arr[1]letc=arr[2]//使用解构赋值从数组中获取成员constarr=['杰克”、“罗斯”、“至m']//前面的[]表示从arr数组中获取成员//abc分别对应这个数组中的索引012//arr必须是数组let[a,b,c]=arr注意{}专门用于解构对象[]专门用于解构数组,不能混用模板字符串。在ES5中,我们在表示字符串时使用''或""。在ES6中,我们还有另外一个东西来表示字符串,就是``(backtick)letstr=`helloworld`console.log(typeofstr)//string和单引号的区别双引号反引号可以换行报错了letstr='helloworld'//下面这个是错误的letstr2='helloworld'letstr=`helloworld`console.log(str)//字符串中可以直接使用反引号拼接variables//当ES5需要字符串拼接变量时letnum=100letstr='hello'+num+'world'+numconsole.log(str)//hello100world100//直接写在字符串里不好letstr2='hellonumworldnum'console.log(str2)//hellonumworldnum//模板字符串连接变量letnum=100letstr=`hello${num}world${num}`console.log(str)//hello100world100in**$`**'中的{}用于写变量的位置。扩展运算符ES6增加了一个新的运算符……叫做扩展运算符。作用是扩充数组letarr=[1,2,3,4,5]console.log(...arr)//12345合并数组时可以用letarr=[1,2,3,4]letarr2=[...arr,5]console.log(arr2)也可以使用letobj={name:'Jack',age:18}letobj2=合并对象{...obj,gender:'male'}console.log(obj2)也可以在函数中传递参数时使用letarr=[1,2,3]functionfn(a,b,c){console.log(a)console.log(b)console.log(c)}fn(...arr)//等同于fn(1,2,3)