首页 > web前端 > js教程 > 正文

JavaScript OOP 概念:基于类与基于原型

Mary-Kate Olsen
发布: 2024-10-20 14:34:29
原创
401 人浏览过

JavaScript OOP Concepts: Class-Based vs. Prototype-Based要撰写有关 JavaScript 面向对象编程 (OOP) 概念和原型的详细博客,我们将首先介绍一等函数 -类实例继承多态封装抽象,解释基于类的基于原型的 方法。


JavaScript 的独特之处在于它可以支持基于类的 OOP(在 ES6 中引入)和基于原型的 OOP(JavaScript 处理 OOP 的原始方式)。本博客将深入探讨关键的 OOP 概念,例如一等函数一等实例继承多态性封装抽象使用这两种方法。

1.一流的功能

在 JavaScript 中,函数是一等公民。这意味着函数可以是:

  • 分配给变量
  • 作为参数传递
  • 从其他函数返回

绝对!让我们对博客文章进行分解,以涵盖在 JavaScript 中使用函数式和基于类的方法的一流函数一流实例。这将使您在面向对象编程 (OOP) 的背景下清楚地理解这些概念。

函数式方法

示例:一等函数

// Assigning a function to a variable
const greet = function(name) {
  return `Hello, ${name}!`;
};

// Passing a function as an argument
function logGreeting(fn, name) {
  console.log(fn(name));
}

// Returning a function
function createMultiplier(multiplier) {
  return function(number) {
    return number * multiplier;
  };
}

logGreeting(greet, "John");  // Output: Hello, John!

const double = createMultiplier(2);
console.log(double(5));  // Output: 10
登录后复制
登录后复制
登录后复制

说明:

  • 函数可以像任何其他值一样存储、传递和返回,展示一流的函数

基于类的方法

虽然函数是一等公民,但我们也可以创建模仿类似行为的类。

示例:类上下文中的一流函数

class Greeter {
  constructor(name) {
    this.name = name;
  }

  greet() {
    return `Hello, ${this.name}!`;
  }
}

// Logging greeting
class Logger {
  static logGreeting(greeter) {
    console.log(greeter.greet());
  }
}

// Using classes to demonstrate first-class functions
const greeter = new Greeter("John");
Logger.logGreeting(greeter); // Output: Hello, John!
登录后复制
登录后复制
登录后复制

说明:

    Greeter 类通过封装greet 方法演示了一流的类似函数的行为,该方法可以传递给其他函数(如 logGreeting)。

2.一级实例

对象或类的实例也可以被视为

一等公民。它们可以分配给变量,作为参数传递,并存储在集合中。

像函数一样,对象或类的实例也可以被视为

一等公民。他们可以是:

  • 分配给变量
  • 作为参数传递
  • 从函数返回
  • 存储在数组等集合中

函数式方法

示例:第一类实例

// Assigning a function to a variable
const greet = function(name) {
  return `Hello, ${name}!`;
};

// Passing a function as an argument
function logGreeting(fn, name) {
  console.log(fn(name));
}

// Returning a function
function createMultiplier(multiplier) {
  return function(number) {
    return number * multiplier;
  };
}

logGreeting(greet, "John");  // Output: Hello, John!

const double = createMultiplier(2);
console.log(double(5));  // Output: 10
登录后复制
登录后复制
登录后复制

说明:

  • 这里,myCar 和 yourCar 是 Car 函数构造函数的实例。它们可以传递给函数并存储在变量中。

基于类的方法

示例:类上下文中的第一类实例

class Greeter {
  constructor(name) {
    this.name = name;
  }

  greet() {
    return `Hello, ${this.name}!`;
  }
}

// Logging greeting
class Logger {
  static logGreeting(greeter) {
    console.log(greeter.greet());
  }
}

// Using classes to demonstrate first-class functions
const greeter = new Greeter("John");
Logger.logGreeting(greeter); // Output: Hello, John!
登录后复制
登录后复制
登录后复制

说明:

  • 在此示例中,myCar 和 yourCar 是 Car 类的实例,就像函数式方法一样,它们可以传递给函数并进行操作。

3.继承

基于类的继承允许您使用extends关键字创建一个从现有类继承属性和方法的新类。

基于类的示例:

function Car(make, model) {
  this.make = make;
  this.model = model;

  this.startEngine = function() {
    console.log(`${this.make} ${this.model} engine started.`);
  };
}

const myCar = new Car("Toyota", "Corolla");
const yourCar = new Car("Tesla", "Model 3");

// Passing instance as an argument
function showCarDetails(car) {
  console.log(`Car: ${car.make} ${car.model}`);
}

showCarDetails(myCar);  // Output: Car: Toyota Corolla
登录后复制

基于原型的示例:

class Car {
  constructor(make, model) {
    this.make = make;
    this.model = model;
  }

  startEngine() {
    console.log(`${this.make} ${this.model} engine started.`);
  }
}

