Javascript高级-构造函数与类

✊不积跬步,无以至千里;不积小流,无以成江海。

自制一个构造函数

当想要创建一个自定义的构造函数时,可以按照以下步骤进行:

  1. 使用function关键字定义构造函数,并为构造函数选择一个合适的名称。构造函数名称通常以大写字母开头,以与普通函数区分开来。
  2. 在构造函数内部,可以定义属性和方法,这些属性和方法将成为构造函数创建的对象的特征和行为。
  3. 使用this关键字来引用当前正在创建的对象,以便设置对象的属性。
  4. 可以在构造函数的原型上定义共享的方法,这样创建的每个对象都可以访问这些方法,从而实现方法的复用。

下面是一个示例,演示如何创建一个名为Person的构造函数,用于创建具有姓名和年龄属性的人对象:

javascript 复制代码
function Person(name, age) {
  this.name = name;
  this.age = age;
}

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

// 创建 Person 对象的实例
var person1 = new Person("Alice", 25);
var person2 = new Person("Bob", 30);

// 调用实例的方法
person1.sayHello(); // 输出: Hello, my name is Alice and I am 25 years old.
person2.sayHello(); // 输出: Hello, my name is Bob and I am 30 years old.

在上面的示例中,Person构造函数接受两个参数 nameage,并使用this关键字将它们赋值给正在创建的对象的属性。然后,我们在构造函数的原型上定义了一个名为sayHello的方法,它可以在每个Person对象上被调用。通过new关键字,我们可以创建Person构造函数的实例,然后调用实例的方法。

在构造函数内部定义多个属性和方法

构造函数作为一个特殊的函数,用于创建对象,并可以在其中定义对象的初始属性和方法。

下面是一个示例,展示了构造函数内部定义多个属性和方法的方式:

javascript 复制代码
function Person(name, age) {
  this.name = name;
  this.age = age;

  // 定义构造函数内部的方法
  this.sayHello = function() {
    console.log("Hello, my name is " + this.name + " and I am " + this.age + " years old.");
  };

  // 定义构造函数内部的属性
  var country = "USA";
  this.getCountry = function() {
    return country;
  };
}

// 创建 Person 对象的实例
var person = new Person("Alice", 25);

// 调用实例的方法
person.sayHello(); // 输出: Hello, my name is Alice and I am 25 years old.

// 获取实例的属性
console.log(person.getCountry()); // 输出: USA

在上面的示例中,构造函数Person内部定义了两个属性:nameage,以及两个方法:sayHellogetCountrysayHello方法用于在控制台打印问候语,getCountry方法用于返回内部变量country的值。

在构造函数内部 定义的属性和方法将成为每个通过构造函数创建的对象的实例属性和方法。每个对象都将有自己的属性副本 ,但是方法将是共享的,因为它们都定义在构造函数的原型上。

由于属性和方法是在构造函数内部定义的,每次创建对象时都会重新定义它们。这可能会占用更多的内存,尤其是当创建大量对象时。如果这些属性和方法对每个对象都是相同的 ,更好的做法是将它们定义在构造函数的原型上,以实现方法的共享和节省内存。

隐藏属性和共有属性

隐藏属性是在构造函数内部定义的变量,无法直接通过对象实例访问。它们被称为隐藏属性,因为它们只在构造函数的作用域内可见。通常使用闭包的方式来创建隐藏属性,以提供对象的私有性。

共有属性是通过构造函数内部使用this关键字定义的属性,可以通过对象实例访问和修改。它们被称为共有属性,因为它们对于每个通过构造函数创建的对象都是可见和共享的。

下面是一个示例,展示了构造函数的隐藏属性和共有属性的不同:

javascript 复制代码
function Person(name, age) {
  // 隐藏属性
  var country = "USA";

  // 共有属性
  this.name = name;
  this.age = age;

  // 共有方法
  this.sayHello = function() {
    console.log("Hello, my name is " + this.name + " and I am " + this.age + " years old.");
  };

  // 隐藏方法
  function getCountry() {
    return country;
  }

  // 公共接口暴露隐藏方法
  this.getCountry = function() {
    return getCountry();
  };
}

// 创建 Person 对象的实例
var person = new Person("Alice", 25);

// 访问共有属性
console.log(person.name); // 输出: Alice
console.log(person.age); // 输出: 25

// 调用共有方法
person.sayHello(); // 输出: Hello, my name is Alice and I am 25 years old.

// 访问隐藏属性(无法直接访问)
console.log(person.country); // 输出: undefined

// 调用通过公共接口暴露的隐藏方法
console.log(person.getCountry()); // 输出: USA

在上面的示例中,构造函数Person内部定义了一个隐藏属性country,它无法直接通过对象实例访问。同时,构造函数通过this关键字定义了共有属性nameage,以及共有方法sayHello。隐藏方法getCountry被定义在构造函数内部,通过公共接口getCountry暴露给外部访问。

通过这种方式,隐藏属性和方法只能在构造函数的作用域 内使用,而共有属性和方法可以通过对象实例访问。这样可以实现数据的封装和隐藏,将对象的内部状态保护起来,并提供公共接口来访问和操作对象的属性和方法。

构造函数标准写法箭头函数不能当构造函数

