JavaScript面向对象设计二 构造函数模式

JavaScript 面向对象设计二 构造函数模式

构造函数和普通函数的区别

在JavaScript中,构造函数和普通函数的区别在于函数的调用方式不同。

普通函数使用 function 声明,调用方式是 函数名()

而构造函数使用 function 声明,调用方式是使用 new 操作符来调用。

构造函数模式的基本使用方法

构造函数通常用来创建一个对象,并对对象进行初始化。

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

const person1 = new Person('张三', 18, '男');
console.log(person1); // {name: '张三', age: 18, gender: '男'}

const person2 = new Person('李四', 20, '女');
console.log(person2); // {name: '李四', age: 20, gender: '女'}

在上面的代码中,我们定义了一个构造函数 Person,它有3个参数 nameagegender。当我们使用 new 操作符来调用这个函数时,它会创建一个新的对象,并将这个对象的属性设置为传入的参数,最后返回这个新的对象。

构造函数内部的this指向

在构造函数内部,this 指向新创建的对象。

function Person(name, age, gender) {
  console.log(this); // Person {}
  this.name = name;
  this.age = age;
  this.gender = gender;
}

const person = new Person('张三', 18, '男');
console.log(person); // {name: '张三', age: 18, gender: '男'}

上面的代码中,当我们在 Person 构造函数内部使用 console.log(this) 输出 this 时,它指向一个空对象 {}。这是因为在使用 new 操作符调用 Person 函数时,它会将 this 指向一个新的空对象,然后再将这个新对象返回。

构造函数中的方法和属性

在构造函数中,我们可以定义方法和属性。方法和属性可以对创建的对象进行操作,也可以通过对象来访问和修改。

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

const person = new Person('张三', 18, '男');
console.log(person); // {name: '张三', age: 18, gender: '男'}

person.sayHello(); // Hello, my name is 张三,I am 18 years old.

在上面的代码中, Person 构造函数中定义了一个 sayHello 方法,用来打印对象的 nameage。在 person 对象上使用 sayHello() 方法时,它将输出 Hello, my name is 张三,I am 18 years old.

构造函数模式的缺陷

构造函数模式也存在一些缺陷。

  • 每个函数都有自己的方法和属性,造成内存的浪费。
  • 所有方法都得在函数内部定义,导致代码重复,不利于代码维护。

可以使用原型链模式对其进行改进。

构造函数模式和原型链模式的结合

可以将对象的方法和属性定义在构造函数的原型上,从而让所有对象共享这些方法和属性,减少代码量,提高效率。

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

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

const person = new Person('张三', 18, '男');
console.log(person); // {name: '张三', age: 18, gender: '男'}

person.sayHello(); // Hello, my name is 张三,I am 18 years old.

示例:创建一个图形对象

function Shape(x, y) {
  this.x = x;
  this.y = y;
}

Shape.prototype.move = function (x, y) {
  this.x += x;
  this.y += y;
  console.log(`Shape moved to (${this.x}, ${this.y})`);
}

function Rectangle(x, y, width, height) {
  Shape.call(this, x, y);
  this.width = width;
  this.height = height;
}

Rectangle.prototype = Object.create(Shape.prototype);
Rectangle.prototype.constructor = Rectangle;

Rectangle.prototype.draw = function() {
  console.log('Drawing a Rectangle');
}

const rect = new Rectangle(0, 0, 100, 100);
rect.move(10, 10); // Shape moved to (10, 10)
rect.draw(); // Drawing a Rectangle

在上述示例中,我们定义了一个 Shape 构造函数,它包含两个属性 xy,还有一个 move 方法。

然后我们创建了一个 Rectangle 构造函数,它继承自 Shape 构造函数,包含 widthheight 两个属性,还有一个 draw 方法。

我们使用 Object.create 方法来定义 Rectangle 构造函数的原型对象,并将其设置为 Shape.prototype。这样 Rectangle 就可以继承到 Shape 的所有方法和属性。

最后我们创建了一个 rect 对象,它调用了 movedraw 方法。

示例:创建一个按钮对象

function Button(config) {
  this.width = config.width || 150;
  this.height = config.height || 50;
  this.color = config.color || 'red';
  this.text = config.text || 'Click me!';
  this.$el = document.createElement('button');
}

Button.prototype.render = function (target) {
  this.$el.style.width = this.width + 'px';
  this.$el.style.height = this.height + 'px';
  this.$el.style.background = this.color;
  this.$el.innerHTML = this.text;
  target.appendChild(this.$el);
}

