0

0

深入了解JavaScript中的Object(对象)

青灯夜游

青灯夜游

发布时间:2021-07-07 10:57:32

|

3982人浏览过

|

来源于csdn

转载

深入了解JavaScript中的Object(对象)

这里我们继续学习两个比较重要的类型,就是 ObjectSymbol。我们主要讲的是 Object,相对 Object 来说 Symbol 只是一个配角。

关于对象这个概念大家非常早就会接触到了,其实人大概在 5 岁的时候就会产生对象的抽象。很多时候我们看起来好像对象是我们学编程的时候才知道有面向对象。但是从认知的角度来说,应该是比我们平时对数字中的值这个类型的认知要早的多。所以历史的角度也一直被评价为,对象是更贴近人类的自然思维的。

刚刚说到我们从小时候就已经产生了对象的概念了,那为什么说从小就有呢?Object 在英文里其实它的意思是一个非常广泛的东西,他是任何一个物体,可以是抽象的物体,也可以是一个实际的物体。但是在我们中文里,找不到一个合适的词,可以代表保罗万物的词来表达 Object 的含义。所以在中文中我们就直接翻译成 “对象”。

所以这个中文翻译过来的词,就造成了我们对 Object 的一定误解。因为对象在英文中,我觉得更接近 target 这个单词的意思。其实在台湾就会把 Object 翻译成 “物件”。物件这个词在语义上确实会更贴合一些,但是物件这个词大家也不是特别熟悉,所以它就演变成了一个技术的专用名词。

立即学习Java免费学习笔记(深入)”;

但是不论如何,我们脑子里面应该是有这么一个概念的,从小我们就应该知道我们有三条一模一样的鱼,但是其实他是三个不同的对象。那为什么一模一样的鱼,他们是不同的对象呢?

我们可以这么理解哈,突然有一天其中一条鱼的尾巴被咬掉了。很惊奇的发现,另外两条鱼并不会受到影响。因此,当我们在计算机中描述这三条鱼的时候,那肯定是三组相同的数据的对象,但是是单独储存了三份,互相独立的。

这种鱼和鱼之间的区别其实就是,他们的对象的一个特性的体现。一些认知学的研究认为我们人在小时候大概 5 岁的时候就有

这样的认知了,其实现在的孩子发育的比较早,5岁已经是一个最低的年龄了。2 ~ 3 岁的时候大家都知道这个苹果和那个苹果是不一样的,这个咬一口,另外一个苹果安然无事。

所以如果我们在计算机里面描述这三条鱼的时候,我们就必须要把数据单独存储三份,因为是三个对象的状态,而不是我们把同一个数据存了三份,而是恰巧他们是相等而已。其实这个正是所有的面向对象编程的一个基础,也就是说,他是这条鱼就是这条鱼,不是这条鱼就不是这条鱼,不会因为对象本身的状态改变而变得有区别。

所以我们对对象的认知是?

任何一个对象都是唯一的,这与它本身的状态无关,状态是由对象决定的

即使状态完全一致的两个对象,也并不相等。所以有时候我们会把对象当数据用,但是这个其实是一种语言的使用技巧而已,并不是把对象当做对象用,比如我们传一个 config,其实传 config 的过程其实它并不是把对象当对象去传,而是我们把对象当成一种数据载体去传。这个时候就涉及到我们对对象类型的使用,跟语言本身的设计用途的偏差。

我们用状态来描述对象,比如我们有一个对象 “鱼”,然后他的状态就是,它有没有 “尾巴”、“眼睛多大”,我们都会用这些状态值来描述一个对象。

我们的状态的改变既是行为,状态的改变就是鱼的尾巴没有了,被咬掉了。然后过了一段时间它又长出一条新尾巴了,然后尾巴还可以来回摆动。这些都属于它的状态的改变。而这些状态的改变都是行为。

Object 三要素

深入了解JavaScript中的Object(对象)

  • Identifier —— 唯一标识
  • State —— 状态
  • Behavior —— 行为

其实哲学家他们就会研究一个 Object,比如鱼的唯一标识是什么,这条鱼的骨头全部挑出来看还是不是这条鱼。然后把肉都切下来,再拼起来看是不是这一条鱼,这就是著名的哲学问题 “忒修斯之船”。

这个我们就不用关心,我们就说变量它是有一个唯一标识性,这个也是对象的一个核心要素具备了。

对象就要有状态,状态是可以被改变的,改变就是行为。这样对象的三要素就成立了。

我们脑子里的任何一个概念和现实中的任何一个物品,都可以成为一个对象,只要三要素是齐备的。

Object —— Class(类)

首先 Class 类 和 Type 类型是两个不一样的概念。

我们认识对象的一个重要的方式叫做分类,我们可以用分类的方式去描述对象。比如我们研究透测一条鱼之后,它与所有同类型的鱼特性都是类似的,所以我们就可以把这些鱼归为一类,叫 “鱼类”(Fish Class)。