const myCar = new Car("Toyota", "Corolla");
const yourCar = new Car("Tesla", "Model 3");

// Passing instance as an argument
function showCarDetails(car) {
  console.log(`Car: ${car.make} ${car.model}`);
}

showCarDetails(myCar);  // Output: Car: Toyota Corolla
登录后复制

说明:

  • 基于类的继承使用extends从父类继承,而基于原型的继承使用Object.create来链接对象。

4.多态性

多态允许不同的对象定义同一方法的自己的版本,可以在父类型的对象上调用。

基于类的示例:

class Animal {
  constructor(name) {
    this.name = name;
  }

  speak() {
    console.log(`${this.name} makes a sound.`);
  }
}

class Dog extends Animal {
  speak() {
    console.log(`${this.name} barks.`);
  }
}

const myDog = new Dog("Buddy");
myDog.speak();  // Output: Buddy barks.
登录后复制

基于原型的示例:

function Animal(name) {
  this.name = name;
}

Animal.prototype.speak = function() {
  console.log(`${this.name} makes a sound.`);
};

function Dog(name) {
  Animal.call(this, name);  // Inherit properties
}

Dog.prototype = Object.create(Animal.prototype);  // Inherit methods
Dog.prototype.constructor = Dog;

Dog.prototype.speak = function() {
  console.log(`${this.name} barks.`);
};

const myDog = new Dog("Buddy");
myDog.speak();  // Output: Buddy barks.
登录后复制

说明:

  • 多态性 允许基于类和基于原型的对象定义自己的发言方法版本,同时仍然从父类型继承。

5.封装

封装涉及隐藏对象的内部细节并仅公开必要的内容。在 JavaScript 中,我们通过在 基于类的 OOP 中使用私有字段(带有 #)或在 基于原型的 OOP 中使用闭包来实现这一点。

基于类的示例:

class Animal {
  speak() {
    console.log("Animal makes a sound.");
  }
}

class Dog extends Animal {
  speak() {
    console.log("Dog barks.");
  }
}

class Cat extends Animal {
  speak() {
    console.log("Cat meows.");
  }
}

const animals = [new Dog(), new Cat()];

animals.forEach(animal => animal.speak());
// Output:
// Dog barks.
// Cat meows.
登录后复制

基于原型的示例:

function Animal() {}

Animal.prototype.speak = function() {
  console.log("Animal makes a sound.");
};

function Dog() {}

Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.speak = function() {
  console.log("Dog barks.");
};

function Cat() {}

Cat.prototype = Object.create(Animal.prototype);
Cat.prototype.speak = function() {
  console.log("Cat meows.");
};

const animals = [new Dog(), new Cat()];
animals.forEach(animal => animal.speak());
// Output:
// Dog barks.
// Cat meows.
登录后复制

说明:

  • 基于类的封装使用私有字段(ES6中引入)来隐藏数据,而基于原型的封装通过闭包实现隐私。

6.抽象

抽象隐藏复杂的逻辑,只暴露必要的细节。它可以通过抽象出内部细节并公开基本方法来实现。

基于类的示例:

// Assigning a function to a variable
const greet = function(name) {
  return `Hello, ${name}!`;
};

// Passing a function as an argument
function logGreeting(fn, name) {
  console.log(fn(name));
}

// Returning a function
function createMultiplier(multiplier) {
  return function(number) {
    return number * multiplier;
  };
}

logGreeting(greet, "John");  // Output: Hello, John!

const double = createMultiplier(2);
console.log(double(5));  // Output: 10
登录后复制
登录后复制
登录后复制

基于原型的示例:

class Greeter {
  constructor(name) {
    this.name = name;
  }

  greet() {
    return `Hello, ${this.name}!`;
  }
}

// Logging greeting
class Logger {
  static logGreeting(greeter) {
    console.log(greeter.greet());
  }
}

// Using classes to demonstrate first-class functions
const greeter = new Greeter("John");
Logger.logGreeting(greeter); // Output: Hello, John!
登录后复制
登录后复制
登录后复制

说明:

  • 这两种方法都封装了管理电池电量的复杂性,仅公开了必要的交互方法。

结论

了解 JavaScript 中基于类基于原型 OOP 之间的差异和相似之处可以增强您的编程技能。一流的函数和实例、继承、多态性、封装和抽象是基本概念,您可以利用它们来编写更清晰、更易于维护的代码。

虽然现代 基于类的 语法(在 ES6 中引入)对于来自其他 OOP 语言的开发人员来说更具可读性和熟悉性,但 基于原型 方法对于 JavaScript 来说更为基础潜在行为。

本博客演示了核心 OOP 概念 — 第一类函数第一类实例继承多态性封装抽象——两种范式都可以实现。无论您使用类还是原型,JavaScript 都提供了强大的机制,以灵活而强大的方式实现 OOP。


以上是JavaScript OOP 概念:基于类与基于原型的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:dev.to
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责声明 Sitemap
PHP中文网:公益在线PHP培训,帮助PHP学习者快速成长!