对象、函数、原型之间的关系

server/2024/12/25 12:17:42/

在 JavaScript 中,对象函数原型 是三者紧密联系的核心概念。它们共同构成了 JavaScript 中面向对象编程的基石,并通过原型链实现了继承与代码复用。本文将从对象、函数、原型的基础概念到它们之间的关系进行详细的讲解,帮助你理解 JavaScript 的底层机制。

1. 什么是对象?

在 JavaScript 中,一切皆对象。对象是包含属性和方法的容器。属性可以是基本数据类型,如字符串、数字等;方法则是一个可以执行的函数。

javascript">var person = {name: "浮游",age: 20,greet: function() {console.log("Hello, I am " + this.name);}
};console.log(person.name);  // 浮游
person.greet();  // Hello, I am 浮游

上面的 person 是一个对象,它包含了两个属性 nameage,以及一个方法 greet

2. 什么是函数?

JavaScript 中的函数实际上也是对象。与其他对象不同的是,函数对象可以被调用。此外,每个函数在创建时都会自动拥有两个属性:prototype__proto__

javascript">function Foo() {}
console.log(typeof Foo); // function
console.log(Foo instanceof Object); // true

可以看出,函数本质上是对象,具有对象的一些特性。同时,它们也有特殊的属性,方便实现继承与原型链机制。

函数的两大属性:
  • prototype:每个函数都有的属性,指向函数的原型对象,用于继承。
  • __proto__:指向创建该对象的构造函数的原型。

3. 什么是原型?

原型是实现继承的核心概念。每个 JavaScript 对象都有一个隐藏的属性 [[Prototype]],可以通过 __proto__ 来访问。原型是一个对象,它用于实现对象之间的属性和方法的共享。

3.1 原型对象 (prototype)

每个函数对象在创建时都会有一个 prototype 属性,该属性指向原型对象,而这个原型对象中包含了通过该函数创建的实例所共享的属性和方法。

javascript">function Person(name, age) {this.name = name;this.age = age;
}// 向原型对象中添加方法
Person.prototype.greet = function() {console.log("Hello, I am " + this.name);
};var person1 = new Person("浮游", 20);
var person2 = new Person("熠星", 24);person1.greet();  // Hello, I am 浮游
person2.greet();  // Hello, I am 熠星

在上面的例子中,Person 函数有一个 prototype 属性,所有通过 Person 创建的对象 (person1person2) 都共享 prototype 中的 greet 方法。

3.2 隐式原型 (__proto__)

每个 JavaScript 对象都有一个 __proto__ 属性,指向其构造函数的原型。通过这个属性,对象可以继承构造函数原型上的属性和方法。__proto__ 是对象与原型之间的链接,形成了原型链。

javascript">console.log(person1.__proto__ === Person.prototype); // true
console.log(Person.prototype.__proto__ === Object.prototype); // true
console.log(Object.prototype.__proto__); // null, 原型链的顶端

person1 通过 __proto__ 链接到 Person.prototypePerson.prototype 又通过 __proto__ 链接到 Object.prototype,这就是 JavaScript 原型链的基础。

4. 对象、函数与原型的关系

JavaScript 是基于原型的语言,这意味着每个对象都从一个“原型”对象继承属性和方法。

  • 函数是对象:函数本身是一个对象,有 __proto__ 属性,它指向 Function.prototype
  • 对象有原型:每个对象都有一个 __proto__ 属性,它指向它的构造函数的 prototype
  • 原型链:通过 __proto__ 属性,对象可以访问其原型对象上的属性和方法。如果在自身对象中找不到某个属性,它会沿着原型链向上查找。
4.1 构造函数与实例对象的关系
javascript">function Car(model) {this.model = model;
}Car.prototype.drive = function() {console.log(this.model + " is driving");
};var car1 = new Car("Toyota");
var car2 = new Car("Honda");car1.drive();  // Toyota is driving
car2.drive();  // Honda is drivingconsole.log(car1.__proto__ === Car.prototype);  // true
console.log(Car.prototype.constructor === Car);  // true
  • car1car2 是由构造函数 Car 创建的实例对象。
  • 它们的 __proto__ 属性都指向 Car.prototype
  • Car.prototype.constructor 指向 Car 构造函数本身。
4.2 原型链的查找机制

当你访问一个对象的属性时,JavaScript 引擎首先会在对象本身的属性中查找。如果找不到,它会沿着原型链在其原型对象上查找。这个过程会持续到原型链的顶端——Object.prototype

