zoukankan      html  css  js  c++  java
  • Es6对象的扩展和Class类的基础知识笔记

    /*---------------------对象的扩展---------------------*/
    //属性简写 ,属性名为变量名, 属性值为变量的值
    export default function(){
        const a='aaa';
        const b={a};
        console.info(b);//b==={a: "aaa"}
    
        function d(x,y){
            //相当于 return {x:x,y:y} //属性的简写
            return console.info({x,y})
        }
        d(1,2); //{x: 1, y: 2}
    
        const name='leyi',petName='jiucaiqiezi';
        const e={
             name,
             petName, //属性简写 petName:petName
             sayHello(){console.info({name,petName})} //函数简写
        };
        e.sayHello(); //{name: "leyi", petName: "jiucaiqiezi"}
    }
    
    //属性名表达式
    const f={};
    f.name='leyi';
    f['pet'+'name']='jiucaiqieizi';
    console.info(f); //{name: "leyi", petName: "jiucaiqiezi"}
    
    const fname='name';
    const g={
         [fname]:'leyi',
         ['pet'+'name']:'jiucaiqieizi',
         ['say'+'Hello'](){
             console.info(this.fname);
         },
    };
    console.info(g);//{name: "leyi", petName: "jiucaiqiezi"}
    g.sayHello();//表达式可以用于定义方法名
    
    //属性名表达式如果是一个对象,默认情况下会自动将对象转为字符串[object Object]
    const h={'name':'leyi'};
    const i={
        [h]:'jiucaiqiezi',
    };
    console.info(i); //{[object Object]: "jiucaiqiezi"}
    
    //Object.is  用来比较两个值是否严格相等,与严格比较运算符(===)的行为基本一致
    console.info(Object.is(+0,-0)); //false 不会转换数据类型
    
    //Object.assign方法用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target) 跟$.extend()差不多
    //如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性
    
    const j={"name":"hello"};
    const k={"petName":"jiucaiqiezi",obj:{'color':'red'}};
    //不是对象的参数会转成对象
    const l=Object.assign({"name":"leyi"},j,k,undefined,null,'wo'); //undefined和null无法转成对象,非首参数就会跳过
    console.info(l);
    //Object.assign方法实行的是浅拷贝,而不是深拷贝。如果源对象某个属性的值是对象,那么目标对象拷贝得到的是这个对象的引用
    k.obj.color='green';
    console.info(l);//{0: "w", 1: "o", name: "hello", petName: "jiucaiqiezi", obj: Object} obj{"color:green}
    //Object.assign可以用来处理数组,但是会把数组视为对象。
    console.info(Object.assign([1,2,3])); //{0:1,1:2,2:3}
    console.info(Object.assign([1,2,3],[4,5,6])); //[4, 5, 6]
    
    //属性的遍历
    //for...in循环遍历对象自身的和继承的可枚举属性
    //Object.keys(obj) 返回一个数组,包括对象自身的(不含继承的)所有可枚举属性 所以一般用Object.keys()代替for...in循环
    const m={'name':'leyi',"petName":'jiucaiqiezi'};
    console.info("Object.keys",Object.keys(m)); //["name", "petName"]
    //Object.getOwnPropertyNames 返回一个数组,包含其自身的可枚举和不可枚举属性的名称
    const n=[1,2,3,4,5];
    console.info("Object.getOwnPropertyNames",Object.getOwnPropertyNames(n)); //["0", "1", "2", "3", "4", "length"]
    
    function OParent(){
        this.pAttr=0;
    }
    function OChild(){
        this.cttr1=1;
        this.cttr2=2
    }
    OChild.prototype=new OParent();
    //该方法不会获取到原型链上的属性
    console.info(Object.getOwnPropertyNames(new OChild())); //["cttr1", "cttr2"]
    
    //Object.setPrototypeOf方法用来设置一个对象的prototype对象并返回该对象 prototype
    const proto={'petName':'jiucaiqiezi'};
    const obj={"name":'leyi'};
    Object.setPrototypeOf(obj,proto);
    console.info(obj.__proto__); //{petName: "jiucaiqiezi"}
    //getPrototypeOf用于读取一个对象的原型对象
    console.info(Object.getPrototypeOf(new OChild())); //{pAttr: 0}
    
    //Object.keys  Object.values Object.entries
    console.info(Object.keys(obj)); //["name"]
    console.info(Object.values(obj));//["leyi"]
    console.info(Object.entries(obj)); //[['name','leyi']];
    
    //通过Object.entries将对象转为map结构
    const p={'name':'leyi','petName':'jiucaiqiezi'};
    const pMap=new Map(Object.entries(p));
    console.info(pMap.size);
    const q = { one: 1, two: 2 };
    for (let [k, v] of new Map(Object.entries(q))) {
        console.info(`${k}------${v}`);
    }
    
    /*---------------------class基本语法---------------------*/
    //定义类
    //定义“类”的方法的时候,前面不需要加上function这个关键字,直接把函数定义放进去了就可以了。另外,方法之间不需要逗号分隔,加了会报错。
    class R{
      constructor(ag1,ag2){
          this.ag1=ag1;
          this.ag2=ag2;
      }
      hello(){
          return `
          ${this.ag1}
          ${this.ag2}
          `
      }
    }
    const s=new R(1,2);
    console.info(s.hello()); //1 2
    
    //类的所有方法都定义在类的prototype属性上面
    class T{
        tt(){}
        ttt(){}
    }
    //上面等同于
    T.prototype={
        tt(){},
        ttt(){},
    };
    
    //类的方法都定义在prototype对象上面,所以类的新方法可以添加在prototype对象上面。Object.assign方法可以很方便地一次向类添加多个方法
    Object.assign(T.prototype,{
        tttt(){},
        ttttt(){},
    });
    console.info(Object.getPrototypeOf(new T()));//{tt: function, ttt: function, tttt: function, ttttt: function}
    
    //constructor方法是类的默认方法,通过new命令生成对象实例时,自动调用该方法。一个类必须有constructor方法,
    // 如果没有显式定义,一个空的constructor方法会被默认添加。
    //constructor方法默认返回实例对象
    //类的所有实例共享一个原型对象
    //可以通过实例的__proto__属性为Class添加方法
    new T().__proto__.tttttt=function(){};
    console.info(Object.getPrototypeOf(new T()));//{tt: function, ttt: function, tttt: function, ttttt: function, tttttt: function}
    
    //class的继承
    //Class之间可以通过extends关键字实现继承
    class U extends R{
        constructor(ag1,ag2,name){
            super(ag1,ag2);  //super关键字,它在这里表示父类的构造函数,用来新建父类的this对象
            //this 指向当前类 super(ag1,ag2).call(this)
            this.name='leyi';
        }
        hi(){
            return this.name+'-----'+this.ag1+'-----'+this.ag2
        }
    }
    const v=new U(1,2);
    v.hi();
    console.info(v,v instanceof U,v instanceof R);//{ag1: 1, ag2: 2, name: "leyi"} true true
    
    //super作为对象时,在普通方法中,指向父类的原型对象;在静态方法中,指向父类。
    class S1{
        constructor(){
        }
        static sayhi(){
            console.info('sayhi');
        }
        sayhello(){
            console.info('sayhello');
        }
    }
    S1.attr1='attr1';
    
    class S2 extends S1{
        constructor(){
            super();
        }
        static hi(){
            super.sayhi();//super作为对象时,在静态方法中,指向父类
            console.info( super.attr1);//attr1
        }
        hello(){
            super.say1; //super作为对象时,在普通方法中,指向父类的原型对象
        }
    }
    
    new S2().hello();
    S2.hi();
    
    //Class作为构造函数的语法糖,同时有prototype属性和__proto__属性
    //子类的__proto__属性,表示构造函数的继承,总是指向父类
    //子类prototype属性的__proto__属性,表示方法的继承,总是指向父类的prototype属性。
    class W{
    }
    class X extends W{
        constructor(){
            super();
        }
    }
    console.info(X.__proto__==W,X.prototype.__proto__= W.prototype);// true true
    
    //Object.getPrototypeOf方法可以用来从子类上获取父类,也可以用来判断一个类是否继承了另一个类
    console.info(Object.getPrototypeOf(X)===W);//true X.__proto__==W
    
    //类的静态方法
    //该方法不会被实例继承,而是直接通过类来调用
    class Y{
        static method1(){
            return 'hello static!'
        }
    }
    console.info("Y.method1()------------->",Y.method1());
    
    //父类的静态方法,可以被子类继承
    class YY extends Y{
        static method2(){
            return super.method1(); //静态方法也是可以从super对象上调用
        }
    }
    console.info("YY.method1()------------->",YY.method1());
    console.info("YY.method2()------------->",YY.method2());
    
    //ES6规定Class内部只有静态方法,没有静态属性
    //class 的静态属性 静态属性指的是Class本身的属性 和实例属性
    class Z{
        //static attr0='attr0'; //Es7的提案 定义类的静态属性,目前不支持
        //attr0='attr0'; //定义类的实例属性 不支持
        constructor(){
            this.attr0='attr0';
            console.info(this.attr0);
        }
    }
    Z.attr1='attr1'; //定义类的静态属性
    console.info("new Z().attr0---->",new Z().attr0);//attr0
    
    //new.atrget 属性 返回new命令作用于的那个构造函数。如果构造函数不是通过new命令调用的,new.target会返回undefined
    
    class AA{
        constructor(){
            console.info("new.target----->",new.target===AA); //new.target-----> true
        }
    }
    new AA();
    
    //子类继承父类时,new.target会返回子类
    class AAA extends AA{
        constructor(){
            super(); //new.target-----> false
            console.info("new.target----->",new.target===AAA);//new.target-----> true
        }
    }
    new AAA();
    
    //利用这个特点,可以写出不能独立使用、必须继承后才能使用的类
    class BB{
        constructor(){
            if(new.target===BB){
                throw new Error('此类不能被实例化!');
            }
        }
    }
    class BBB extends BB{
        constructor(){
            super();
            this.name='leyi';
        }
        hello(){
            console.info("this.name----->",this.name);
        }
    }
    
    new BB(); //此类不能被实例化!
    new BBB().hello(); //this.name-----> leyi
    

      

  • 相关阅读:
    android 休眠唤醒机制分析(三) — suspend
    android 休眠唤醒机制分析(一) — wake_lock
    开机音乐不发声的问题
    Linux的时钟管理
    Android4.2增加新键值
    _IO, _IOR, _IOW, _IOWR 宏的用法与解析
    Mifare 0简介
    Mifare 1卡的存储结构
    Maven 介绍
    DAL 层引用 System.Net.Http ,引发的一阵心慌
  • 原文地址:https://www.cnblogs.com/leyi/p/6733855.html
Copyright © 2011-2022 走看看