其实在鱼的分类上还有更大的为 “动物分类 (Animal)”,那么动物下面还有其他动物的分类,比如说羊 (Sheep)。所以说鱼和羊之间他们的共性就会用 “动物” 来描述。然后我们一层一层的抽象,在 “Animal” 之上还会有 Object。

类是一个非常常见的描述对象的一种方式,比如说我们刚刚讲到的生物,用对象可以把所有的生物分成界门纲目科属种,是一个庞大的分类体系。在写代码的时候,分类是一个为业务服务的,我们没有必要分的那么细。通常我们会把有共性的需要写在代码里的,我们就把 Animal 提出来,就不再分这个哺乳动物,还是卵生,还是脊索动物等等。

分类有两个流派,一种是归类,一种是分类

千博企业网站管理系统标准版2013 Build0206
千博企业网站管理系统标准版2013 Build0206

系统简介 千博企业建站系统是根据企业客户实际应用需求而提供的一套完整的中小企业网站应用解决方案,协助企业对公司产品进行更深层次的展示、推广。 千博企业建站系统主要面向企业进行产品展示、推广、企业形象展示而设计研发,系统界面简洁大方,管理操作非常简易,可高效构建企业、行业、律师、医院、政府信息门户网站、内部知识网站、信息门户等平台,并内置了专业的内容管理功能模块,可为浏览网站的顾客提供全方位的导购服

下载
  • 归类 —— 就是我们去研究单个对象,然后我们从里面提取共性变成类,之后我们又在类之间去提取共性,把它们变成更高的抽象类。比如我们在 “羊” 和 “鱼” 中提取共性,然后把它们之间的共享再提取出来变成 “动物” 的类。对于 “归类” 方法而言,多继承是非常自然的事情,如 C++ 中的菱形继承,三角形继承等。
  • 分类 —— 则是把世界万物都抽象为一个基类 Object,然后定义这个 Object 中有什么。采用分类思想的计算机语言,则是单继承结构。并且会有一个基类 Object。

JavaScript 这个语言比较接近 “分类” 这个思想,但是它也不完全是分类的思想,因为它是一个多范式的面向对象语言。

Object —— Prototype(原型)

接下来我们讲一讲 JavaScript 描述对象的方式。

其实分类 Class Based 的 Object 并不是一个唯一的认识对象的方法,我们还有一个更接近人类自然认知的。分类的能力可能至少要到小学才有的。但是我们认识对象之后,几乎是马上就可以得到另外一种描述对象的方式。那就是 “原型”。

原型其实用 “照猫画虎” 来理解 ,其实照猫画虎就是用的一种原型方法。因为猫和虎很像,所以我们只需要把它们直接的有区别的地方分出来就可以了。

比如说我们现在想研究鱼,那么找一种典型的鱼,比如找一条具体的鲤鱼,然后我们把这条鲤鱼所有的特征都加到鱼类的原型上。其他的鱼只要有对象,我们就根据鱼的原型进行修改。比如说鲶鱼比鲤鱼更能吃,它是吃肉的,而且身上还是滑滑的,所以我们就可以在鲤鱼的原型基础上把这些特征加上,这样我们就能描述出鲶鱼了。

那么在羊类里面,我们也选中一只小绵羊来做我们的基础原型。然后如果我们找到一只山羊,我们分析出它的特性是多胡子,脚是弯点,又长又硬又能爬山,那么我们就在小绵羊的原型上加上这些特性,那我们就描述了一只山羊了。

那么在上级的 “动物” 中我们也选一只典型的动物,比如说老虎,有四个蹄,但是不一定所有动物都有4个蹄子,不过原型选择相对来说它是比较自由的。比如说我们选择蛇作为动物的原型的话,那么我们在描述鱼的时候就特别费劲了,描述猫的时候就更费劲了。

原型里面也会有一个最终版的原型叫 Object Prototype,这个就是所有物品的典型的物品,也可以说是我们所有对象的老祖宗。我们描述任何对象都是从它与描述对象的区别来进行描述的。

然后在 Object Prototype之上一般来说是不会再有原型了,但是有一些语言里面会允许有一种 Nihilo 原型。Nihilo 的意思就是虚无空虚,这个是语言中立的讲法。如果我们用 JavaScript 的具体的设施来描述,那这个 Nihilo 原型就是 null,这个大家就很容易理解了,我们很容易就可以一个 null 对象的原型。

小总结:

  • 我们这种原型是更接近人类原始认知的描述对象的方法
  • 所以面向对象的各种方法其实并没有绝对的对错,只存在在不同场景下不同的代价
  • 原型的认知成本低,选错的成本也比较低,所以原型适合一些不是那么清晰和描述上比较自由的场景
  • 而分类(Class)更适合用在一些比较严谨的场景,而 Class 有一个优点,它天然的跟类型系统有一定的整合的,所以很多的语言就会选择把 Class 的继承关系整合进类型系统的继承关系当中

小练习

