javascript对象包含哪些要素_重学JavaScript 对象

栏目为大家介绍JavaScript的对象,重新认识。

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

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

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

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

但是不论如何,我们脑子里面应该是有这么一个概念的,从小我们就应该知道我们有三条一模一样的鱼,但是其实他是三个不同的对象。那为什么一模一样的鱼,他们是不同的对象呢?我们可以这么理解哈,突然有一天其中一条鱼的尾巴被咬掉了。很惊奇的发现,另外两条鱼并不会受到影响。因此,当我们在计算机中描述这三条鱼的时候,那肯定是三组相同的数据的对象,但是是单独储存了三份,互相独立的。这种鱼和鱼之间的区别其实就是,他们的对象的一个特性的体现。一些认知学的研究认为我们人在小时候大概 5 岁的时候就有这样的认知了,其实现在的孩子发育的比较早,5岁已经是一个最低的年龄了。2 ~ 3 岁的时候大家都知道这个苹果和那个苹果是不一样的,这个咬一口,另外一个苹果安然无事。所以如果我们在计算机里面描述这三条鱼的时候,我们就必须要把数据单独存储三份,因为是三个对象的状态,而不是我们把同一个数据存了三份,而是恰巧他们是相等而已。其实这个正是所有的面向对象编程的一个基础,也就是说,他是这条鱼就是这条鱼,不是这条鱼就不是这条鱼,不会因为对象本身的状态改变而变得有区别。

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

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

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

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

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

Object 三要素

Identifier —— 唯一标识

State —— 状态

Behavior —— 行为

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

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

对象就要有状态,状态是可以被改变的,改变就是行为。这样对象的三要素就成立了。我们脑子里的任何一个概念和现实中的任何一个物品,都可以成为一个对象,只要三要素是齐备的。

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

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

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

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

分类有两个流派,一种是归类,一种是分类。归类 —— 就是我们去研究单个对象,然后我们从里面提取共性变成类,之后我们又在类之间去提取共性,把它们变成更高的抽象类。比如我们在 “羊” 和 “鱼” 中提取共性,然后把它们之间的共享再提取出来变成 “动物” 的类。对于 “归类” 方法而言,多继承是非常自然的事情,如 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复制代码设计对象的原则:我们不应该受到语言描述的干扰(特别是业务需求的干扰)

在设计对象的状态和行为时,我们总是遵循 “行为改变状态” 的原则

违背了这个原则,整个对象的内聚性就没有了,这个对架构上会造成巨大的破坏相关免费学习推荐:javascript(视频)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/267492.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【iOS开发必收藏】详解iOS应用程序内使用IAP/StoreKit付费、沙盒(SandBox)测试、创建测试账号流程!...

Himi 原创, 欢迎转载,转载请在明显处注明! 谢谢。 原文地址:http://blog.csdn.net/xiaominghimi/article/details/6937097 终于在11月公司的游戏即将上线了,那么对于iOS游戏来说当今都是内置道具收费属于主流&#xf…

「BZOJ2879」[Noi2012]美食节

这道题就是 「BZOJ1070」[SCOI2007]修车 的加强版 如果一开始把全部边连上会T 优化的方法是只连用到过和下一次增广可能用到的边。 1 #include<bits/stdc.h>2 using namespace std;3 const int N50,M110,NN100010,oo1e9;4 int n,m,cost[N][M],tot,s,t,p[N],rank[NN],c[NN…

不越狱换壁纸_终于来了!iOS 14.3 正式版,可自动定时换壁纸

嘿嘿&#xff0c;我没有猜错吧&#xff01;iOS 14.3 正式版会在12月15日凌晨时段发布&#xff0c;在前几天我就有提到&#xff0c;这一天会发布&#xff0c;主要是与新品 AirPods Max 发售时间与iOS 14.3正式版发布时间一致。其次这次发布iOS 14.3正式版更新内容与 iOS 14.3 RC…

Hibernate【inverse和cascade属性】知识要点

Inverse属性 Inverse属性&#xff1a;表示控制权是否转移.. true:控制权已转移【当前一方没有控制权】false&#xff1a;控制权没有转移【当前一方有控制权】Inverse属性&#xff0c;是在维护关联关系的时候起作用的。只能在“一”的一方中使用该属性&#xff01;Inverse属性的…

[转]HOWTO do Linux kernel development - take 3 (中文版)

打好linux基础&#xff0c;不断的跟随这篇文章中的建议&#xff0c;适应linux kernel开发的流程。虽然需要很久甚至几年的时间&#xff0c;但我相信坚持就会前进&#xff01;加油&#xff01; HOWTO do Linux kernel development - take 3 (中文版) 译者&#xff1a;张乐 rober…

中list如何清空_如何根据索引删除 list 中的元素

这个问题很简单, 首先想到的就是a list(range(10)) del a[2]这个就可以很方便的删除掉 a 中的第 3 个元素.如果我想删除多个元素怎么办, 比如我想删除第 3, 4, 5, 6 个元素? 这个也很好办:a list(range(10)) del a[2:6]那么我要删除的元素的索引不连续呢? 比如我要删除第 3…

sql server紧急状态下登录脚本

--打开xp_cmdshell功能 EXEC [sys].[sp_configure] configname xp_cmdshell, -- varchar(35)configvalue 1 -- int 4 RECONFIGURE WITH override--修改注册表&#xff0c;修改身份验证为混合验证方式 USE [master] GOEXEC xp_instance_regwrite NHKEY_LOCAL_MACHINE, NSoftwa…

