重学JavaScript01:就从面向对象说起吧

{"type":"doc","content":[{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"你真的理解Object吗?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https://www.macmillandictionary.com/dictionary/british/object_1","title":""},"content":[{"type":"text","text":"Macmillan"}]},{"type":"text","text":"的解释是:"}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"a thing that you can see and"},{"type":"text","text":" "},{"type":"link","attrs":{"href":"https://www.macmillandictionary.com/dictionary/british/touch_1","title":null},"content":[{"type":"text","text":"touch"}]},{"type":"text","text":" "},{"type":"text","marks":[{"type":"strong"}],"text":"that is not"},{"type":"text","text":" "},{"type":"link","attrs":{"href":"https://www.macmillandictionary.com/dictionary/british/alive","title":null},"content":[{"type":"text","text":"alive"}]},{"type":"text","text":" "},{"type":"text","marks":[{"type":"strong"}],"text":"and is"},{"type":"text","text":" "},{"type":"link","attrs":{"href":"https://www.macmillandictionary.com/dictionary/british/usually","title":null},"content":[{"type":"text","text":"usually"}]},{"type":"text","text":" "},{"type":"link","attrs":{"href":"https://www.macmillandictionary.com/dictionary/british/solid_1","title":null},"content":[{"type":"text","text":"solid"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"一种你能够触摸到的实物,并非活物。"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"新华字典中,对象的基本含义是:"}]},{"type":"blockquote","content":[{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"行动或思考时作为目标的人或事物"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"特指恋爱的对方"}]}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"“你是我的研究对象,你是我的学习对象,这是今天的讨论对象”但如果单独用,就成了恋爱对方。“这是我对象”"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"因此对象在中文世界中并非像英文所指的那么普世,于是对象成了计算机领域中的专有名词,代表一切事物的总称。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"而从英文解释中,可以体会到,object是人类认知世界,而产生的一种思维抽象。什么意思呢?也就是人类成长过程中,对眼前事物的感知。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我是两个孩子的爸爸,我认真观察过他们,他俩小时候都是先用眼睛看,进入口欲期后用嘴巴感知,这个东西是红色,那个东西冰冰凉,再然后大人们教他们数数,OK,这是两个苹果。于是对象有了属性和值。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"《面向对象分析与设计中》,Grady Booch 说,从人类认知角度来说,对象是:"}]},{"type":"blockquote","content":[{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"一个可以触摸或者可以看见的东西;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"人的智力可以理解的东西;"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"可以指导思考或行动(进行想象或施加动作)的东西。"}]}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"对象的特征是:"}]},{"type":"blockquote","content":[{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"对象具有唯一标识性:即使完全相同的两个对象,也并非同一个对象。"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"对象有状态:对象具有状态,同一对象可能处于不同状态之下。"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"对象具有行为:即对象的状态,可能因为它的行为产生变迁。"}]}]}]}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"计算机中的Object"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在计算机语言的设计中,不同的设计者利用着他们对object理解,来对object进行了描述,也就是我们今天耳熟能详的,比如Java、C++ 中基于“类”的面相对象编程的概念。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"但Javascript有点特立独行,使用了“原型("},{"type":"link","attrs":{"href":"https://www.macmillandictionary.com/dictionary/british/prototype","title":""},"content":[{"type":"text","text":"Prototype"}]},{"type":"text","text":")”。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"the first form of something new, made before it is produced in large quantities"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"这里先不展开。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"JavaScript 的Object 之路"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"由于产生之时的政治原因,JS受管理层要求模仿Java,于是你看到了创始人 Brendan Eich 在“原型运行时”的基础上引入了 new、this 等语言特性,使之“看起来更像 Java”。ES6规范之前,甚至有大量的框架将JS改造成基于类来编程,而这样做的弊端明显要大于收益。"}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"JavaScript 的对象特征"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"幸运的是,任何语言的运行时,类的概念都会被弱化。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"对照上面说的,面向对象的三个特征:唯一、状态、行为"}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"唯一标识性"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"一般,对所有的语言来说,对象的唯一标识性都是通过"},{"type":"text","marks":[{"type":"strong"}],"text":"内存地址"},{"type":"text","text":"来实现的,对象具有唯一标识的内存地址,也就具有唯一标识了。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"也就是为什么,下面的返回为false:"}]},{"type":"codeblock","attrs":{"lang":"javascript"},"content":[{"type":"text","text":"var o1 = { a: 1 };\nvar o2 = { a: 1 };\nconsole.log(o1 === o2);"}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"状态与行为"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"对不同的语言来说,状态和行为会使用不同的描述:"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"C++ 中的“成员变量”和“成员函数”"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Java中的“属性”和“方法”"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"而在JS中,状态和行为统一抽象成了"},{"type":"text","marks":[{"type":"strong"}],"text":"属性"},{"type":"text","text":"(函数也是一种特殊的对象)。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如下例中,对对象o来说,d 和 f 就是两个普通的属性"}]},{"type":"codeblock","attrs":{"lang":"javascript"},"content":[{"type":"text","text":"var o = {\nd: 1,\nf() {\nconsole.log(this.d);\n}\n};"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"也就是说,JS能很好地体现对象的基本特征。"}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"JS对象的独有特色"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"但为什么很多人说“JS不是面向对象”的呢?因为JS的对象设计有其独有的特点,那就是:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"对象具有高度的动态性,因为JS能在运行时被修改状态和行为。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"你试过Java在运行时添加向对象添加属性吗?JS 能做到!"}]},{"type":"codeblock","attrs":{"lang":"javascript"},"content":[{"type":"text","text":"var o = { a: 1 };\no.b = 2;\nconsole.log(o.a, o.b); //1 2"}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"JS的属性"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"JS为了提高抽象能力,将属性设计成了(比别的语言)更加复杂的形势,提供了"},{"type":"text","marks":[{"type":"strong"}],"text":"数据属性"},{"type":"text","text":"和*"},{"type":"text","marks":[{"type":"italic"}],"text":"访问器属性"},{"type":"text","text":"*两类。也就是说,JS的属性并非简单的名称(键)和值,而是用了一组attribute(特征)来描述property(属性)。"}]},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":"数据属性"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"数据属性类似其他语言的“属性”,具有四个特征。"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"属性的值:value"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"能否赋值:writable"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"能否被(如for in)枚举:enumerable"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"能否被更新(改变或删除):configurable"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"虽然,我们通常只关系值。"}]},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":"访问器属性"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"也就是getter/setter属性,它也有四个特征。"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"取值时调用:getter"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"设置时调用:setter"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"能否被(如for in)枚举:enumerable"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"能否被更新(改变或删除):configurable"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"也就是说,读和写的时候,访问器属性可以执行代码,让读和写得到完全不同的值,可以看作一种函数的语法糖。"}]},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":"实践一下"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"这位客官问了,我怎么没设置过什么writable、enumerable、configurable啊?因为通常我们定义属性时,其默认值都是true,那我们怎么看到呢?getOwnPropertyDescripter"}]},{"type":"codeblock","attrs":{"lang":"javascript"},"content":[{"type":"text","text":"var o = { a: 1 };\no.b = 2;\n//a和b皆为数据属性\nObject.getOwnPropertyDescriptor(o,\"a\") // {value: 1, writable: true, enumerable: true, configurable: true}\nObject.getOwnPropertyDescriptor(o,\"b\") // {value: 2, writable: true, enumerable: true, configurable: true}"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"那如何改变呢?defineProperty"}]},{"type":"codeblock","attrs":{"lang":"javascript"},"content":[{"type":"text","text":"var o = { a: 1 };\nObject.defineProperty(o, \"b\", {value: 2, writable: false, enumerable: false, configurable: true});\n//a和b都是数据属性,但特征值变化了\nObject.getOwnPropertyDescriptor(o,\"a\"); // {value: 1, writable: true, enumerable: true, configurable: true}\nObject.getOwnPropertyDescriptor(o,\"b\"); // {value: 2, writable: false, enumerable: false, configurable: true}\no.b = 3;\nconsole.log(o.b); // 2"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"那访问器属性呢?"}]},{"type":"codeblock","attrs":{"lang":"javascript"},"content":[{"type":"text","text":"var o = { get a() { return 1 } };\no.a = 2\nconsole.log(o.a); // 1"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"每次访问属性都会实行getter 或者setter 函数,因此o.a 每次都得到1。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"总结一下, JS中的对象,实际上是一个“属性的集合”:"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"属性的key 为字符串或Symbol,"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"属性的value 为数据属性特征值或者访问器属性特征值"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"上面例子中的的a就是key,而它的value,是{writable:true,value:1,configurable:true,enumerable:true}"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"因此,JS的对象与其他语言相比,有些另类。"}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"特殊却普通"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"正如我们前面说到的:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"任何语言的运行时,类的概念都会被弱化。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"因此JS可以模仿多数面向对象编程范式,比如基于原型,甚至基于类。也正因此,JS是正如其语言标准所说的:JS是一门面向对象的语言。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"既然这样,我们就不要机械地用JS来模仿其他语言,充分利用它的"},{"type":"text","marks":[{"type":"strong"}],"text":"高度动态性的属性集合"},{"type":"text","text":"这一对象系统,挖掘它的能力吧。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章