js es6二

…运算符

rest参数(接受剩余参数)

代码案例:

// rest参数,形式为... ,是在函数的形参中进行定义,只要定义了rest参数,那么此参数永远是个数组
// 是为了代替arguments(接收所有的实参:它是伪数组)
//1、rest 完善了arguments,并且还可以接收剩余参数 。

function fn1( ...arg ){// 接收所有的参数
    console.log( arg )
}

fn1(  )//就算没有实参,rest参数也是个数组,只不过是个空数组
fn1( 10,20 )//[ 10,20 ] 接收所有的参数

 //2、rg : 接收剩余参数 。
function fn2( a,b,...arg ){
    console.log( a,b,arg )
}

// fn2( 10,20,30,40 )
fn2( 10,20 )

扩展运算符(spread)

  • 展开数据
  • 可以直接展开数组
  • 展开对象,不可以直接展开对象,要在{}里展开。

函数传参


function fn1(a,b){
    console.log( a,b )
}

// fn1( 10,20 )
// fn1( [11,22] )//a:[11,22]  b:undefined

fn1( ...[111,222] ) //...spread参数 展开数据 //  => fn1( 111,222 )

// console.log( 1,2,2,3 )
// console.log( ...[11,22])

实现浅拷贝(展开对象或数组)

let obj1 = { a:1,b:2,c:[10,20] }
let obj2 = { ...obj1 } //实现了浅拷贝
obj1.a = 10 
obj1.c[0] = 100 //注意:因为是浅拷贝,所以obj2中的c数组也会跟着改变
console.log( obj1,'obj1' )
console.log( obj2,'obj2' )

数组合并/伪数组转数组


<button>按钮1</button><button>按钮2</button><button>按钮3</button>
<script>

//1. 数组合并: concat
//... 
// let arr1 = [ 50,40,33 ]
// let arr2 = [ 111,20 ]

let arr3 = [ ...arr1,...arr2 ] 
// console.log( arr3,'实现数组合并' )


//2. 伪数组转数组
let oBtns = document.querySelectorAll('button')

oBtns = [ ...oBtns ]
console.log( oBtns ,'转换成功 ') // Array.from  Array.prototype.slice.call( 伪数组 )
</script>

展开对象小技巧( 加薪优化 )


let persons = [
    {
        username:'张飞',
        sex:'男',
        salary:50000 
    },
    {
        username:'关羽',
        sex:'男',
        salary:60000
    }
]

let newPersons = persons.map( function(value){ 
//return { username:value.username,sex:value.sex,salary:value.salary+2000 }
    return { ...value,salary:value.salary+2000  } //每天一个涨薪小技巧
    
} )  


console.log( newPersons,'newPersons' )
console.log( persons,'persons' )

函数扩展

箭头函数基础用法

箭头函数不会更改this 指向,用来指定回调函数会非常合适,且没有function关键字,无函数名,写起来更加简洁。99%的场景是用在回调中。

特点

  • 如果形参只有一个,则小括号可以省略

  • 函数体如果只有一条语句,则花括号可以省略,函数的返回值为该条语句的执行结果

  • 箭头函数 this 指向声明时所在作用域下 this 的值 (即上一级作用域)

  • 箭头函数不能作为构造函数实例化

  • 不能使用 arguments

参数特性

没有参数、一个参数、多个参数

//es6为我们提供了箭头函数的用法 。

//1. 箭头函数没有function关键字,无函数名,写起来更加简洁。99%的场景是用在回调中。

// let fn1 = ()=>{
//     console.log('my is fn1 function')
// }

// fn1()

//2. 回忆回调的形式。
// function A( cb ){
//     cb()
// }
// function B(){
//     console.log('my is B')
// }

// A( B ) //函数B是A函数的回调,回调函数一定是在另一个函数内部执行的。

//3. 运动框架中,数组的很多函数都有回调: forEach map filter some every ...

