JavaScript 칼럼은 모든 사람에게 JavaScript 개체를 소개하고 새로운 이해를 제공합니다.
여기서 우리는 두 가지 더 중요한 유형인 Object
和 Symbol
에 대해 계속해서 배웁니다. Object에 비해 Symbol은 조연에 불과합니다.
사람은 누구나 아주 어릴 때부터 사물에 대한 개념을 접하게 됩니다. 사실 사람들은 대략 5살이 되면 사물에 대한 추상성을 가지게 됩니다. 우리는 프로그래밍을 배울 때만 객체가 객체라고 생각하는 것 같습니다. 그러나 인지적 관점에서 볼 때 숫자의 가치 유형에 대한 일반적인 이해보다 훨씬 이전 단계여야 합니다. 그러므로 역사적 관점에서 볼 때 사물은 인간의 자연적 사고에 더 가깝다는 평가가 항상 이루어져 왔다.
방금 우리는 어릴 때부터 사물의 개념을 갖고 있다고 했는데 왜 어릴 때부터 가지고 있다고 할까요? 객체는 실제로 영어로 매우 광범위한 것을 의미하며, 추상적인 객체일 수도 있고 실제 객체일 수도 있습니다. 그러나 우리 중국어에서는 바울의 모든 것을 대표하여 대상의 의미를 표현할 수 있는 적절한 단어를 찾을 수 없습니다. 그래서 중국어에서는 이를 "객체"로 직접 번역합니다.
그래서 이 중국어 번역어는 Object에 대한 오해를 불러일으켰습니다. object가 영어로 되어 있기 때문에 target이라는 단어의 의미에 더 가까운 것 같아요. 실제로 대만에서는 Object를 '객체'로 번역합니다. 객체라는 단어는 실제로 의미상 더 관련성이 높지만 모든 사람이 객체라는 단어에 특별히 익숙하지 않아 기술 명사로 발전했습니다.
하지만 어쨌든 우리는 어릴 때부터 그런 개념을 마음속에 품고 있어야 합니다. 우리는 세 마리의 똑같은 물고기가 있지만 사실은 세 마리의 다른 물체라는 것을 알아야 합니다. 그렇다면 왜 같은 물고기가 다른 물체일까요?
이렇게 이해할 수 있습니다. 어느 날 갑자기 물고기 한 마리의 꼬리가 물렸습니다. 나는 다른 두 마리의 물고기가 영향을 받지 않았다는 사실에 놀랐습니다. 따라서 컴퓨터에 있는 이 세 마리의 물고기를 설명할 때 동일한 데이터 개체의 세 세트여야 하지만 세 개의 복사본은 별도로 저장되고 서로 독립적입니다.
이런 종류의 물고기와 물고기의 차이점은 실제로 개체의 특성이 구현되는 것입니다. 일부 인지 연구에서는 우리가 약 5세 때 이런 인지 능력을 갖고 있다고 믿습니다. 사실 오늘날 어린이들은 더 일찍 발달하며, 5세가 이미 가장 낮은 연령입니다. 우리가 2~3살이 되면 이 사과가 저 사과와 다르다는 것을 모두가 알 것이다. 이 사과를 한 입 먹으면 다른 사과도 괜찮을 것이다.
그래서 이 세 마리의 물고기를 컴퓨터에 기술한다면 세 개의 객체의 상태이기 때문에 세 개의 개별 복사본에 데이터를 저장해야 합니다. 그들은 동등합니다. 사실 이것은 모든 객체 지향 프로그래밍의 기본입니다. 즉, 이 물고기라면 이 물고기이고, 이 물고기가 아니면 이 물고기가 아니기 때문입니다. 객체 자체의 상태 변경.
그렇다면 우리는 사물을 어떻게 이해하고 있을까요?
모든 객체는 고유하며 자체 상태와 관련이 없습니다. 상태는 객체에 의해 결정됩니다완전히 동일한 상태를 가진 두 객체도 동일하지 않습니다. 그래서 객체를 데이터로 사용하는 경우도 있는데 이는 실제로는 언어 사용 기술이며 객체를 객체로 사용하지 않습니다. 예를 들어 config를 전달할 때 실제로 config를 전달하는 과정은 객체를 객체로 취급하지 않습니다. . 그것을 전송하는 대신, 우리는 객체를 전송하기 위한 데이터 캐리어로 사용합니다. 이번에는 객체 유형 사용과 언어 자체의 설계 목적 사이의 편차가 포함됩니다.
상태를 사용하여 개체를 설명합니다. 예를 들어 "물고기" 개체의 상태는 "꼬리"가 있는지 여부와 "눈이 얼마나 큰지"를 설명하는 데 사용됩니다. 객체.
우리 상태의 변화는 둘 다 행동이고, 상태의 변화는 물고기의 꼬리가 없어져 물린 것입니다. 그러다가 얼마 후에 새로운 꼬리가 자라게 되었고 꼬리는 앞뒤로 흔들릴 수 있었습니다. 이것은 모두 상태의 변화입니다. 그리고 이러한 상태 변화는 행동입니다.
사실, 철학자들은 개체를 연구합니다. 물고기 이게 뭐죠? 이 물고기의 뼈를 모두 골라내면 이 물고기인지 알 수 있습니다. 그런 다음 고기를 모두 잘라서 함께 모아서 같은 생선인지 확인합니다. 이것은 유명한 철학적 질문 "Ship of Theseus"입니다.
이 점은 신경 쓸 필요가 없습니다. 변수에 개체의 핵심 요소이기도 한 고유 식별자가 있다고만 말하면 됩니다.
객체에는 상태가 있어야 하며 상태는 변경될 수 있으며 변경은 동작입니다. 이러한 방식으로 객체의 세 가지 요소가 설정됩니다.
세 가지 요소가 완전하다면 우리 마음 속의 모든 개념과 현실의 모든 항목이 객체가 될 수 있습니다.
우선
Class
클래스와Type
유형은 서로 다른 개념입니다.Class
类 和Type
类型是两个不一样的概念。
我们认识对象的一个重要的方式叫做分类,我们可以用分类的方式去描述对象。比如我们研究透测一条鱼之后,它与所有同类型的鱼特性都是类似的,所以我们就可以把这些鱼归为一类,叫 “鱼类”(Fish Class)。
其实在鱼的分类上还有更大的为 “动物分类 (Animal)”,那么动物下面还有其他动物的分类,比如说羊 (Sheep)。所以说鱼和羊之间他们的共性就会用 “动物” 来描述。然后我们一层一层的抽象,在 "Animal" 之上还会有 Object。
类是一个非常常见的描述对象的一种方式,比如说我们刚刚讲到的生物,用对象可以把所有的生物分成界门纲目科属种,是一个庞大的分类体系。在写代码的时候,分类是一个为业务服务的,我们没有必要分的那么细。通常我们会把有共性的需要写在代码里的,我们就把 Animal 提出来,就不再分这个哺乳动物,还是卵生,还是脊索动物等等。
分类有两个流派,一种是归类
,一种是分类
。
归类
—— 就是我们去研究单个对象,然后我们从里面提取共性变成类,之后我们又在类之间去提取共性,把它们变成更高的抽象类。比如我们在 “羊” 和 “鱼” 中提取共性,然后把它们之间的共享再提取出来变成 “动物” 的类。对于 “归类” 方法而言,多继承是非常自然的事情,如 C++ 中的菱形继承,三角形继承等。分类
객체를 이해하는 중요한 방법은 분류를 사용하여 객체를 설명할 수 있습니다. 예를 들어, 물고기를 연구하고 탐지한 후에는 동일한 유형의 모든 물고기와 유사한 특성을 가지므로 이러한 물고기를 "물고기 클래스"라는 하나의 범주로 분류할 수 있습니다.
분류
이고 다른 하나는 분류
입니다.
분류
- 즉, 단일 객체를 연구한 다음 그 객체에서 공통성을 클래스로 추출하고 클래스 간의 공통점을 추출하여 더 높은 추상화 유형으로 전환합니다. 예를 들어, "양"과 "물고기" 사이의 공통점을 추출한 다음, 이들 간의 공유를 "동물" 클래스로 추출합니다. "분류" 방법의 경우 다중 상속은 C++의 다이아몬드 상속, 삼각형 상속 등과 같이 매우 자연스러운 것입니다.
분류
- 세상의 모든 것을 기본 클래스 객체로 추상화한 다음 이 객체에 무엇이 있는지 정의합니다. 분류 아이디어를 채택한 컴퓨터 언어는 단일 상속 구조를 갖습니다. 그리고 기본 클래스인 Object가 있을 것입니다.
Object - Prototype
🎜🎜다음으로 JavaScript가 객체를 설명하는 방식에 대해 이야기해 보겠습니다. 🎜🎜🎜🎜🎜🎜🎜🎜사실 클래스 기반 객체가 객체를 이해하는 유일한 방법은 아닙니다. 인간의 자연스러운 인지에 더 가까운 또 다른 방법이 있습니다. 분류 능력은 적어도 초등학교 때까지는 가능하지 않을 수도 있습니다. 그러나 우리가 대상을 알게 된 후에는 거의 즉시 대상을 설명하는 다른 방법을 얻을 수 있습니다. 그것이 바로 “🎜프로토타입🎜”입니다. 🎜🎜프로토타입은 사실 "🎜고양이를 흉내내고 호랑이를 그려보세요🎜"라고 이해하시면 됩니다. 사실 고양이를 흉내내고 호랑이를 그리는 데 사용되는 프로토타입 방식입니다. 고양이와 호랑이는 매우 유사하기 때문에 직접적인 차이점만 구별하면 됩니다. 🎜예를 들어, 지금 물고기를 연구하고 싶다면 특정 잉어와 같은 전형적인 물고기를 찾은 다음 이 잉어의 모든 특성을 fish 프로토타입에 추가합니다. 다른 물고기가 객체를 갖고 있는 한, 우리는 물고기 프로토타입을 기반으로 객체를 수정할 것입니다. 예를 들어 메기는 잉어보다 식용성이 좋고, 고기를 먹으며 몸이 미끄럽기 때문에 잉어의 원형에 이러한 특성을 더하면 메기를 묘사할 수 있다.
그래서 양 카테고리에서는 작은 양도 기본 프로토타입으로 선택했습니다. 그런 다음 염소를 발견하고 그 특징이 수염, 구부러진 발, 길고 단단하며 산을 오를 수 있는 것으로 분석하면 이러한 특징을 작은 양의 원형에 추가한 다음 염소를 설명합니다. .
그런 다음 우수한 "동물" 중에서 발굽이 4개 있는 호랑이와 같은 전형적인 동물도 선택합니다. 그러나 모든 동물이 발굽이 4개 있는 것은 아니지만 프로토타입 선택은 상대적으로 자유롭습니다. 예를 들어, 동물의 원형으로 뱀을 선택한다면 물고기를 묘사할 때 많은 노력을 기울이고 고양이를 묘사할 때 더 많은 노력을 기울일 것입니다.
프로토타입에는 Object Prototype
이라는 최종 프로토타입도 있을 예정입니다. 이것은 모든 아이템의 대표적인 아이템이자 우리 모든 아이템의 조상이라고도 할 수 있습니다. 우리는 설명되는 대상과의 차이점을 기준으로 모든 대상을 설명합니다. 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
Object Prototype
위에는 프로토타입이 없지만 일부 언어에서는 Nihilo
프로토타입을 허용합니다. 니힐로(Nihilo)는 무(無)와 공허함을 의미하는데, 이는 언어 중립적인 말하기 방식입니다. JavaScript의 특정 기능을 사용하여 설명하면 Nihilo
의 프로토타입은 null
입니다. 이는 누구나 쉽게 를 생성할 수 있습니다. null
객체의 프로토타입입니다. 🎜🎜간단한 요약: 🎜
- 저희 프로토타입은 인간의 본래 인지에 가까운 객체를 기술하는 방식입니다.
- 따라서 다양한 객체지향 방식이 절대적이지는 않습니다. 틀리면 시나리오마다 비용이 다를 뿐입니다
- 프로토타입의 인지 비용도 낮고, 잘못된 선택을 하는 데 드는 비용도 상대적으로 낮으므로 프로토타입은 그다지 명확하지 않은 일부 시나리오에 적합합니다. 설명이 상대적으로 자유롭습니다.
- li>
- 분류(클래스)는 좀 더 엄격한 시나리오에 사용하기에 더 적합하며 클래스는 유형 시스템과 자연스럽게 통합되므로 많은 장점이 있습니다. 언어는 유형 시스템의 상속 관계에 통합 클래스의 상속 관계를 사용하도록 선택합니다.
Dog
클래스를 정의한 다음 이 클래스에 bite
메서드를 제공합니다. 🎜class Human { hurt(damage) { //...... } }复制代码
bite
가 발생하는 한 잘못된 것입니다. 🎜🎜🎜왜요? 🎜🎜<그림>bite
액션을 작성했지만 변경된 상태가 "human"인 경우, 개가 인간을 물은 후에는 인간에게 해를 끼칠 뿐입니다. 그러므로 이 행동에서는 "인간"의 상태가 변화하므로 그 행동이 개의 클래스에 속한다면 객체지향적 특성에 위배된다. 🎜🎜물론, 개가 사람을 먹는다면, 개가 사람을 먹고 배불러서 개 상태가 변하기 때문에 거의 확립할 수 없습니다. 그러나 개가 사람을 물 때, 우리는 기본적으로 이러한 행동이 개의 상태를 어떤 식으로든 바꾸지 않는다고 생각할 수 있습니다. 🎜🎜그래서 우리는 "person" 클래스에서 동작을 디자인해야 합니다. 그러면 일부 학생들은 사람들에게 biteBy
동작을 추가해야 합니까?라고 묻습니다. 그냥 물린 행위인가요? 개인 클래스의 동작을 사용하여 개인의 상태를 변경해야 하기 때문에 이는 옳지 않은 것 같습니다. 그렇다면 이 동작의 이름은 무엇이어야 할까요? 🎜🎜여기서 더 합리적인 행동은 상처를 받았다는 것을 나타내는 상처
여야 하며, 이 행동에 전달되는 매개변수는 손상 정도 손상
입니다. 이곳 사람들은 피해 규모에만 관심이 있을 뿐, 개에게 물린 것인지 다른 것인지는 신경 쓸 필요가 없기 때문이다. 🎜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(视频)
위 내용은 JavaScript 객체 다시 학습의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!