JavaScript面向对象OOP

44 阅读2分钟

abstrict

JS中没有传统的类,使用构造函数模拟

instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上,返回 true / false

this指向所创建的类 ,因此可以使用this.属性名,创建属性

构造函数会自动 return 返回

const Animals = function (animal, food) {
  console.log(this);		//Animals()
  this.animal = animal;		//属性名可以随意定义
  this.food = food;
};

const cat = new Animals("Cat", "fish");
const dog = "Dog";
console.log(cat instanceof Animals);		//true
console.log(dog instanceof Animals);		//false

Way 2 :

class Animals {
  constructor(animal, food, birthYear) {
    this.animal = animal;
    this.food = food;
    this.birthYear = birthYear;
  }

  calAge() {
    console.log(2023 - this.birthYear);
  }
}
const dog = new Animals("dog", "bone", 2020);
dog.calAge();		//3

{ } 链接protoType

console.log(Animals.prototype);

Animals.prototype.likes = function (likes) {
  console.log("wool");
};

console.log(cat.__proto__);
console.log(cat.__proto__ === Animals.prototype); //true

console.log(Animals.prototype.isPrototypeOf(cat)); //true
console.log(Animals.prototype.isPrototypeOf(dog)); //false

console.log(cat.hasOwnProperty("animal")); //true

set 与 get,调用原型数据,进行阻挡操作

const account = {
  owner: "Chris",
  movements: [200, 530, 120, 300],
  //   number: 10,

  get latest() {
    return this.movements;
  },

  set changeNum(num) {
    return num > 10 ? alert("Good") : alert("Bad");
  },
};
console.log(account.latest);
account.changeNum = 99;

Object.create

// Object 创建
const Person = {
  init(name, birthYear) {
    this.name = name;
    this.birthYear = birthYear;
  },
  calAge(birthYear) {
    // console.log(2023 - this.birthYear);
    return 2023 - this.birthYear;
  },
};

const Chris = Object.create(Person);
// Chris.name = "Chris";
// Chris.birthYear = 2001;
Chris.init("Chris", 2001);

console.log(Chris);
console.log(Chris.calAge());
// Chris.calAge();
console.log(Chris.__proto__ === Person);

继承

const Person = function (firstName, birthYear) {
  this.firstName = firstName;
  this.birthYear = birthYear;
};

Person.prototype.calcAge = function () {
  console.log(2037 - this.birthYear);
};

const Student = function (firstName, birthYear, course) {
  //   console.log(this);
  // this 实现继承
  Person.call(this, firstName, birthYear);
  this.course = course;
};
Student.prototype.introduce = function () {
  console.log(`My name is ${this.firstName} and I study ${this.course}`);
};

// 连接原型
Student.prototype = Object.create(Person.prototype);
// Student.prototype = Person.prototype        //原型链断开
// console.log(Person.prototype);
// console.log(Student.prototype);

const Chris = new Student("Chris", 2001, "Computer");
// console.log(Chris);
Chris.calcAge();

//全部继承
// console.log(Chris instanceof Student);
// console.log(Chris instanceof Person);
// console.log(Chris instanceof Object);
console.log(Student.prototype.constructor); //Person,因为Student的原型链指向为Person
Student.prototype.constructor = Student;
console.log(Student.prototype.constructor); //Student

静态类(static)

super

访问对象字面量或类的原型([[Prototype]])上的属性,或调用父类的构造函数 ,不能用问父类的实例字段,原生属性

class Base {
  baseField = 10;
}
class Extended extends Base {
  extendedField = super.baseField; // undefined,因为缺少this(实例字段是在实例上设置的)
}

类继承与super使用

class PersonCl {
  constructor(fullName, birthYear) {
    this.fullName = fullName;
    this.birthYear = birthYear;
  }

  // static method
  static hey() {
    console.log("Hey World 👨‍👨‍👦");
  }
}

// 继承类
class studentCl extends PersonCl {
  constructor(fullName, birthYear, course) {
    super(fullName, birthYear);
    this.course = course;
  }

  introduce() {
    console.log(`My name is ${this.fullName} and I study ${this.course}`);
  }
}

const Chris = new studentCl("Chris", 2001, "Computer Science");
Chris.introduce();

封装

# == private,对变量or方法进行封装

外部调用私有方法:

  1. 浏览器报错 : Private field '#calAge' must be declared in an enclosing class

  2. vaCode报错 : Property '#calAge' is not accessible outside class 'Animals' because it has a private identifier.

class Animals {
  // public fields
  local = navigator.language;

  // private fields
  #toys = [];
  constructor(name, birthYear, food) {
    this.birthYear = birthYear;
    this.food = food;
    this.name = name;
  }

  // public methods
  calToys(toy) {
    this.#toys.push(toy);
    return this;
  }

  // private methods
  #calAge(birthYear) {
    this.birthYear = 2023 - birthYear;
  }

  outAge(birthYear) {
    this.#calAge(birthYear);
  }
}

const dog = new Animals("dog", 2012, "bone");
dog.calToys("tennis");
dog.calToys("flying disc");
console.log("public methods" + dog.calToys);
console.log("private methods" + dog.#calAge);		//报错

console.log(dog);

在这里插入图片描述

chaining链接方法

需要对与每一个方法返回this指向,否则报错,Cannot read properties of undefined

dog.calToys("shoes").outAge(2020);		//  3