//4. 没有参数、一个参数、多个参数
    //4.1 如果箭头函数只有一个形参,那么箭头函数的小括号可以省略。
    // let fn2 = (a)=>{
    //     console.log( a,'只有一个形参' )
    // }
    // let fn2 = a=>{
    //     console.log( a,'只有一个形参' )
    // }
    // fn2(20)
    //4.2 多个参数:无特殊说明
    // let fn3 = (a,b)=>{
    //     console.log( a,b,'多个形参' )
    // }
    // fn3( 20,30 )

返回值特性

 //5.1 完整的不省略return
    let fn4 = ()=>{
        return 20
    }
    console.log( fn4() ) //20
//5.2 省略return关键字:前提条件(函数内只有一行代码,那么可以省略return,同时也必须省略花括号)
    let fn5 = ()=> true
     console.log( fn5() )//true

//5.3 返回对象的问题,需要使用 () 解决。

    let fn6 = ()=>( { username:'zs',age:20 } )

    console.log( fn6() )//{username: 'zs', age: 20}

不做为构造函数

//1. 不做为构造函数,也就是说不能实例化
let fn1 = ()=>{

}
// new fn1()// 报错:fn1 is not a constructor

函数参数默认值

//为某个元素设置背景色,如果未背景色默认为红色

    // function setEleBgColor( ele,bgColor='blue' ){ //默认值为blue
    //     ele.style.backgroundColor = bgColor
    // }

    let setEleBgColor = (  ele,bgColor='green' )=>{//默认值为green
        ele.style.backgroundColor = bgColor
    }

    let oBtn = document.getElementById('btn')
    setEleBgColor( oBtn )
    // setEleBgColor( oBtn,'yellow' )

箭头函数没有arguments

箭头函数无arguments,使用...rest代替。
let fn2=( ...arg )=>{
    //console.log( arguments )//arguments is not defined
    console.log( arg )//[ 20,10 ]
}
fn2( 20,10 )

箭头函数的this指向(本身无this指向)


//箭头函数中的this永远指向它上级所处的this是谁。即箭头函数 this 指向声明时所在作用域下 this 的值

// 案例1
let fn1 = ()=>{
    console.log( this,'my fn1' )
}
// fn1() //window


// 案例2
// document.onclick = function(){
//     console.log( this,'事件' )//document
// }

// console.log( this,'全局' )
// document.onclick = ()=>{
//     console.log( this,'事件' )//window 此箭头函数所处在全局中,指向window
// }

// 案例3
function Person(){
    this.username = 'zs'

    let fn = ()=>{
        console.log( this,'fn函数' )
    }
    fn()
}

// Person() //this => window    window.Person()
// new Person() //this=> Person的实例对象 new 改变的是Person函数中的this指向 。
// Person.call( document ) //this = > document

//
// 案例4
let fn2 = ()=>{
    console.log( this )
}

fn2.call( document )//window

关于环境的补充


// 只能是全局或函数内才有上下文环境 。
let obj = {
    fn1:function(){
        console.log( this,'fn1' )
    },
    fn2(){
        console.log( this,'fn2' )
    },
    fn3:()=>{
        console.log( this,'fn3' )
    }
}
obj.fn1() //obj
obj.fn2() //obj
obj.fn3() //window

类class

面向对象编程

概念

面向对象是一种以对象为中心的编程思想。面向对象是相对于面向过程来讲的,面向对象把相关的数据和方法组织为一个整体来看待,从更高的层次来进行系统建模。

面向过程

面向过程思想强调的是步骤,当碰见问题时,思考的是“我该怎么做”,分析出解决问题所需要的步骤,一步步的去实现。
例如:想吃蛋炒饭,首先想到的是我要如何做,包括哪些步骤。比如:起锅烧油,加入鸡蛋,加入米饭,加入调料,翻炒,装盘等。

面向对象

面向对象思想强调的是对象,当碰见问题时,思考的是“我该让谁来做”。这个“谁”其实就是对象。找合适的对象做合适的事情。而对象如何去做(采用什么样的步骤)我们就不关心了,最终把问题解决掉就可以了。

