(JavaScript)中的静态属性和静态方法、继承Object和不继承Object的区别

静态方法

class User {
     
  static staticMethod() {
     
    //在User.staticMethod()调用中的this的值是类构造器User自身
    alert(this === User);
  }
}

User.staticMethod(); // true

//上面的等同于
/*
class User { }

User.staticMethod = function() {
  alert(this === User);
};

User.staticMethod(); // true
*/
  • 通常,静态方法用于实现属于该类但不属于该类任何特定对象的函数

工厂方法

  • 我们需要通过几种方法来创建一个文章
    1.通过用给定的参数来创建(title、date等):可以使用constructor来实现
    2.使用今天的日期来创建一个空的文章:可以创建一个类的静态方法来实现
    3…其它方法
class Article {
     
  constructor(title, date) {
     
    this.title = title;
    this.date = date;
  }

  static createTodays() {
     
    // 记住 this = Article
    return new this("Today's digest", new Date());
  }
}

let article = Article.createTodays();

alert( article.title ); // Today's digest

  • 静态方法也被用于与数据库相关的公共类,可以用于搜索 / 保存 / 删除数据库中的条目
// 假定 Article 是一个用来管理文章的特殊类
// 静态方法用于移除文章:
Article.remove({
     id: 12345});

静态属性

class Article {
     
  static publisher = "Levi Ding";
}

alert( Article.publisher ); // Levi Ding

//上面的等同于:
//Article.publisher = "Levi Ding";

继承静态属性和方法

class Animal {
     
  static planet = "Earth";

  constructor(name, speed) {
     
    this.speed = speed;
    this.name = name;
  }

  run(speed = 0) {
     
    this.speed += speed;
    alert(`${
       this.name} runs with speed ${
       this.speed}.`);
  }

  static compare(animalA, animalB) {
     
    return animalA.speed - animalB.speed;
  }

}

// 继承于 Animal
class Rabbit extends Animal {
     
  hide() {
     
    alert(`${
       this.name} hides!`);
  }
}

let rabbits = [
  new Rabbit("White Rabbit", 10),
  new Rabbit("Black Rabbit", 5)
];

rabbits.sort(Rabbit.compare);

rabbits[0].run(); // Black Rabbit runs with speed 5.

alert(Rabbit.planet); // Earth

  • Rabbit函数原型继承自Animal函数
  • Rabbit.prototype原型继承自Animal.prototype
class Animal {
     }
class Rabbit extends Animal {
     }

// 对于静态的
alert(Rabbit.__proto__ === Animal); // true

// 对于常规方法
alert(Rabbit.prototype.__proto__ === Animal.prototype); // true

继承Object和不继承Object的区别

  • 不继承Object
class Rabbit {
     
  constructor(name) {
     
    this.name = name;
  }
}

let rabbit = new Rabbit("Rab");

// hasOwnProperty 方法来自于 Object.prototype
alert( rabbit.hasOwnProperty('name') ); // true
  • 继承Object
class Rabbit extends Object {
     
  constructor(name) {
     
    this.name = name;
  }
}

let rabbit = new Rabbit("Rab");

alert( rabbit.hasOwnProperty('name') ); // Error

原因解释:

  • 派生类的constructor必须调用super(),否则"this"不会定义
class Rabbit extends Object {
     
  constructor(name) {
     
    super(); // 需要在继承时调用父类的 constructor
    this.name = name;
  }
}

let rabbit = new Rabbit("Rab");

alert( rabbit.hasOwnProperty('name') ); // true

"extends" 语法会设置两个原型:

  • 在构造函数的 "prototype" 之间设置原型(为了获取实例方法)。
  • 在构造函数之间会设置原型(为了获取静态方法)。
class Rabbit extends Object {
     }

alert( Rabbit.prototype.__proto__ === Object.prototype ); // (1) true
alert( Rabbit.__proto__ === Object ); // (2) true

所以,现在 Rabbit 可以通过 Rabbit 访问 Object 的静态方法,像这样:

class Rabbit extends Object {
     }

// 通常我们调用 Object.getOwnPropertyNames
alert ( Rabbit.getOwnPropertyNames({
     a: 1, b: 2})); // a,b
  • 但是如果我们没有 extends Object,那么 Rabbit.__proto__ 将不会被设置为 Object
  • 所以,在这种情况下,Rabbit 没有提供对 Object 的静态方法的访问。
  • Function.prototype 有一些“通用”函数方法,例如 callbind 等。在上述的两种情况下它们都是可用的,因为对于内建的 Object 构造函数而言,Object.__proto__ === Function.prototype
    (JavaScript)中的静态属性和静态方法、继承Object和不继承Object的区别_第1张图片(JavaScript)中的静态属性和静态方法、继承Object和不继承Object的区别_第2张图片

你可能感兴趣的:(Javascript,相关知识点,js)