javascript">console.log(car1.toString()); // [object Object]

car1 并没有 toString 方法,但是它沿着原型链找到了 Object.prototype.toString,因此可以调用它。

5. 原型链

原型链是指对象通过 __proto__ 一直向上查找,直到找到 Object.prototype 为止。如果在整个原型链中没有找到该属性,则返回 undefined

javascript">console.log(car1.__proto__); // Car.prototype
console.log(car1.__proto__.__proto__); // Object.prototype
console.log(car1.__proto__.__proto__.__proto__); // null, 原型链的顶端

6. 总结

  • 对象:JavaScript 中的任何实体都是对象,它们可以有属性和方法。
  • 函数:JavaScript 中的函数也是对象,它们有额外的 prototype 属性,用于支持原型链和继承。
  • 原型:原型是对象的共享属性和方法的容器,通过原型链实现继承。每个对象都有一个 __proto__ 属性,指向它的构造函数的 prototype
对象、函数与原型的关系:
对象 --通过 __proto__ --> 构造函数的 prototype --通过 constructor--> 构造函数

通过这个关系,JavaScript 实现了灵活的继承机制,使得我们能够通过原型链实现对象的扩展和代码的复用。

7. 关键要点

  • 原型链是 JavaScript 继承机制的核心,通过它可以实现属性和方法的查找。
  • 每个函数都有一个 prototype 属性,指向它的原型对象,原型对象上的属性和方法可以被该构造函数的实例对象共享。
  • 每个对象都有一个 __proto__ 属性,指向它的构造函数的原型对象。
  • 原型链的终点是 Object.prototype,它是所有对象的最终原型。

http://www.ppmy.cn/server/153034.html

相关文章

Hive其三,数据库操作,小技巧设置,加载数据等操作

目录 一、操作数据库 二、关于表的操作 1)关于字符类型的 2)创建表 3) 修改表 4)删除表 5) 小案例演示 三、Hive中经常使用的小技巧的设置 四、加载数据 1)加载本地数据: 2)从HDFS加载到Hive中&a…

基于Spring Boot的校园商城系统

一、系统背景与意义 随着互联网技术的快速发展,电子商务已经渗透到生活的方方面面。校园作为一个相对封闭但活跃的社群,同样需要一个专门的线上平台来满足其特殊的需求。基于Spring Boot的校园商城系统正是为此目的而设计,它结合了微服务架构…

【开源】一款基于SpringBoot的智慧小区物业管理系统

一、下载项目文件 项目文件源码链接:https://pan.quark.cn/s/3998d958e182如出现网盘空间不够存的情况!!!解决办法是先用夸克手机app注册,然后保存上方链接,就可以得到1TB空间了!!&…

【深入理解@EnableCaching】

深入理解EnableCaching EnableCaching 是 Spring Framework 中用于启用和配置缓存机制的一个注解。它通常被应用在配置类上,用来告诉 Spring 容器需要激活缓存相关的功能。Spring 的缓存抽象提供了一种简单的机制来管理缓存,可以减少重复的计算或数据库…

人工智能学习框架入门教程(一)

人工智能(AI)学习框架是指为开发、训练和部署人工智能模型提供的结构化工具和环境。它们帮助开发者实现AI项目的高效性、可扩展性、可维护性,并提供了优化算法、模型训练、评估、调优等功能。根据任务的不同,人工智能框架可以分为…

云边端架构的优势是什么?面临哪些挑战?

一、云边端架构的优势 降低网络延迟:在传统集中式架构中,数据需传输到云计算中心处理,导致网络延迟较高。而云边端架构将计算和存储推向边缘设备,可在离用户更近的地方处理数据,大大降低了网络延迟,提升了用…

ETCD备份还原

环境准备: master 192.168.8.128 node1 192.168.8.129 k8s版本: 一:安装etcdctl工具 1.1下载安装包: wget https://github.com/etcd-io/etcd/releases/download/v3.4.13/etcd-v3.4.13-linux-amd64.tar.gz 1.2解压&…

用于汽车碰撞仿真的 Ansys LS-DYNA

使用 Ansys LS-DYNA 进行汽车碰撞仿真汽车碰撞仿真 简介 汽车碰撞仿真是汽车设计和安全工程的一个关键方面。这些仿真使工程师能够预测车辆在碰撞过程中的行为,从而有助于改进安全功能、增强车辆结构并符合监管标准。Ansys LS-DYNA 是一款广泛用于此类仿真的强大工具…