如果对象字面量初始化时,成员的名称来自于一个变量,并且和变量的名称相同,则可以进行简写
function createUser(loginId, loginPwd, nickName) {const sayHello = function () {console.log("loginId", this.loginId, "nickname", this.nickName);};return {loginId,loginPwd,nickName,sayHello,id: Math.random(),};
}
const u = createUser("abc", "123", "aaa");
对象字面初始化时,方法可以省略冒号和 function 关键字
const user = {name: "姬成",age: 100,sayHello() {console.log(this.name, this.age);},
};user.sayHello();
有的时候,初始化对象时,某些属性名可能来自于某个表达式的值,在 ES6,可以使用中括号来表示该属性名是通过计算得到的。
const prop1 = "name2";
const prop2 = "age2";
const prop3 = "sayHello2";const user = {[prop1]: "姬成",[prop2]: 100,[prop3]() {console.log(this[prop1], this[prop2]);},
};user[prop3]();console.log(user);
用于判断两个数据是否相等,基本上跟严格相等(===)是一致的,除了以下两点:
1). NaN 和 NaN 相等
2). +0 和-0 不相等
console.log(NaN === NaN); // false
console.log(+0 === -0); // trueconsole.log(Object.is(NaN, NaN)) // true
console.log(Object.is(+0, -0)) // false
2 Object.assign
用于混合对象
const obj1 = {a: 123,b: 456,c: "abc"
}const obj2 = {a: 789,d: "kkk"
}/*
{a: 789,b: 456,c: "abc",d: "kkk"
}
*///将obj2的数据,覆盖到obj1,并且会对obj1产生改动,然后返回obj1
// const obj = Object.assign(obj1, obj2);const obj = Object.assign({}, obj1, obj2);console.log(obj)
//{a: 789, b: 456, c: 'abc', d: 'kkk'}console.log(obj===obj1) //falseconsole.log(obj1) //{a: 123, b: 456, c: 'abc'}console.log(obj2) //{a: 789, d: 'kkk'}
ES6 规定了该方法返回的数组的排序方式如下:
const obj = {d: 1,b: 2,a: 3,0: 6,5: 2,4: 1,
};
const props = OwnPropertyNames(obj);
console.log(props);
//['0', '4', '5', 'd', 'b', 'a']
该函数用于设置某个对象的隐式原型
比如: Object.setPrototypeOf(obj1, obj2),
相当于: ` obj1.__proto__ = obj2 `
const obj1 = {a: 1
}const obj2 = {b: 2
}// obj1.__proto__ = obj2Object.setPrototypeOf(obj1, obj2)console.log(obj1)
// 构造函数 构造器
function Animal(type, name, age, sex) {pe = type;this.name = name;this.age = age;this.sex = sex;
}// 定义实例方法(原型方法)
Animal.prototype.print = function () {console.log(`【种类】:${pe}`);console.log(`【名字】:${this.name}`);console.log(`【年龄】:${this.age}`);console.log(`【性别】:${this.sex}`);
};const a = new Animal("狗", "旺财", 3, "男");
a.print();for (const prop in a) {console.log(prop); //原型成员可以被枚举
}
// 类对照写法
class Animal {constructor(type, name, age, sex) {pe = type;this.name = name;this.age = age;this.sex = sex;}print() {console.log(`【种类】:${pe}`);console.log(`【名字】:${this.name}`);console.log(`【年龄】:${this.age}`);console.log(`【性别】:${this.sex}`);}
}
匿名类,类表达式
const A = class { a = 1;b = 2;
}const a = new A();
console.log(a)
class Test {constructor() {this.a = 123;}print = () => {console.log(this.a)}
}const t1 = new Test();
const t2 = new Test();
console.log(t1.print === t2.print)
//false
class Test {static a = 1;b = 2;c = 3;constructor() {this.d = this.b + this.c;}
}const t = new Test();
console.log(t)//Test {b: 2, c: 3, d: 5}
const printName = "print"; //可计算的成员名class Animal {constructor(type, name, age, sex) {pe = type;this.name = name;this.age = age;this.sex = sex;}//创建一个age属性,并给它加上getter,读取该属性时,会运行该函数get age() {return this._age + "岁";}//创建一个age属性,并给它加上setter,给该属性赋值时,会运行该函数set age(age) {if (typeof age !== "number") {throw new TypeError("age property must be a number");}if (age < 0) {age = 0;} else if (age > 1000) {age = 1000;}this._age = age;}[printName]() {//可计算的成员名console.log(`【种类】:${pe}`);console.log(`【名字】:${this.name}`);console.log(`【年龄】:${this.age}`);console.log(`【性别】:${this.sex}`);}
}var a = new Animal("狗", "旺财", 3, "男");
a[printName](); //可计算的成员名Animal.abc = 123;
Object.defineProperty 可定义某个对象成员属性的读取和设置
使用 getter 和 setter 控制的属性,不在原型上
构造函数本身的成员
//静态成员与实例成员的区别
Animal.abc = 123;
const a = new Ainmal(“狗”, “旺财”, 3, “男”);
//abc 不能通过 a 来访问,只能通过构造函数的本身访问
//a 只能访问本的实例成员和原型的实例成员
使用 static 关键字定义的成员即静态成员
class Chess {constructor(name) {this.name = name;}static width = 50;static height = 50;static method() {}
}
//静态成员
console.dir(Chess);
hod();
//实例成员
const chess = new Chess();
console.dir(chess);
注意:
1). 使用 static 的字段初始化器,添加的是静态成员
2). 没有使用 static 的字段初始化器,添加的成员位于对象上
3). 箭头函数在字段初始化器位置上,指向当前对象
类表达式
[扩展]装饰器(ES7)(Decorator)
横切关注点
装饰器的本质是一个函数
5-6. 类的继承
如果两个类 A 和 B,如果可以描述为:B 是 A,则,A 和 B 形成继承关系
如果 B 是 A,则:
B 继承自 A
A 派生 B
B 是 A 的子类
A 是 B 的父类
如果 A 是 B 的父类,则 B 会自动拥有 A 中的所有实例成员。
新的关键字:
extends:继承,用于类的定义
super
直接当作函数调用,表示父类构造函数
如果当作对象使用,则表示父类的原型
注意:ES6 要求,如果定义了 constructor,并且该类是子类,则必须在 constructor 的第一行手动调用父类的构造函数
如果子类不写 constructor,则会有默认的构造器,该构造器需要的参数和父类一致,并且自动调用父类构造器
class Animal {constructor(type, name, age, sex) {pe = type;this.name = name;this.age = age;this.sex = sex;}print() {console.log(`【种类】:${pe}`);console.log(`【名字】:${this.name}`);console.log(`【年龄】:${this.age}`);console.log(`【性别】:${this.sex}`);}jiao(){throw new Error("动物怎么叫的?");}
}class Dog extends Animal {constructor(name, age, sex) {super("犬类", name, age, sex);// 子类特有的属性this.loves = "吃骨头";}print(){//调用父类的printsuper.print();//自己特有的代码console.log(`【爱好】:${this.loves}`);}//同名方法,会覆盖父类jiao(){console.log("旺旺!");}
}const d = new Dog("旺财", 3, "公");
d.print();//【种类】:犬类 【名字】:旺财 【年龄】:3 【性别】:公 【爱好】:吃骨头console.log(d)//Dog {type: '犬类', name: '旺财', age: 3, sex: '公', loves: '吃骨头'}d.jiao(); //旺旺!
class Animal {constructor(type, name, age, sex) {if (new.target === Animal) {throw new TypeError("你不能直接创建Animal的对象,应该通过子类创建")}pe = type;this.name = name;this.age = age;this.sex = sex;}print() {console.log(`【种类】:${pe}`);console.log(`【名字】:${this.name}`);console.log(`【年龄】:${this.age}`);console.log(`【性别】:${this.sex}`);}jiao() {throw new Error("动物怎么叫的?");}
}class Dog extends Animal {constructor(name, age, sex) {super("犬类", name, age, sex);// 子类特有的属性this.loves = "吃骨头";}print() {//调用父类的printsuper.print();//自己特有的代码console.log(`【爱好】:${this.loves}`);}//同名方法,会覆盖父类jiao() {console.log("旺旺!");}
}//下面的代码逻辑有误
const a = new Dog("旺财", 3, "公")
a.print();
【冷知识】
用 JS 制作抽象类
抽象类:一般是父类,不能通过该类创建对象
正常情况下,this 的指向,this 始终指向具体的类的对象
本文发布于:2024-02-02 12:26:41,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170684800243791.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |