Javascript 编程基础(5)面向对象 | 5.1、构造函数实例化对象

文章目录

前言:

在 JavaScript 里,构造函数是创建对象实例的一种方式。构造函数本质上是普通的函数,不过有其特定的使用模式:要用 new 关键字来调用,这样才能创建对象实例。下面为详细介绍构造函数实例化对象的相关内容。

一、构造函数实例化对象

1、基本语法

使用构造函数创建对象实例,需要遵循以下步骤:

  • 定义一个构造函数,函数名一般首字母大写(这是约定俗成的写法,并非强制要求)。
  • 在构造函数内部,通过 this 关键字来设置对象的属性和方法。
  • 使用 new 关键字调用构造函数,从而创建对象实例。

下面是一个简单的例子:

javascript 复制代码
// 定义一个构造函数
function Person(name, age) {
  this.name = name;
  this.age = age;
  this.sayHello = function() {
    console.log(`你好,我是${this.name},今年${this.age}岁了。`);
  };
}

// 使用new关键字创建对象实例
const person1 = new Person('张三', 25);
const person2 = new Person('李四', 30);

// 调用对象的属性和方法
console.log(person1.name); // 输出: 张三
person2.sayHello(); // 输出: 你好,我是李四,今年30岁了。

2、构造函数与原型的关系

当使用 new 关键字调用构造函数时,会按照以下步骤执行:

  • 首先创建一个新对象。
  • 让这个新对象的 [[Prototype]](即原型)指向构造函数的 prototype 属性。
  • 将构造函数的 this 绑定到新创建的对象上。
  • 执行构造函数内部的代码,这样就可以为新对象设置属性和方法。
  • 如果构造函数返回了一个对象,那么就返回该对象;否则,返回新创建的对象。

3、完整的原型链

一个典型的原型链如下所示:

cpp 复制代码
实例对象 -> 构造函数.prototype -> Object.prototype -> null

验证方法:

javascript 复制代码
persona1.__proto__ === Person.prototype; // true
Person.prototype.__proto__ === Object.prototype; // true
Object.prototype.__proto__ === null; // true

4、构造函数的特点

  • 属性和方法的复制 :每次通过构造函数创建对象实例时,都会为每个实例复制一份属性和方法。就像上面例子中的 sayHello 方法,每个实例都有自己独立的副本。
  • 原型链继承 :所有通过同一个构造函数创建的对象实例,都会继承构造函数 prototype 属性上的方法和属性。

下面通过代码说明原型链继承:

javascript 复制代码
function Car(make, model) {
  this.make = make;
  this.model = model;
}

// 给构造函数的prototype添加方法
Car.prototype.getInfo = function() {
  return `这是一辆${this.make} ${this.model}。`;
};

// 创建对象实例
const car1 = new Car('丰田', '卡罗拉');
const car2 = new Car('本田', '思域');

// 调用原型上的方法
console.log(car1.getInfo()); // 输出: 这是一辆丰田 卡罗拉。
console.log(car2.getInfo()); // 输出: 这是一辆本田 思域。

5、prototype__proto__属性

5.1、对象实例的__proto__属性

在 JavaScript 中,对象实例 本身没有prototype属性,但有__proto__属性(非标准,对应内部的[[Prototype]])。以下是详细说明:

  • proto(非标准):指向该对象的原型对象。
  • [[Prototype]](标准):内部属性,实际决定原型链。
javascript 复制代码
const obj = {};
console.log(obj.prototype); // undefined(实例没有prototype属性)
console.log(obj.__proto__ === Object.prototype); // true

5.2、prototype属性仅存在于函数对象

每个函数 默认有一个prototype属性,指向其原型对象:

javascript 复制代码
function Person() {}
console.log(Person.prototype); // { constructor: ƒ Person() }

// 验证函数也是对象,其原型是Function.prototype
console.log(Person.__proto__ === Function.prototype); // true

5.3、实例与原型的关系

当使用new创建对象时,实例的__proto__指向构造函数的prototype

javascript 复制代码
function Person() {}
const alice = new Person();

console.log(alice.__proto__ === Person.prototype); // true
console.log(Person.prototype.constructor === Person); // true

5.4、获取对象原型

推荐使用标准方法Object.getPrototypeOf()获取对象原型:

javascript 复制代码
const obj = {};
console.log(Object.getPrototypeOf(obj) === Object.prototype); // true

6、注意事项

  • 忘记使用 new 关键字的问题 :如果在调用构造函数时忘记使用 new 关键字,this 会指向全局对象(在浏览器环境中是 window 对象),这可能会导致意外的结果。为了避免这种情况,可以使用箭头函数或者在构造函数内部检查 this 是否是当前构造函数的实例。
  • 性能方面的考虑 :如果构造函数内部定义了大量方法,每个对象实例都会拥有这些方法的独立副本,这会造成内存的浪费。通常的做法是将共享的方法定义在构造函数的 prototype 上。
相关推荐
rzl022 分钟前
java web5(黑马)
java·开发语言·前端
Amy.Wang3 分钟前
前端如何实现电子签名
前端·javascript·html5
海天胜景5 分钟前
vue3 el-table 行筛选 设置为单选
javascript·vue.js·elementui
今天又在摸鱼6 分钟前
Vue3-组件化-Vue核心思想之一
前端·javascript·vue.js
百锦再10 分钟前
Vue中对象赋值问题:对象引用被保留,仅部分属性被覆盖
前端·javascript·vue.js·vue·web·reactive·ref
jingling55515 分钟前
面试版-前端开发核心知识
开发语言·前端·javascript·vue.js·面试·前端框架
FogLetter22 分钟前
图片懒加载:让网页飞起来的魔法技巧 ✨
前端·javascript·css
拾光拾趣录25 分钟前
JavaScript 加载对浏览器渲染的影响
前端·javascript·浏览器
m0_6873998433 分钟前
写一个Ununtu C++ 程序,调用ffmpeg API, 来判断一个数字电影的视频文件mxf 是不是Jpeg2000?
开发语言·c++·ffmpeg
爱上语文43 分钟前
Redis基础(5):Redis的Java客户端
java·开发语言·数据库·redis·后端