Es6对象的扩展和Class类的基础知识笔记

时间:2023-03-08 15:25:33
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