我们如果需要编写一个 “狗 咬 人” 的 Class,我们需要怎么去设计呢?

如果我们按照一个比较朴素的方法,我们就会去定义一个 Dog Class,然后里面给予这个 Class 一个 bite 的方法。

class Dog {
  bite(Human) {
    // ......
  }
}

这样的一段代码是跟我们的题目是一模一样的,但是这个抽象是一个错误的抽象。因为这个违背了面向对象的基本特征,不管我们是怎么设计,只要这个 bite 发生在狗身上就是错误的。

为什么?

因为我们前面讲到了面向对象的三要素,对象的状态必须是对象本身的行为才能改变的。那么如果我们在狗的 Class 中写 bite 这个动作,但是改变的状态是 “人”,最为狗咬了人之后,只会对人造成伤害。所以在这个行为中 “人” 的状态是发生变化的,那么如果行为是在狗的 Class 中就违反了面向对象的特征了。

当然如果是狗吃人,那我们勉强是可以成立的,因为狗吃了人狗就饱了,那对狗的状态是有发生改变的。但是狗咬人,我们基本可以认为这个行为对狗的状态是没有发生任何改变的。

所以我们应该在 “人” 的 Class 中设计一个行为。那么有些同学就会问,我们是应该在人的身上加入一个 biteBy 行为吗?就是人被咬的一个行为?似乎也不对,因为人 Class 里面的行为应该是用于改变人的状态的,那这个行为的命名应该是怎么样的呢?

这里更加合理的行为应该是 hurt 表示被伤害了,然后传入这个行为的参数就是受到的伤害程度 damage。因为这里人只关心它受到的伤害有多少就可以了,他是不需要关心是狗咬的还是什么咬的。

class Human {
  hurt(damage) {
    //......
  }
}

狗咬人在实际开发场景中,是一个业务逻辑,我们只需要设计改变人 Human 对象内部的状态的行为,所以它正确的命名应该是 hurt。这里的 damage,可以从狗 Class 中咬 bite, 的行为方法中计算或者生成出来的一个对象,但是如果我们直接传狗 Dog 的对象进来的话,肯定是不符合我们对对象的抽象原则的。

最终我们的代码实现逻辑如下:

class Human {
  constructor(name = '人') {
    this.name = name;
    this.hp = 100;
  }

  hurt(damage) {
    this.hp -= damage;
    console.log(`${this.name} 受到了 ${damage} 点伤害,剩余生命中为 ${this.hp}`);
  }
}

class Dog {
  constructor(name = '狗') {
    this.name = name;
    this.attackPower = 10; // 攻击力
  }

  bite() {
    return this.attackPower;
  }
}

let human = new Human('三钻');
let dog = new Dog();

human.hurt(dog.bite()); // 输出:三钻 受到了 10 点伤害,剩余生命中为 90

设计对象的原则

  • 我们不应该受到语言描述的干扰(特别是业务需求的干扰)
  • 在设计对象的状态和行为时,我们总是遵循 “行为改变状态” 的原则
  • 违背了这个原则,整个对象的内聚性就没有了,这个对架构上会造成巨大的破坏

更多编程相关知识,请访问:编程入门!!

相关文章

java速学教程(入门到精通)
java速学教程(入门到精通)

java怎么学习?java怎么入门?java在哪学?java怎么学才快?不用担心,这里为大家提供了java速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

236

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

458

2024.03.01

go语言 面向对象
go语言 面向对象

本专题整合了go语言面向对象相关内容,阅读专题下面的文章了解更多详细内容。

56

2025.09.05

java面向对象
java面向对象

本专题整合了java面向对象相关内容,阅读专题下面的文章了解更多详细内容。

52

2025.11.27

java多继承如何实现
java多继承如何实现

本专题整合了java多继承相关内容以及教程,阅读专题下面的文章了解更多详细内容。

26

2025.10.28

class在c语言中的意思
class在c语言中的意思

在C语言中,"class" 是一个关键字,用于定义一个类。想了解更多class的相关内容,可以阅读本专题下面的文章。

469

2024.01.03

python中class的含义
python中class的含义

本专题整合了python中class的相关内容,阅读专题下面的文章了解更多详细内容。

13

2025.12.06

俄罗斯Yandex引擎入口
俄罗斯Yandex引擎入口

2026年俄罗斯Yandex搜索引擎最新入口汇总,涵盖免登录、多语言支持、无广告视频播放及本地化服务等核心功能。阅读专题下面的文章了解更多详细内容。

141

2026.01.28

包子漫画在线官方入口大全
包子漫画在线官方入口大全

本合集汇总了包子漫画2026最新官方在线观看入口,涵盖备用域名、正版无广告链接及多端适配地址,助你畅享12700+高清漫画资源。阅读专题下面的文章了解更多详细内容。

24

2026.01.28

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
React 教程
React 教程

共58课时 | 4.3万人学习

TypeScript 教程
TypeScript 教程

共19课时 | 2.5万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号