对象

# 对象

# 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();
  }
}