const button = new Button({ width: 200, height: 60, color: 'blue', text: 'Submit' });
button.render(document.body);

在上述示例中,我们定义了一个 Button 构造函数,它通过传入一个配置对象来设置按钮的一些属性。然后我们在构造函数中创建了一个 HTML 按钮元素,并定义了一个 render 方法将按钮元素渲染到指定的页面元素上。

最后我们创建了一个 button 对象,将它渲染到页面上。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JavaScript面向对象设计二 构造函数模式 - Python技术站

(0)
上一篇 2023年6月26日
下一篇 2023年6月26日

相关文章

  • linux系统下查看usb设备名及使用usb设备

    以下是关于Linux系统下查看USB设备名及使用USB设备的详细攻略: Linux系统下查看USB设备名 在Linux系统下,您可以使用以下命令来查看USB设备名: lsusb 该命将列出所有连接到计算机的USB设备及其详细信息,包括设备名称、供应商ID、产品ID等。 以下是一个示例输出: Bus 002 Device001: ID 1d6b:0003 Li…

    other 2023年5月7日
    00
  • package.json管理依赖包版本详解

    package.json管理依赖包版本详解 在Node.js项目中,package.json文件是用来管理项目依赖包的配置文件。通过package.json,我们可以指定项目所需的依赖包及其版本。下面是关于如何管理依赖包版本的详细攻略。 1. 创建package.json文件 首先,我们需要在项目根目录下创建一个package.json文件。可以通过以下命令…

    other 2023年8月3日
    00
  • c++如何快速清空vector以及释放vector内存?

    以下是“C++如何快速清空vector以及释放vector内存”的完整攻略: C++如何快速清空vector以及释放vector内存 在C++中,vector是一种非常常用的容器,但是在使用过程中,可能会出现需要清空vector或释放vector内存的情况。本攻略将介绍如何快速清空vector以及释放vector内存。 方法1:使用clear()函数 vec…

    other 2023年5月7日
    00
  • SpringBoot内部外部配置文件加载顺序解析

    我将详细讲解“SpringBoot内部外部配置文件加载顺序解析”的完整攻略。 SpringBoot内部外部配置文件加载顺序解析 在Spring Boot中,应用程序的配置信息可以通过内部和外部的两种方式进行加载。对于这两种方式,Spring Boot在加载时都有着不同的顺序和用途。 内部配置文件 内部配置文件是指在Spring Boot项目中,通过appli…

    other 2023年6月25日
    00
  • Python读取配置文件(config.ini)以及写入配置文件

    下面是Python读取配置文件(config.ini)以及写入配置文件的完整攻略。 读取配置文件 步骤一:安装ConfigParser模块 在Python 3.x中,ConfigParser已经被重命名为configparser。如果你想使用ConfigParser,请在代码中引入configparser而不是ConfigParser。安装ConfigPar…

    other 2023年6月25日
    00
  • js变量作用域及可访问性的探讨

    JS变量作用域及可访问性的探讨 在JavaScript中,变量的作用域和可访问性是非常重要的概念。了解这些概念可以帮助我们编写更具可维护性和可扩展性的代码。本攻略将详细讲解JavaScript中的变量作用域和可访问性,并提供两个示例来说明这些概念。 1. 变量作用域 变量作用域指的是变量在代码中的可见范围。在JavaScript中,有三种变量作用域:全局作用…

    other 2023年7月29日
    00
  • 详解jQuery lazyload 懒加载

    详解jQuery lazyload 懒加载 什么是懒加载 懒加载是一种提高网站性能的技术,在用户浏览网页时,只加载当前页面可见的部分,而不是一次性加载全部内容。这种技术能够减少页面的请求次数,节约流量,并且加速页面的加载速度。 jQuery lazyload jQuery lazyload 是一款基于 jQuery 的懒加载插件,它可以延迟加载网页中的图片、…

    other 2023年6月25日
    00
  • 固态硬盘的常用分区格式介绍以及用哪种分区格式好

    固态硬盘的常用分区格式介绍 固态硬盘常用的分区格式有主分区、扩展分区和逻辑分区,此外还有文件系统格式。 主分区 主分区是最基本的一种分区方式,一个硬盘上最多可以分出四个主分区。一般情况下,一个固态硬盘只需要一个主分区即可。 扩展分区 扩展分区是用于分出多个逻辑分区的一种特殊分区。一个硬盘上最多只能有一个扩展分区,但在扩展分区内可以分出多个逻辑分区。 逻辑分区…

    other 2023年6月27日
    00
合作推广
合作推广
分享本页
返回顶部