여기서 우리는 Object
和 Symbol
라는 두 가지 더 중요한 유형을 계속해서 배웁니다. Object에 비해 Symbol은 조연에 불과합니다.
사람은 누구나 아주 어릴 때부터 사물에 대한 개념을 접하게 됩니다. 사실 사람들은 대략 5살이 되면 사물에 대한 추상성을 가지게 됩니다. 우리는 프로그래밍을 배울 때만 객체가 객체라고 생각하는 것 같습니다. 그러나 인지적 관점에서 볼 때 숫자의 가치 유형에 대한 일반적인 이해보다 훨씬 이전 단계여야 합니다. 그러므로 역사적 관점에서 볼 때 대상은 인간의 자연스러운 사고에 더 가깝다는 평가가 항상 이루어져 왔다.
방금 우리는 어릴 때부터 사물의 개념을 갖고 있다고 했는데 왜 어릴 때부터 가지고 있다고 할까요? Object는 실제로 영어로 매우 광범위한 것을 의미하며, 추상적인 객체일 수도 있고 실제 객체일 수도 있습니다. 그러나 우리 중국어에서는 바울의 모든 것을 대표하여 대상의 의미를 표현할 수 있는 적절한 단어를 찾을 수 없습니다. 그래서 중국어에서는 그냥 "객체"로 직접 번역합니다.
그래서 이 중국어 번역어는 Object에 대한 오해를 불러일으켰습니다. object는 영어로 되어 있기 때문에 target이라는 단어의 의미에 더 가까운 것 같아요. 실제로 대만에서는 Object를 "object"로 번역합니다. 객체라는 단어는 실제로 의미상 더 관련성이 높지만 모든 사람이 객체라는 단어에 특별히 익숙하지 않아 기술 명사로 발전했습니다.
하지만 어쨌든 우리는 어릴 때부터 그런 개념을 마음속에 품고 있어야 합니다. 우리는 세 마리의 똑같은 물고기가 있지만 사실은 세 마리의 다른 물체라는 것을 알아야 합니다. 그렇다면 왜 같은 물고기가 다른 물체일까요?
이런 종류의 물고기와 물고기의 차이점은 실제로 개체의 특성이 구현되는 것입니다. 일부 인지 연구에서는 우리가 약 5세 때 이런 인지 능력을 갖고 있다고 믿습니다. 사실 오늘날 어린이들은 더 일찍 발달하며, 5세가 이미 가장 낮은 연령입니다. 우리가 2~3살이 되면 이 사과가 저 사과와 다르다는 것을 모두가 알 것이다. 이 사과를 한 입 먹으면 다른 사과도 괜찮을 것이다.이렇게 이해할 수 있습니다. 어느 날 갑자기 물고기 한 마리의 꼬리가 물렸습니다. 나는 다른 두 마리의 물고기가 영향을 받지 않았다는 사실에 놀랐습니다. 따라서 컴퓨터에서 이 세 마리의 물고기를 설명할 때 동일한 데이터 개체의 세 세트여야 하지만 세 개의 복사본은 별도로 저장되어 서로 독립적입니다.
그래서 이 세 마리의 물고기를 컴퓨터에 기술한다면 세 개의 객체의 상태이기 때문에 세 개의 개별 복사본에 데이터를 저장해야 합니다. 그들은 동등합니다. 사실 이것은 모든 객체 지향 프로그래밍의 기본입니다. 즉, 이 물고기라면 이 물고기이고, 이 물고기가 아니면 이 물고기가 아니기 때문입니다. 객체 자체의 상태 변경.
그렇다면 우리는 사물을 어떻게 이해하고 있을까요?
모든 객체는 고유하며 자체 상태와 관련이 없습니다. 상태는 객체에 의해 결정됩니다
완전히 동일한 상태를 가진 두 객체도 동일하지 않습니다. 그래서 객체를 데이터로 사용하는 경우도 있는데 이는 실제로는 언어 사용 기술이며 객체를 객체로 사용하지 않습니다. 예를 들어 config를 전달할 때 실제로 config를 전달하는 과정은 객체를 객체로 취급하지 않습니다. . 그것을 전송하는 대신, 우리는 객체를 전송하기 위한 데이터 캐리어로 사용합니다. 이번에는 객체 유형 사용과 언어 자체의 설계 목적 사이의 편차가 포함됩니다. 상태를 사용하여 개체를 설명합니다. 예를 들어 개체 "물고기"가 있고 개체의 상태는 "꼬리"가 있는지 여부와 "눈이 얼마나 큰지"를 설명하는 데 사용됩니다. 객체.
상태의 변화는 행동이고, 상태의 변화는 물고기의 꼬리가 없어져 물린 것입니다. 그러다가 얼마 후에 새로운 꼬리가 자라게 되었고 꼬리는 앞뒤로 흔들릴 수 있었습니다. 이것은 모두 상태의 변화입니다. 그리고 이러한 상태 변화는 행동입니다.
객체의 세 가지 요소State - 상태
Behavior - 행동객체에는 상태가 있어야 하며 상태는 변경될 수 있으며 변경은 동작입니다. 이런 식으로 객체의 세 가지 요소가 설정됩니다.
세 가지 요소가 완전하다면 우리 마음속의 모든 개념과 현실의 모든 항목이 객체가 될 수 있습니다.
우선
Class
와Type
은 서로 다른 개념입니다.Class
类 和Type
类型是两个不一样的概念。
我们认识对象的一个重要的方式叫做分类,我们可以用分类的方式去描述对象。比如我们研究透测一条鱼之后,它与所有同类型的鱼特性都是类似的,所以我们就可以把这些鱼归为一类,叫 “鱼类”(Fish Class)。
其实在鱼的分类上还有更大的为 “动物分类 (Animal)”,那么动物下面还有其他动物的分类,比如说羊 (Sheep)。所以说鱼和羊之间他们的共性就会用 “动物” 来描述。然后我们一层一层的抽象,在 “Animal” 之上还会有 Object。
类是一个非常常见的描述对象的一种方式,比如说我们刚刚讲到的生物,用对象可以把所有的生物分成界门纲目科属种,是一个庞大的分类体系。在写代码的时候,分类是一个为业务服务的,我们没有必要分的那么细。通常我们会把有共性的需要写在代码里的,我们就把 Animal 提出来,就不再分这个哺乳动物,还是卵生,还是脊索动物等等。
分类有两个流派,一种是归类
,一种是分类
。
归类
—— 就是我们去研究单个对象,然后我们从里面提取共性变成类,之后我们又在类之间去提取共性,把它们变成更高的抽象类。比如我们在 “羊” 和 “鱼” 中提取共性,然后把它们之间的共享再提取出来变成 “动物” 的类。对于 “归类” 方法而言,多继承是非常自然的事情,如 C++ 中的菱形继承,三角形继承等。分类
—— 则是把世界万物都抽象为一个基类 Object,然后定义这个 Object 中有什么。采用分类思想的计算机语言,则是单继承结构。并且会有一个基类 Object。JavaScript 这个语言比较接近 “分类” 这个思想,但是它也不完全是分类的思想,因为它是一个多范式的面向对象语言。
接下来我们讲一讲 JavaScript 描述对象的方式。
其实分类 Class Based 的 Object 并不是一个唯一的认识对象的方法,我们还有一个更接近人类自然认知的。分类的能力可能至少要到小学才有的。但是我们认识对象之后,几乎是马上就可以得到另外一种描述对象的方式。那就是 “原型”。
原型其实用 “照猫画虎” 来理解 ,其实照猫画虎就是用的一种原型方法。因为猫和虎很像,所以我们只需要把它们直接的有区别的地方分出来就可以了。
比如说我们现在想研究鱼,那么找一种典型的鱼,比如找一条具体的鲤鱼,然后我们把这条鲤鱼所有的特征都加到鱼类的原型上。其他的鱼只要有对象,我们就根据鱼的原型进行修改。比如说鲶鱼比鲤鱼更能吃,它是吃肉的,而且身上还是滑滑的,所以我们就可以在鲤鱼的原型基础上把这些特征加上,这样我们就能描述出鲶鱼了。
那么在羊类里面,我们也选中一只小绵羊来做我们的基础原型。然后如果我们找到一只山羊,我们分析出它的特性是多胡子,脚是弯点,又长又硬又能爬山,那么我们就在小绵羊的原型上加上这些特性,那我们就描述了一只山羊了。
那么在上级的 “动物” 中我们也选一只典型的动物,比如说老虎,有四个蹄,但是不一定所有动物都有4个蹄子,不过原型选择相对来说它是比较自由的。比如说我们选择蛇作为动物的原型的话,那么我们在描述鱼的时候就特别费劲了,描述猫的时候就更费劲了。
原型里面也会有一个最终版的原型叫 Object Prototype
분류
이고 다른 하나는 분류
입니다. 🎜분류
- 즉, 단일 객체를 연구한 후 그 객체에서 공통점을 추출하여 클래스로 바꾸고, 클래스 간의 공통점을 추출하여 클래스로 바꾸는 것입니다. 더 높은 추상 클래스로. 예를 들어, "양"과 "물고기" 사이의 공통점을 추출한 다음, 이들 간의 공유를 "동물" 클래스로 추출합니다. "분류" 방법의 경우 다중 상속은 C++의 다이아몬드 상속, 삼각형 상속 등과 같이 매우 자연스러운 것입니다. 분류
- 세상의 모든 것을 기본 클래스 Object로 추상화한 다음 이 Object에 무엇이 있는지 정의합니다. 분류 아이디어를 채택한 컴퓨터 언어는 단일 상속 구조를 갖습니다. 그리고 기본 클래스인 Object가 있을 것입니다. Object Prototype
이라는 최종 프로토타입도 있을 예정입니다. 이는 모든 아이템의 대표적인 아이템이자 우리 모든 아이템의 조상이라고도 할 수 있습니다. 우리는 설명되는 대상과의 차이점을 기준으로 모든 대상을 설명합니다. 🎜일반적으로 말하면 Object Prototype
외에는 프로토타입이 없지만 일부 언어에서는 Nihilo
프로토타입을 허용합니다. 니힐로(Nihilo)는 무(無)와 공허함을 의미하는데, 이는 언어 중립적인 말하기 방식입니다. JavaScript의 특정 기능을 사용하여 설명하면 Nihilo
의 프로토타입은 null
입니다. 이는 누구나 쉽게 를 생성할 수 있습니다. null
객체의 프로토타입입니다. 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
간단한 요약:
이러한 코드 조각은 우리 질문과 완전히 동일하지만 이 추상화는 잘못된 추상화입니다. 이는 객체지향의 기본 특성에 어긋나기 때문에 우리가 어떻게 설계하든 개에게우리의 프로토타입은 인간의 원래 인지에 더 가까운 객체를 설명하는 방법입니다.따라서 다양한 객체 지향 방법은 절대적으로 옳고 그름이 아니며 비용이 다른 시나리오에만 존재합니다. 프로토타입의 인지 비용이 낮고 잘못된 선택에 대한 비용도 상대적으로 낮기 때문에 프로토타입은 그다지 명확하지 않고 설명이 상대적으로 자유로운 일부 장면에 적합합니다
그리고 좀 더 엄격한 일부 장면에는 분류(클래스)가 더 적합합니다. 씬과 클래스는 자연스럽게 타입 시스템과 통합된다는 장점이 있기 때문에 많은 언어에서는 클래스의 상속 관계를 타입 시스템의 상속 관계에 통합하는 쪽을 선택할 것입니다
- "개에 물린 사람" 클래스를 작성해야 한다면 어떻게 디자인해야 할까요?
작은 연습
- 비교적 간단한 방법을 따르면
Dog
클래스를 정의한 다음 이 클래스에bite
메서드를 제공합니다.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
bite
가 발생하는 한 잘못된 것입니다. bite
액션을 작성했지만 변경된 상태가 "human"인 경우, 개가 인간을 물은 후에는 인간에게 해를 끼칠 뿐입니다. 그러므로 이 행동에서는 "인간"의 상태가 변화하므로 그 행동이 개의 클래스에 속한다면 객체지향적 특성에 위배된다. 🎜🎜물론, 개가 사람을 먹는다면, 개가 사람을 먹고 배불러서 개 상태가 변하기 때문에 거의 확립할 수 없습니다. 그러나 개가 사람을 물 때, 우리는 기본적으로 이러한 행동이 개의 상태를 어떤 식으로든 바꾸지 않는다고 생각할 수 있습니다. 🎜🎜그래서 우리는 "person" 클래스에서 동작을 디자인해야 합니다. 그러면 일부 학생들은 사람들에게 biteBy
동작을 추가해야 합니까?라고 묻습니다. 그냥 물린 행위인가요? 개인 클래스의 동작을 사용하여 개인의 상태를 변경해야 하기 때문에 이는 옳지 않은 것 같습니다. 그러면 이 동작의 이름은 무엇이어야 합니까? 🎜🎜여기서 더 합리적인 행동은 상처를 받았다는 것을 나타내는 상처
여야 하며, 이 행동에 전달되는 매개변수는 손상 정도 손상
입니다. 여기 사람들은 피해 정도에만 관심이 있을 뿐, 개에게 물린 것인지 다른 것인지는 신경 쓸 필요가 없기 때문이다. 🎜rrreee🎜실제 개발 시나리오에서는 개가 사람을 물게 되는데 이는 비즈니스 로직입니다. 인간 Human
객체의 내부 상태를 변경하는 동작만 설계하면 되므로 정확한 이름은 상처. 여기서 피해
는 개 클래스 바이트 bite
의 행동 메소드로부터 계산되거나 생성된 객체일 수 있지만, 개를 직접 전달하는 경우 Dog object of code>가 들어 오면 객체에 대한 추상 원칙을 확실히 준수하지 않을 것입니다. 🎜🎜저희 코드의 최종 구현 로직은 다음과 같습니다. 🎜rrreee🎜🎜🎜Principles of designing object🎜: 🎜🎜🎜언어 설명에 방해를 받아서는 안 됩니다(특히 비즈니스 요구 사항에 의한 간섭)🎜🎜상태 및 동작을 설계할 때 객체의 경우, 우리는 항상 "🎜행동은 상태를 변경합니다🎜"라는 원칙을 따릅니다.🎜🎜이 원칙을 위반하면 객체 전체의 응집력이 사라져 아키텍처에 막대한 피해를 줄 수 있습니다🎜🎜🎜🎜더 많은 프로그래밍 관련 지식이 있으신 분들은 🎜프로그래밍 입문🎜을 방문해 주세요! ! 🎜
위 내용은 JavaScript의 객체에 대해 자세히 알아보기의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!