例如:还是想吃蛋炒饭,首先想到的是让谁来帮我做蛋炒饭,比如找厨师来帮我做蛋炒饭。具体厨师如何去做这个蛋炒饭,做饭的步骤是怎么样的我们并不关心。只要最终把蛋炒饭做好就可以了。

类与对象

现实中:先有对象,再归类 。

程序中:先有类(构造函数),再有具体实例对象

  • class 声明类

  • constructor 定义构造函数初始化

  • extends 继承父类

  • super 调用父级构造里的属性和方法

  • static 定义静态方法和属性

  • 父类方法可以重写

class的基本使用

代码示例:


//class : 就是定义类的。

// 定义有属性和方法的类
class Person{ 
    username = 'zs'
    age = 20 
    say2 = ()=>{ //这叫定义了一个say2属性,里面存储了一个函数
        console.log( this) //注意箭头函数this指向
    }


    say1(){ //它会自动加到原型上。
        console.log( this )
    }
    
}

let p1 = new Person()
// console.log( p1,'p1对象' )
p1.say1() //p1
p1.say2() //p1

构造器函数方式定义属性

class Person{
    constructor( username,age ){ //实例化的时候,可以传递实参                  
        // 这是类中的固定的函数,不能手动调用,每实例化一次会调用一次
        this.uname = username 
        this.uage = age
    }

    say(){
        console.log('say方法')
    }
}

// let p1 = new Person()
// let p2 = new Person()

let p3 = new Person( 'zs',20 )
console.log( p3 ,'实例化完成')

静态属性和静态方法

代码示例1:函数模拟静态

function fn(){} //引用类型

fn.aa = '我是aa属性' //这就是静态属性

// console.log( fn.aa )
let fnObj = new fn()
console.log( fnObj.aa )//undefined

代码示例2:类中的static关键字语法

// 使用static关键字修饰静态属性或方法
    //这个属性或方法不想操作对象,那么可以用static进行修饰 
class Person{
    static a = '20'

    static fn(){
        console.log('my is fn函数')
    }
}

console.log( Person.a )
Person.fn()//'my is fn函数'

// let p1 = new Person()
// console.log( p1 );

继承

Class 可以通过extends关键字实现继承,这比 ES5 的通过修改原型链实现继承,要清晰和方便很多。

基本用法

代码案例:

//继承的原则 :1. 子类继承父类的所有特性  2. 不能影响父类

class Person{ //父类
    username =  'zs'

    say(){
        console.log('say 方法')
    }
}

    //extends : 就是继承的意思 。
class Student extends Person {
     xuehao = 'a0001'

    zuozuoye(){
        console.log( '做作业' )
    }
}


let stu1 = new Student()
// console.log(stu1.username) //zs
// stu1.say() //方法也继承了
// console.log( stu1,'学生对象' )

let p1 = new Person()
// console.log( p1 )
p1.zuozuoye()//zuozuoye is not a function : 这是对的。

super的用法

代码案例:

//完整的继承写法 。super的用法 。

class Person{ //父类
    constructor( username,age ){
        this.username = username
        this.age = age
    }
    call(){
        log('父级');
    }
}

//子类
// class Student extends Person{
//1. 子类可以不写constructor,那么实例化子类时候,实参会自动传递给父类的constructor
// }

class Student extends Person{
//2. 子类如果写constructor,那么必须在子类的constructor中的第1行写super调用 。
        
    constructor( username,age,xuehao ){
      super()//父级方法自动调用不需要传参。
      super(username,age)//必须传参调用父类的构造函数里的属性
      this.xuehao = xuehao
    }  
    //方法重写
    call(){
        log('子级');
    }
}

let stu1 = new Student( 'zs',15,'a0002' ) 
console.log( stu1 )

面向对象的应用场景

JavaScript的底层就是面向对象思想封装的。

Jquery使用原理

//https://cdn.bootcdn.net/ajax/libs/jquery/1.9.1/jquery.min.js
//$() 为jquery的对象

    // $.extend

    $.prototype.aa = 123345

let jq = $()
console.log( jq.aa ) //123345

