20181211 - es6(Array && Object && class继承剖析 && generator和iterator原理)

Array数组(map,reduce,filter,forEach,reduceRight.some,every,find,findIndex)

  • filter过滤;
var arr1 = [24,56,88,90,5]
var arr2 = arr1.filter((item,index)=>{
    return item>30;//会将满足条件的元素添加到新数组中返回,不满足条件则过滤调
})

//模拟实现
Array.prototype.filter = function(cb){
    let result = [];
    for(let i = 0; i<this.length;i++){
        let flag = cb(this[i],i)
        if(flag){
            result.push(this[i])
        }
    }
    return result;
}

复制代码
  • find 查找元素,返回结果是元素
var arr4 = [1,2,3,4]
arr4.find((item,index)=>{
    return item ==4; //满足条件就立刻返回该元素,不继续找了;没找到则最后返回undefined
})
//模拟实现
Array.prototype.find = function(cb){
    for(let i = 0 ; i< this.length;i++){
        let flag = cb(this[i],i);
        if(flag){
            return this[i]
        }
    }
    return  undefined;
}

复制代码
  • findIndex 查找索引
var arr4 = [1,2,3,4]
arr4.findIndex((item,index)=>{
    return item ==4; //满足条件就立刻返回该元素的索引,不继续找了;没找到则最后返回-1
})
//模拟实现
Array.prototype.find = function(cb){
    for(let i = 0 ; i< this.length;i++){
        let flag = cb(this[i],i);
        if(flag){
            return i ;
        }
    }
    return  -1;
}
复制代码
  • some 有一个满足条件就行,返回的布尔;
var arr4 = [1,2,3,4]
arr4.some((item,index)=>{
    return item ==4; //只要有一个满足条件就返回true,没有满足的返回false
})

Array.prototype.find = function(cb){
    for(let i = 0 ; i< this.length;i++){
        let flag = cb(this[i],i);
        if(flag){
            return true ;
        }
    }
    return  false;
}


复制代码
  • every 所有都满足条件,返回布尔
var arr4 = [1,2,3,4]
arr4.every((item,index)=>{
    return item ==4; //都满足条件就返回true,只要有一个没有满足的返回false
})
Array.prototype.find = function(cb){
    let flag = true;
    for(let i = 0 ; i< this.length;i++){
        let flag = cb(this[i],i);
        if(!flag){
            return false ;
        }
    }
    return  flag;
}

复制代码
  • map映射
  • reduce 求和
  • forEach 遍历
  • Array.from 类数组转换为数组
function print(){
    let arr = Array.from(arguments);
    
}
print(1,2,3,4)

复制代码
  • 声明一个有长度但是为空的数组并且填充;创建一个长度为1,只有一个元素的数组
var arr = Array(3);//[ <3 empty items> ]
arr.fill(1)//[1,1,1]

var ary = Array.of(3)//
console.log(ary);//[ 3 ]
复制代码

Object对象

  • 短命名,如果对象的属性名和变量名如果一样的话,可以二合一
let name ='zfpx',age=9;
let obj ={name,age}
console.log(obj);

复制代码
  • super可以调用__proto__指向的原型对象的方法
var obj1 = {age:1,getFood(){return '面包'}}
var obj3 = {
    getFood(){
        //通过super可以调用原型上的方法
        return '蔬菜'+super.getFood()
    }
}
Object.setPrototypeOf(obj3,obj1)//obj3.__proto__ = obj1
console.log(obj3.age);
console.log(obj3.getFood());
复制代码
  • Object.setProtoTyoe(a,b) 设置对象__proto__指针指向
    等价与 a.__proto__ = b; 用于继承公有属性
复制代码

-Object.assign(target,data) 合并对象

var nameObj = {name:'zfpx'};
var ageObj = {age:8};
var obj = {};
Object.assign(obj,nameObj,ageObj);
复制代码
特殊:Object.is(NaN,NaN) //true;
复制代码
  • Object.creat(obj) 用obj作为原型创建一个对象
//创建一个对象,对象的__proto__ 指向obj

//模拟实现
Object.create = function(obj){
    function Fn(){
        
    }
    Fn.prototype = obj;
    return new Fn();
}

知识点:
// .__proto__  setProtoType 和 .protoType 区别
//原型链查找是通过__proto__实现,继承是通过修改__proto__改变对象的指向的原型
//setProtoType 是修改一个对象的__proto__指向谁
//.protoType 是类的原型对象。


