20181210-es6(let&const&解构&模版字符串原理 &展开运算符、剩余运算符运用 & 深拷贝原理 & reduce原理 & 箭头函数)...

变量声明

var 特点:
1.可以重复声明
2.不能定义常量
3.不支持块级作用域
复制代码
  • let
//1.不存在预解释 变量提升
//2.暂时性死区
//3.具备块级,同一块内不能重复声明;
 let a ={name:'xiaoming'}
 if(true){
     let a = 'xiaohong'//不同块,可以声明相同名;
 }
 console.log(a) //{name:'xiaoming'}
 
 if(true){
     let v= '20130401'
 }
 console.log(v)   //报错:v is not defined
 
 for(var i=0;i<3;i++){//i是全局的
 //闭包
     (function(i){
         setTimeout(function(){
             console.log(i)
         })
     })(i)
 }
 //用let
 for(let i = 0;i<3;i++){//i是块级的
     setTimeout(function(){
         console.log(i)
     },1000)
 }
复制代码
  • const
//不存在预解释、变量提升
//不能重复定义声明
//不能更改他的值。
//具备块级

const str = 123;
str = 3445;//报错:常量不能重新赋值

const = obj = {name:'xiaoming'}
obj.name= 'xiaohong'//可以修改;const限制的是不能给变量重新赋值,给变量的属性修改,实际并未修改内存地址。

复制代码

解构

解构就是分解一个对象的解构,可以用一种类似数组的方式定义n个变量,可以将一个数组中的值按照规则赋值过去。
解构的时候,等号两边结构类似;左边对象右边就是对象;左边数据右边也得是数组,右边还必须是一个真是存在的值;
复制代码
  • 数组、对象的简单解构赋值
var arr = [1,2,3]
var [a,b,c] = arr; // a=>1 b=>2 c=>3

var obj = {a:1,b:2}
var {a,b} = obj; //对象解构,根据key解构,a=>1,b=>2 
var {a:a1,b:b1} = obj;// 对象解构,不用key作为变量名,指定变量名;  a1=>1  b1=>2
复制代码
  • 嵌套解构赋值
var arr = [{a:1,b:2},[3,4],5]
var [{a,b},[c,d],e] = arr; //结构一样,a=1 b=2,c=3,d=4,e=5

var [obj,ary,n] = arr ; //整合起来赋值,obj= {a:1,b:2} ary=[3,4] n=5

复制代码
  • 默认赋值解构;如果能取到值就用取到的,取不到(undefined)时就用默认的值;
var obj = {a:1}
var {a,b} = obj;
console.log(b)//undefined
var {a,b=2} = obj;
console.log(b)//2

var ary = [1,,3]//ary[1] = undefined
var [a = "a", b = "b", c =new Error('C必须指定')] = ary;
console.log(a, b, c);// 1,b,3