箭头函数不能用作构造函数。箭头函数具有词法作用域绑定 ,不会创建自己的this值,而是继承外部作用域的this值。这导致箭头函数无法正确地使用new关键字创建对象。

构造函数需要使用this关键字来引用正在创建的对象,并在对象上设置属性和方法。由于箭头函数没有自己的this值,它无法正确地执行这些操作。

以下是一个示例,展示了箭头函数不能用作构造函数的情况:

ini 复制代码
// 错误的示例,箭头函数作为构造函数使用
const Person = (name, age) => {
  this.name = name; // 错误:箭头函数没有自己的this值
  this.age = age;
};

// 使用箭头函数作为构造函数创建对象
const person = new Person("Alice", 25); // 错误:TypeError: Person is not a constructor

在上面的示例中,尝试使用箭头函数Person作为构造函数来创建对象。但是,由于箭头函数没有自己的this值,this.namethis.age都无法正确地引用正在创建的对象。因此,在使用new关键字创建对象时,会抛出TypeError: Person is not a constructor错误。

如果您需要创建一个构造函数,应该使用普通的函数声明或函数表达式,而不是箭头函数。这样可以确保构造函数正确地创建对象并设置属性和方法。

class语法

使用 class 语法可以更方便地定义构造函数和原型方法,它提供了一种更简洁、易读的方式来创建对象和定义类的行为。

下面是使用 class 语法定义构造函数和原型方法的示例:

javascript 复制代码
class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }

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

// 创建 Person 类的实例
const person = new Person("Alice", 25);

// 调用实例的方法
person.sayHello(); // 输出: Hello, my name is Alice and I am 25 years old.

在上面的示例中,我们使用 class 关键字定义了一个名为 Person 的类。constructor 方法是一个特殊的方法,用于在创建对象时初始化对象的属性。在 constructor 方法内部,我们使用 this 关键字来引用正在创建的对象,并设置 nameage 属性。

类中的其他方法(如 sayHello)将被添加到类的原型上,因此所有实例都可以通过原型链继承和共享这些方法。

使用 class 语法还可以方便地定义静态方法和使用继承创建子类。以下是一个示例:

scala 复制代码
class Animal {
  constructor(name) {
    this.name = name;
  }

  static info() {
    console.log("This is an animal.");
  }
}

class Dog extends Animal {
  bark() {
    console.log("Woof!");
  }
}

const dog = new Dog("Fido");

dog.bark(); // 输出: Woof!
Dog.info(); // 输出: This is an animal.

在上面的示例中,我们定义了一个 Animal 类和一个 Dog 类作为 Animal 的子类。Animal 类的 constructor 方法设置了 name 属性,而 Dog 类添加了一个 bark 方法。

我们还在 Animal 类上定义了一个静态方法 info,可以直接通过类调用,而不需要创建实例。

静态方法

静态方法是定义在类本身上,而不是类的实例上的方法。它们在类级别上执行操作,而不依赖于特定的实例。静态方法可以通过类直接调用,而不需要创建类的实例。

以下是一个示例,展示了如何定义和使用静态方法:

javascript 复制代码
class MathUtils {
  static add(a, b) {
    return a + b;
  }

  static subtract(a, b) {
    return a - b;
  }
}

// 调用静态方法
console.log(MathUtils.add(5, 3)); // 输出: 8
console.log(MathUtils.subtract(10, 4)); // 输出: 6

在上面的示例中,我们定义了一个 MathUtils 类,并在其中定义了两个静态方法:addsubtract。这些静态方法可以直接通过类名进行调用,而不需要创建 MathUtils 类的实例。

静态方法通常用于执行与类相关的操作,例如提供实用函数、进行数据验证或执行类级别的计算 等。它们不依赖于类的实例状态或属性,因此可以在不创建实例的情况下使用。

需要注意的是,静态方法不能访问实例属性或方法,因为它们不在特定实例的上下文中执行。静态方法只能访问静态属性和其他静态方法。

相关推荐
老码沉思录1 小时前
写给初学者的React Native 全栈开发实战班
javascript·react native·react.js
我不当帕鲁谁当帕鲁1 小时前
arcgis for js实现FeatureLayer图层弹窗展示所有field字段
前端·javascript·arcgis
那一抹阳光多灿烂1 小时前
工程化实战内功修炼测试题
前端·javascript
红中马喽4 小时前
JS学习日记(webAPI—DOM)
开发语言·前端·javascript·笔记·vscode·学习
Black蜡笔小新5 小时前
网页直播/点播播放器EasyPlayer.js播放器OffscreenCanvas这个特性是否需要特殊的环境和硬件支持
前端·javascript·html
Dread_lxy6 小时前
vue 依赖注入(Provide、Inject )和混入(mixins)
前端·javascript·vue.js
奔跑草-7 小时前
【前端】深入浅出 - TypeScript 的详细讲解
前端·javascript·react.js·typescript
羡与8 小时前
echarts-gl 3D柱状图配置
前端·javascript·echarts
前端郭德纲8 小时前
浏览器是加载ES6模块的?
javascript·算法
JerryXZR8 小时前
JavaScript核心编程 - 原型链 作用域 与 执行上下文
开发语言·javascript·原型模式