第一次项目之后...

从开始学习php不知不觉已经过去两个多月了&#xff0c;其中经历了各种各样以前没有经历过的生活和学习&#xff0c;在将近三个月的学习生活中我完成了第一个php项目。要说感觉&#xff0c;还真有些奇特&#xff0c;从开始连php是什么到现在能够亲手写出一个像模像样的网站就好像…

查询时拼接两列数据_如何用VBA代码查询两列数据差异?

爱就一个字&#xff0c;我只说一次……北京市第三交通委提醒您&#xff1a;代码千万条&#xff0c;注释第一条&#xff0c;命名不规范&#xff0c;修订两行泪……咳&#xff0c;给大家拜晚年了&#xff0c;再提前祝大家元宵快乐……我们今天和大家分享的内容是如何用VBA代码查询…

setTimeout详解

https://www.cnblogs.com/wzndkj/p/7069331.html 一、setTimeout基础 setTimeout(func|code,delay);第一个参数表示将要推迟的函数名或者一段代码&#xff0c;第二个参数表示推迟执行的毫秒数eg: console.log(1); setTimeout(console.log(2),1000); console.log(3);answer: 1 3…

Kappa电商负责人顾皓澜:电商业务一直保持盈利

Kappa电商负责人顾皓澜&#xff08;TechWeb配图&#xff09; 【TechWeb报道】10月初&#xff0c;闹得沸沸扬扬的淘宝商城事件吸引了无数互联网用户的目光&#xff0c;处于漩涡中心的淘宝商城当仁不让地挤入话题排行榜&#xff0c;商城上大小卖家的命运也牵动了众多消费者的心。…

python abs(3+4j)_表达式 abs(3+4j) 的值为 ____________ 。_学小易找答案

【单选题】REHL6/Centos6中重启网络服的命令是( ) 【单选题】在故障分析时,对变压器,以下说法不正确的是( ) 【填空题】表达式 chr(ord(A)+1) 的值为 ____________________ 。 【填空题】 【简答题】 【简答题】请提交实验报告 【单选题】电力系统发生三相短路时,短路电流知包含…

Citrix VDI-in-a-Box 第二篇:架构篇

前言&#xff1a;为什么Citrix会收购Kaviza&#xff0c;就是因为其VDI-in-a-Box产品架构比较简单。 本文重点描述其架构和安装要求。 如果你想了解一个东西&#xff0c;首先必须了解其架构。 vdiManager是管理整个架构的工具&#xff0c;所有的虚拟机都运行在Hypervisor上。整 …

看完此文再不懂区块链算我输,用Python从零开始创建区块链

如果你还没有听说过 3 点钟区块链群&#xff0c;说明你还不是链圈的人&#xff1b;如果你还没有加入 3 点钟区块链群&#xff0c;说明你还不是链圈的大佬&#xff1b;如果你还没有被 3 点钟区块链群刷屏&#xff0c;说明你还体会不到什么是“币圈一天&#xff0c;人间一年”。 …

重新加一个window_Activity、View、Window关系,进程间通信,责任链模式,Https,数据存储...

码仔&#xff0c;今天就给大家带来了《每日一道面试题》的第九期&#xff1a;01理解Activity View window的关系 Activity像一个工匠(控制单元)&#xff0c;Window像窗户(承载模型)&#xff0c;View像窗花(显示视图)LayoutInflater像剪刀&#xff0c;Xml配置像窗花图纸。 Activ…

Maven项目编译工具的使用

Java项目中最常用的编译工具是Ant&#xff0c;Ant解析XML配置文件&#xff0c;即build.xml&#xff0c;执行Target来实现用户目标的编译工作。Maven也是一个非常好用的编译工具&#xff0c;Maven类似于Ant也是有一个配置文件来配置编译信息&#xff0c;即pom.xml. 本文简要描述…

排他网关(ExclusiveGateWay)

网关&#xff08;ExclusiveGateWay&#xff09; 作者&#xff1a;邓家海2018年3月11日 00:13:25 情景:某一家公司最近在给一个单位做一个财务审批的OA。具体需求是这样的&#xff1a;当部门申请的金额小于一万块的时候&#xff0c;财务部可以直接决策。当部分申请的金额大于一万…

离线安装宝塔lnmp_宝塔LNMP环境 Nginx安装EduSoho教程说明

[toc]宝塔下使用LNMP Nginx安装EduSoho创建站点 宝塔后台 > 网站 > 添加站点 > 输入信息 > 提交填写信息创建完成设置运行目录 宝塔后台 > 网站 > 管理运行目录选择web目录后保存 网站目录 > 运行目录 > 保存修改配置文件 配置文件 > 修改参数 >…

NHibernate初学者指南(10):一级和二级缓存

一级缓存 为了获得更好的性能&#xff0c;NHibernate智能地缓存数据。NHibernate有不同的缓存机制起作用&#xff0c;最重要的就是一级缓存。每个session对象维持一个一级缓存&#xff0c;session对象创建时缓存创建&#xff0c;session对象释放时缓存销毁。 缓存只不过是一个哈…

Freemarker模板引擎

模板引擎的实质就是将页面结构提前写好&#xff0c;然后将数据渲染到模板上生成一个静态页面&#xff0c;这样一来&#xff0c;下次就可以 直接访问静态文件&#xff0c;不用进行额外的获取数据的操作&#xff08;例如&#xff1a;访问数据库&#xff09;&#xff0c;这样大大提…