function ajax(options){
    var method = options.method || 'get'
    var data = options.data || {}
    ...
    
}
函数声明形参利用解构赋值+默认赋值
function ajax({method='get',data={}){
    //函数传参解构赋值,相当于let了这个变量;
    console.log(method,data)
}
ajax({
    method:'get',
    data:{id:1}
})

复制代码
  • 省略赋值
var arr = [1,2,3]
var [,,j] = arr;
console.log(j)//3 只想取出数组最后一个
复制代码

模版字符串

  • 1.可以嵌套变量
  • 2.支持换行
  • 3.可带一个标签属性进行描述,因为我们希望有时候在拼接字符串的时候有自己的逻辑
var name = 'xiaoming',age = 9;
var str = `${name}今年${age}岁`
var str1= `${name}
今年${age}岁
`console.log(str)
console.log(str1)

//把老数组中的每一个元素应设为新数组中的每一个元素
var users = [{id:1,name:'zfpx1'},{id:2,name:'zfpx2'}]
var newUser = users.map(item=>{
    return `<li>${item.id}:${item.name}</li>`
})
let str = (`
    <ul>
    ${newUser}
    </ul>
`)
console.log(str)


//描述
//带标签的模版字符串就像一个函数调用
//参数:第一个参数是文本的数组,剩下的依次是模版字符串中出现的变量值;可以用剩余运算符收拢起来
//strings 文本的数组 指的是 模版字符串被变量分割出来的数组。
function desc(strings,...rest){
    let result = '';
    for(let i =0;i<rest.length;i++){
        result +=(strings[i]+rest[i])
    }
    result += strings[strings.length-1] //strings是被变量分割出来的,所以长度比rest多一个;
    return result;
}
var str = desc`${name}今年{age}岁了`
//str就是desc的返回值



面试:模版字符串(ejs等字符串模版通用原理)的原理:正则匹配-分组捕获-替换
var name = 'xiaoming',age = 9;
var tem = "${name}今年${age}岁了";
function replace(tem){
    return tem.replace(/\$\{(\w+)\}/g,function(...args){
            //args[0] 匹配到的整个串
            //args[1] 第一个分组捕获的
            return eval(args[1]);//替换匹配到的整个串
            })
}
console.log(replace(tem))

复制代码

字符串新增的方法

  • includes 是否包含
  • startsWith 是否以什么开头
  • endsWith 是否以什么结尾
  • repeat 重复多少遍,返回新的字符串
let address1 = 'http://www.baidu.com'
let address2 = 'ftp://www.baidu.com'
if(address1.startsWith('http')){
    console.log('http网址')
}else  if(address1.endsWidth('http')){
    console.log('ftp服务')
}
let filename = 'avatar.jpg';
if(filename.endsWith('jpg') || filename.endWith('png')){
    console.log('图片')
}

let str = 'zfpx'
str.includes('z')//true 包含

let str2 = str.repeat(3);// zfpxzfpxzfpx 重复三遍,返回新的字符串

复制代码

func方法(函数传参、接收参数、剩余运算符、展开运算符)

  • 默认参数:可以指定默认值,没传的话(undefined)就用默认值;指定必传参数,不传报错;解构赋值参数; function ajax(url=new Error('url不能为空'),method='get',dataType='json'){ console.log(url) console.log(method) console.log(dataType) } function ajax1({url=new Error('url不能为空'),method='get',dataType='json'}){ console.log(url) console.log(method) console.log(dataType) }

ajax('/user') ajax1({ url:'/user' })

  • 剩余操作符,函数接收参数时使用,只能作为函数的最后一个接收参数使用;
//求和
function sum(prefix,...rest){
    let n = rest.reduce((prev,next,nextIndex,origin)=>{
        return prev+next;
    })
    return prefix+n
}
sum('$',1,2,3,4)

//求平均值
function fn(...rest){
    return rest.reduce((prev,next,nextIndex,origin)=>{
        let sum = prev+next;
        if(nextIndex == origin.length-1){
            return sum/origin.length;
        }else{
            return sum;
        }
    })
}
fn(1,2,3,4)

复制代码
  • 展开运算符(浅拷贝、合并对象、函数入参)
//数组
var arr1 = [1,2,3]
var arr2 = [4,5,6]
var arr3 = [...arr1,...arr2]
var arr4 =arr1.concat(arr2)


//对象
var obj1 = {a:1,b:2}
var obj2 = {c:3,d:4}
var obj3 = {
    ...obj1,
    ...obj2
}
var obj4 = Object.assign({},obj1,obj2)
//函数入参
function sum(a,b,c){
    return a+b+c
}
sum(...arr1)

Math.max(1,2,3)
Math.max.apply(null,arr1)
Math.max(...arr1)


前端面试扩展:
//深拷贝、浅拷贝
浅拷贝:  ...展开运算符、Object.assign
深拷贝:
JSON.parse(JSON.stringify({home:{city:'beijing'}))
function deepClone(origin){
    let result;
    if(origin instanceof Array){
        result = [];
        for(let i=0;i<origin.length;i++){
            result.push(deepClone(origin[i]))
        }
    }else if(origin instanof Object){
        result  = {};
        for(let key in origin){
            result[key] = deepClone(origin[key])
        }
    }else{
        result = origin
    }
    return result;
}

//reduce 的原理
//reduce 支持两个参数:第一个参数是函数,第二个参数是初始值(不传的话默认是数组第一项)
//主要原理 就是 上一次的执行结果是下一次的初始值。
 var arr = [1,2,3,4]
 arr.reduce((prev,next,nextIndex,origin)=>{
     return prev +next
 },10)  //初始值是10,第一次调用prev是10,next是1,nextIndex是0, 最后得到的结果是20 
 
 
Array.prototype.myReduce = function(cb,initVal){
    var prev,nextIndex;
    if(typeof initVal =='undefined'){
        //没传的话,初始值是数组第一项,next的索引是1
        prev = this[0];
        nextIndex = 1;
    }else{
        //传了的话,初始值是传入的,next的索引是0
        prev = initVal;
        nextIndex = 0;
    }
    for(var j = nextIndex;j<this.length;j++){
        prev = cb(prev,this[j],j,this)//执行结果是下一次的初始值。
    }
    return prev;
}
 

复制代码

arrow箭头函数

  • this指向上一级作用域的this
  • 没有arguments
var sum = function(a,b){
    return a+b;
}
//如果只有返回值,没有函数题代码,则可以省略{}
var sum1 = (a,b)=>a+b;
sum1(1,2)

如果有且只有一个参数,可以省略小括号;
var double = num =>num*2
console.log(double(2))


//this问题,  箭头函数没有this,他会使用上级作用域的的this;


 let obj = {
    name:'zfpx',
    getName(){
        console.log(this.name)//this=>obj
    }
 }
 obj.getName()
-------
let obj2 = {
    name:'zfpx',
    getName(){
        //this=>obj
        setTimeout(function () {
            console.log(this.name)//this=>window,   undefined
        },1000)
    }
}
obj2.getName()

---
let obj3 = {
    name:'zfpx',
    getName(){
        //this=>obj
        setTimeout( ()=> {
            //箭头函数没有this,他会使用上级作用域的的this
            console.log(this.name)//this=>obj,  zfpx
        },1000)
    }
}
obj3.getName()

---
let obj4 = {
    name:'zfpx',
    getName:()=>{
        console.log(this.name,11111) //this =>window,    undefined
    }
}
obj4.getName()


//箭头函数的this是定死的,在定义时就定死了,不管在哪里调,不管谁去调,this都是定义时的外层作用域的this
var obj5 = {
    name:'zfpx',
    getName:()=>{
        console.log(this.name) //this =>window,    undefined
    }
}
var obj6 = {};
obj6.getName = obj5.getName;
obj6.getName();


复制代码
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值