复制代码

class 类

  • 普通声明一个类
特点:只能通过new调用,不能通过函数调用
//定义一个类
class Parent {
    //定义构造函数;当new的时候就会调用构造函数
    constructor(name){
        //实例的私有属性
        this.name = name
    }
    //公有方法->原型上的
    getName(){
        console.log(this.name)
    }
    //静态方法 ,类调用
    static say(){
        console.log('我是人类')
    }
}
------------------------------------------上述代码转换为es5-----------------------------------------
var _createClass = function () {
    //target 目标 props数属性对象的数组
    function defineProperties(target, props) {
        //循环数组
        for (var i = 0; i < props.length; i++) {
            //取出每个属性描述器
            var descriptor = props[i];
            //可枚举 for in循环能循环出来就是可枚举
            descriptor.enumerable = descriptor.enumerable || false;
            //可配置 delete
            descriptor.configurable = true;
            //可修改
            if ("value" in descriptor) descriptor.writable = true;
            //真正的给target定义属性
            Object.defineProperty(target, descriptor.key, descriptor);
        }
    }
    //参数1是构造函数 参数二是原型上的属性 参数3是静态属性(类的属性)
    return function (Constructor, protoProps, staticProps) {
        //如果有原型属性的话
        if (protoProps) defineProperties(Constructor.prototype, protoProps);
        //类的属性
        if (staticProps) defineProperties(Constructor, staticProps);
        return Constructor;
    };
}();

//类的调用检查,参数1是类的实例 参数二是类本身
function _classCallCheck(instance, Constructor) {
    if (!(instance instanceof Constructor)) {
        //如果这个实例不是这个构造函数的实例的话,就报错,不能把一个类当成普通函数来调用,只能通过new
        throw new TypeError("Cannot call a class as a function");
    }
}

var Parent = function () {
    //定义构造函数;当new的时候就会调用构造函数
    function Parent(name) {
        //保证Parent是通过new调用的
        _classCallCheck(this, Parent);

        //实例的私有属性
        this.name = name;
    }

    //公有方法->原型上的

    _createClass(Parent, [{
        key: "getName",
        value: function getName() {
            console.log(this.name);
        }
    }],[{
        key: 'say',
        value: function say() {
            console.log('我是人类');
        }
    }]);

    return Parent;
}();


复制代码
  • es6继承:私有属性通过super执行继承过去;公有方法和静态方法通过Object.create 和Object.setProtoType方法继承
//定义一个类
class Parent {
    //定义构造函数;当new的时候就会调用构造函数
    constructor(name){
        //实例的私有属性
        this.name = name
    }
    //公有方法->原型上的
    getName(){
        console.log(this.name)
    }
    //静态方法 ,类调用
    static say(){
        console.log('我是人类')
    }
}
class Child extends Parent{
    constructor(name,age){
        //super指的是父类的构造函数
        super(name);
        this.age = age;
    }
    getAge(){
        console.log(this.age)
    }

}

------------------------------------------上述代码转换为es5-----------------------------------------
var _createClass = function () {
    function defineProperties(target, props) {
        for (var i = 0; i < props.length; i++) {
            var descriptor = props[i];
            descriptor.enumerable = descriptor.enumerable || false;
            descriptor.configurable = true;
            if ("value" in descriptor) descriptor.writable = true;
            Object.defineProperty(target, descriptor.key, descriptor);
        }
    }

    return function (Constructor, protoProps, staticProps) {
        if (protoProps) defineProperties(Constructor.prototype, protoProps);
        if (staticProps) defineProperties(Constructor, staticProps);
        return Constructor;
    };
}();

function _possibleConstructorReturn(self, call) {
    if (!self) {
        throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
    }
    return call && (typeof call === "object" || typeof call === "function") ? call : self;
}

function _inherits(subClass, superClass) {
    //如果父类不是函数,并且父类不等于null,抛出异常,父类必须是函数或者是null
    if (typeof superClass !== "function" && superClass !== null) {
        throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
    }
    //子类的构造函数重写原型,继承父类公有
    // subClass.prototype.__proto__ = superClass.prototype
    subClass.prototype = Object.create(superClass && superClass.prototype, {
        //重写constructor
        constructor: {
            value: subClass,
            enumerable: false,
            writable: true,
            configurable: true
        }
    });
    //subClass.__proto__ = superClass
    //继承静态方法
    if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
}

