对象
# 对象
# Object.is
等效于 ===
但是除了两种情况
- NaN == NaN // false Object.is(NaN,NaN) // true
- +0 == -0 // true Object.is(+0,-0) // false
# Object.setPrototypeof
Object.setPrototypeof(obj1,obj2)
表示将 obj2 设置为 obj1 的隐式原型
# Object.getOwnPropertyNames
该 Api 之前就存在,只是 ES6 对其进行了升级,将返回的属性名数组进行了排序。规则如下:
- 先排序数字 。 -- 先把数字放到前面
- 再排字母。 -- 按照原来的顺序把字母的key 放到后面
- 再排其他。 -- 。。。
# 类 (Class)
# 类的书写方式(Class 语法糖)
使用 Class关键字来声明类,使用 constructor 来定义类的构造函数。定义的函数会放到类的原型中。
Class A{
constructor(name,age){
this.name = name;
this.age = age;
}
// 方法定义,会放到 A.prototype 上,
print(){
}
}
# getter & setter
在方法名前加上 get、set 关键字来定义 getter 和 setter。
使用 getter 和 setter 控制的属性,不在原型上。
Class A{
constructor(name){
this.name = name;
}
// 使用 get 关键字定义 getter
get age(){
return this.age;
}
// 使用 set 关键字定义 setter
set age(age){
this.age = age;
}
}
getter 和 setter 的本质实际上是使用 Object.defineProperty 来定义属性的getter 和 setter,只不过是帮你封装成了一个函数。
Class A{
constructor(name){
this.name = name;
// 实质。
Object.defineProperty(this,'age',{
getter:function (){
return
},
setter:function (val){
this.age = val;
}
})
}
}
# 静态成员
构造函数本身的成员,自己的成员。
使用 static 关键字来定义。
Class A{
static a = 1;
static methods(){
}
}
A.a // 1
A.methods() //
# 字段初始化器(ES7)
- 使用 static 的字段初始化器,添加的是静态成员
- 没有使用 static 的字段初始化器,添加的成员位于对象上,即创建出来的实例每个都有。
- 箭头函数在字段初始化器位置上,指向当前对象。
Class A{
static a = 1; // 静态成员
b = 2;
c = 3;
print = () =>{
}
// 相当于 下面这种写法。
constructor(){
this.b = 2;
this.c = 3;
this.print = ()=>{} // 箭头函数的this由定义的位置决定。
}
}
# 类的继承
- extends 继承,用于类的定义
- super
- 直接当做函数使用,表示父类构造函数。
- 如果当做对象使用,则表示父类的原型。
class Person {
constructor(height, sex, weight) {
this.height = height;
this.sex = sex;
this.weight = weight;
}
print() {
console.log(`身高:${this.height}`);
console.log(`体重:${this.weight}`);
console.log(`性别:${this.sex}`);
}
}
class Chinese extends Person {
constructor(country, name, height, sex, weight) {
super(height, sex, weight);
this.country = country;
this.name = name;
}
}
var p1 = new Chinese("中国", "xiao ming", 185, "男", 140);
console.log(p1);
等同于:借用构造函数添加成员,修改子类 prototype
的隐式原型指向父类的原型对象。完成继承链。
function Person(height, sex, weight) {
this.height = height;
this.sex = sex;
this.weight = weight;
}
Person.prototype.print = function () {
console.log(`身高:${this.height}`);
console.log(`体重:${this.weight}`);
console.log(`性别:${this.sex}`);
};
function Chinese(country, name, height, sex, weight) {
Person.call(this, height, sex, weight);
this.country = country;
this.name = name;
}
Object.setPrototypeOf(Chinese.prototype, Person.prototype);
var p2 = new Chinese("中国", "xiao ming", 185, "男", 140);
console.log(p2);
如果子类中没有定义构造函数,则默认使用父类的构造函数。
class Person {
constructor(height, sex, weight) {
this.height = height;
this.sex = sex;
this.weight = weight;
}
print() {
console.log(`身高:${this.height}`);
console.log(`体重:${this.weight}`);
console.log(`性别:${this.sex}`);
}
}
class Chinese extends Person {
}
// 等同于下面的情况,表现为参数错位。!!!!!
class Chinese extends Person {
constructor(country, name, height, sex, weight) {
super(country, name, height);
}
}
重写父类的原型方法。
可以直接使用同名方法覆盖的方式全部重写父类的原型方法,也可以通过调用父类的原型方法,加以修改,得到自己的方法。
class Chinese extends Person {
constructor(country, name, height, sex, weight) {
super(height, sex, weight);
this.country = country;
this.name = name;
}
// #1
print() {
console.log(`姓名:${this.name}`);
console.log(`国籍:${this.country}`);
console.log(`身高:${this.height}`);
console.log(`体重:${this.weight}`);
console.log(`性别:${this.sex}`);
}
// #2
print() {
console.log(`姓名:${this.name}`);
console.log(`国籍:${this.country}`);
super.print();
}
}