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 类的实例。

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

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

相关推荐
沉登c12 分钟前
Javascript客户端时间与服务器时间
服务器·javascript
持久的棒棒君15 分钟前
ElementUI 2.x 输入框回车后在调用接口进行远程搜索功能
前端·javascript·elementui
小程xy3 小时前
react 知识点汇总(非常全面)
前端·javascript·react.js
非著名架构师4 小时前
js混淆的方式方法
开发语言·javascript·ecmascript
多多米10055 小时前
初学Vue(2)
前端·javascript·vue.js
敏编程5 小时前
网页前端开发之Javascript入门篇(5/9):函数
开发语言·javascript
看到请催我学习5 小时前
内存缓存和硬盘缓存
开发语言·前端·javascript·vue.js·缓存·ecmascript
XiaoYu20027 小时前
22.JS高级-ES6之Symbol类型与Set、Map数据结构
前端·javascript·代码规范
儒雅的烤地瓜7 小时前
JS | JS中判断数组的6种方法,你知道几个?
javascript·instanceof·判断数组·数组方法·isarray·isprototypeof
道爷我悟了7 小时前
Vue入门-指令学习-v-on
javascript·vue.js·学习