function _classCallCheck(instance, Constructor) {
    if (!(instance instanceof Constructor)) {
        throw new TypeError("Cannot call a class as a function");
    }
}

//定义一个类
var Parent = function () {
    //定义构造函数;当new的时候就会调用构造函数
    function Parent(name) {
        _classCallCheck(this, Parent);

        //实例的私有属性
        this.name = name;
    }

    //公有方法->原型上的


    _createClass(Parent, [{
        key: 'getName',
        value: function getName() {
            console.log(this.name);
        }
        //静态方法 ,类调用

    }], [{
        key: 'say',
        value: function say() {
            console.log('我是人类');
        }
    }]);

    return Parent;
}();

var Child = function (_Parent) {
    _inherits(Child, _Parent);

    function Child(name, age) {
        //类调用检查
        _classCallCheck(this, Child);
        //(Child.__proto__ || Object.getPrototypeOf(Child)).call(this, name)
        //Parent.call(this) 继承私有
        var _this = _possibleConstructorReturn(this, (Child.__proto__ || Object.getPrototypeOf(Child)).call(this, name));
        //super指的是父类的构造函数


        _this.age = age;
        return _this;
    }

    _createClass(Child, [{
        key: 'getAge',
        value: function getAge() {
            console.log(this.age);
        }
    }]);

    return Child;
}(Parent);

复制代码

genetator生成器和iterator迭代器

/*
    generator 生成器 和 迭代器 iterator
*   他是理解koa的基础,另外也是异步解决方案 async和await的基础;
*   生成器,用来生成迭代器;
*   迭代器,迭代器可以不停的调用nent方法 得到一个结果 {value,done},当done为true时表示迭代完成。
 */
 
 
 //es6
//生成器函数和普通的函数长的不一样
//1。* 用来描述,执行结果会返回一个迭代器,生成器可以理解为是根据yield分割成了好多小函数;
//2。执行的时候也不一样,可以暂停,yield
 function * read(books){
     console.log('start')
     for(let i = 0 ; i<books.length;i++){
        //产出;每次代码执行遇到yield就会暂停住,并且将yield后面的内容作为value返回出去
         yield books[i]
     }
     console.log('结束')
     //return '结束'
 }
let it = read(['js','node'])
let r1 = it.next();
console.log(r1)//{ value: 'js', done: false }  value就是yield后面的内容, 产出的就是这个内容
let r2 = it.next();
console.log(r2)//{ value: 'node', done: false }
let r3 = it.next();
console.log(r3)//{ value: undefined, done: true }  undefined是看执行到最后是否有返回值 没有的话value就是undefined;如果有返回值value 就是返回值{ value: '结束', done: true }

//循环自动调用
let it2 = read(['js','node'])
let result;
do{
    result = it2.next()
    console.log(result.value)
}while (!result.done)
 
 
 ------------------------------------------上述代码转换为es5-----------------------------------------
 //模拟generator实现
 //read 为生成器,用来返回一个迭代器
 function read(books){
     let index = 0;
     return {
         next(){
            //只要能取到就为false,取不到说明迭代完成,done变为true
             let done  = index == books.length;
             let value = done ?  undefined:books[index];
             index ++;
             return {done,value}
         }
     }
 }
 
//迭代器,迭代器可以不停的调用nent方法 得到一个结果 {value,done}
let it = read(['js','node']);
//it有一个方法,每次调用next都会返回一个结果 {value,done} value值,done是否迭代完成
// let r1 = it.next();
// console.log(r1);
// let r2 = it.next();
// console.log(r2);

//通过循环自动调用next

let result;
do{
    result = it.next()
    console.log(result.value)
}while (!result.done)


复制代码

es6 模块

//导出
export var name = 'zfpx';
export var age = 8;
//导入
//import {name,age} from './school.js';
import * as school from './school.js';
console.log(school.name,school.age);
---------------------------------------------------
//导出时重命名

function say(){
    console.log('say');
}
export {say as say2};
//导入时重命名

import {say2 as say3} from './school.js';

-----------------------------------------------
//默认导出
//每个模块都可以有一个默认要导出的东西 导出
export default function say(){
    console.log('say');
}
//导入

import say from './school.js';

复制代码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值