返回

手写实现 es5 继承 es6 继承

Android

手写实现 ES5 继承

在 ES5 中,可以通过构造函数、原型链、call、apply 和 bind 来实现继承。

1. 构造函数

构造函数是一种特殊的函数,它用于创建对象并初始化对象的属性和方法。在 ES5 中,构造函数通常用 new 来调用。例如:

function Person(name, age) {
  this.name = name;
  this.age = age;
}

这个构造函数创建了一个 Person 对象,并初始化了 name 和 age 属性。

2. 原型链

原型链是 JavaScript 中的一种继承机制。每个对象都有一个原型对象,原型对象也是一个对象,它包含了该对象的所有属性和方法。当一个对象访问一个不存在的属性或方法时,它会沿着原型链向上查找,直到找到该属性或方法。例如:

var person = new Person('John', 30);

console.log(person.name); // John
console.log(person.age); // 30
console.log(person.hasOwnProperty('name')); // true
console.log(person.hasOwnProperty('age')); // true
console.log(person.hasOwnProperty('toString')); // false

在这个例子中,person 对象没有 toString 方法,但是它可以访问原型对象中的 toString 方法。这是因为 Person 构造函数的原型对象具有 toString 方法。

3. call、apply 和 bind

call、apply 和 bind 都是函数调用的方法。它们允许你以不同的方式调用函数。

  • call 方法允许你指定函数的 this 值。
  • apply 方法允许你指定函数的参数。
  • bind 方法允许你创建一个新的函数,该函数的 this 值和参数都已绑定。

例如:

var person = new Person('John', 30);

function greet() {
  console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
}

greet.call(person); // Hello, my name is John and I am 30 years old.

greet.apply(person); // Hello, my name is John and I am 30 years old.

var boundGreet = greet.bind(person);

boundGreet(); // Hello, my name is John and I am 30 years old.

在这个例子中,call 和 apply 方法都用于调用 greet 函数,并将 person 对象作为 this 值。bind 方法用于创建一个新的函数 boundGreet,该函数的 this 值已绑定到 person 对象。

4. 实现 ES5 继承

可以使用构造函数、原型链、call、apply 和 bind 来实现 ES5 继承。例如:

function Person(name, age) {
  this.name = name;
  this.age = age;
}

Person.prototype.greet = function() {
  console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
};

function Student(name, age, major) {
  Person.call(this, name, age);
  this.major = major;
}

Student.prototype = Object.create(Person.prototype);
Student.prototype.constructor = Student;

Student.prototype.study = function() {
  console.log(`I am studying ${this.major}.`);
};

var student = new Student('John', 30, 'Computer Science');

student.greet(); // Hello, my name is John and I am 30 years old.
student.study(); // I am studying Computer Science.

在这个例子中,Student 构造函数使用 call 方法来调用 Person 构造函数,并将 this 值设置为 Student 对象。这使得 Student 对象继承了 Person 对象的属性和方法。Student.prototype 对象被设置为 Object.create(Person.prototype) 的结果,这使得 Student 对象的原型对象指向 Person 对象的原型对象。这使得 Student 对象可以访问 Person 对象原型对象中的所有属性和方法。Student.prototype.constructor 属性被设置为 Student,这使得 Student 对象的 constructor 属性指向 Student 构造函数。

手写实现 ES6 继承

在 ES6 中,可以通过 class 和 extends 关键字来实现继承。例如:

class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }

  greet() {
    console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
  }
}

class Student extends Person {
  constructor(name, age, major) {
    super(name, age);
    this.major = major;
  }

  study() {
    console.log(`I am studying ${this.major}.`);
  }
}

var student = new Student('John', 30, 'Computer Science');

student.greet(); // Hello, my name is John and I am 30 years old.
student.study(); // I am studying Computer Science.

在这个例子中,Student 类使用 extends 关键字来继承 Person 类。这使得 Student 类继承了 Person 类的属性和方法。Student 类还定义了一个新的属性 major 和一个新的方法 study。

总结

在 ES5 中,可以通过构造函数、原型链、call、apply 和 bind 来实现继承。在 ES6 中,可以通过 class 和 extends 关键字来实现继承。ES6 的继承语法更简单、更易于理解和使用。