四、iterator 迭代器

简介

Iterator是一种接口机制,为各种不同的数据结构提供统一的访问机制, 遍历器, 因为现在有Array / Object / Set / Map 4种结构, 所以ES6 加入了Iterator遍历器, 只要拥有这个Iterator遍历器, 就都可以使用for…of进行遍历

作用

  • 为各种数据结构,提供一个统一的、简便的访问接口
  • 使得数据结构的成员能够按某种次序排列
  • ES6创造了一种新的遍历命令for…of循环,Iterator接口主要供for…of使用
  • Iterator是一个抽象的概念, 具体的实现 for…of / Symbol.iterator

工作原理

  • 创建一个指针对象,指向当前数据结构的起始位置

  • 第一次调用对象的 next 方法,指针自动指向数据结构的第一个成员

  • 接下来不断调用 next 方法,指针一直往后移动,直到指向最后一个成员

  • 每调用 next 方法返回一个包含 value 和 done 属性的对象

注:需要自定义遍历数据的时候,要想到迭代器。

for…of

代码案例:

 //Iterator:迭代、遍历、循环、递归
    //for while do...while  for...in each
    //es6觉得以前遍历方式太多了。就统一了遍历方式( for...of )
    //前提条件是:数据的原型上都有 Symbol.iterator才可以使用 for...of。
    //数组、字符、arguments、set、map、元素集合。唯独没有object

    // for( let 变量 of 可遍历的数据 ){
    //     //变量就是当前的循环项
    // }

    let arr1 = [10,5,20]
    // for( let value of arr1 ){
    //     console.log( value,'--' )
    // }
    console.log( arr1,'数组身上有Symbol.iterator' )

    let set1 = new Set( [50,10,20,30,10] )
    // for( let value of set1 ){
    //     console.log( value,'--' )
    // }
    console.log( set1,'Set身上有Symbol.iterator' )
    
    let obj1 = {
        username:'zs',
        age:20
    }
    console.log( obj1,'对象身上没有Symbol.iterator' )
    // for( let value of obj1 ){
    //     //console.log( value,'--' )
    // }

注意事项:在使用for…of遍历数据时, 要确保被遍历的数据, 拥有Iterator功能

数组和Iterator

代码案例:

//分析数组身上的即可,因为每个数据身上的Symbol.itertaor都一样

let arr = [10,20,30]
// console.log( arr )
// console.log( typeof arr[Symbol.iterator] )

let iter = arr[Symbol.iterator]() //Symbol.iterator是个函数, 它返回一个(指针)对象
//console.log( iter,'这是一个指针对象' )//此对象有一个非常重要的next方法。
console.log( iter.next() )//{value: 10, done: false}
console.log( iter.next() )//{value: 20, done: false}
console.log( iter.next() )//{value: 30, done: false}
console.log( iter.next() )//{value: undefined, done: true}
//for...of 会自动调用 arr[Symbol.iterator](),再自动调用 next(),会根据done:tue的时候跳出循环。

为对象部署iterator接口

代码案例:

let obj = {
    username:'zs',
    age:20,
    sex:'男'
}
obj[ Symbol.iterator ] = function(){

    let values = Object.values( obj )
    // console.log( values,'---' )// ['zs', 20,'男']
    let index = 0 //控制数组的索引下标
                  //这里最重要的一个知识点是闭包。函数套函数,函数内部可以访问外部的变量并且不销毁

    return {
        next:function(){
            if( index >= values.length ){
                return {value: values[index++], done: true}
            }else{
                return {value: values[index++], done: false}
            }
            
        }
    }
}

for( let value of obj ){
    console.log( value,'----' )
}


// let iter = obj[ Symbol.iterator ]()
// // console.log( iter,'指针' )
// console.log( iter.next() )//{value: zs, done: false}
// console.log( iter.next() )//{value: 20, done: false}
// console.log( iter.next() )//{value: 男, done: false}
// console.log( iter.next() )//{value: undefined, done: false}

ES6~ES10总结

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值