tags: [JavaScript对象]

categories: 重学前端系列笔记


前言

JavaScript 是面向对象还是基于对象?

要想弄懂这个,就得搞清楚,什么是面向对象?

什么是对象?

  • 之前有说过,对象是一切有形无形物体的总称。
  • 一切的编程语言最开始都是基于人类思想思维演变而来的,在人类思维中

    对象这一概念在人类的幼儿期形成,这远远早于我们编程逻辑中常用的值、过程等概念。 在幼年期,我们总是先认识到某一个苹果能吃(这里的某一个苹果就是一个对象),继而认识到所有的苹果都可以吃(这里的所有苹果,就是一个类),再到后来我们才能意识到三个苹果和三个梨之间的联系,进而产生数字“3”(值)的概念。

这样可以总结出以下的对象特征

  1. 一个可以触摸或者可以看见的东西
  2. 人的智力可以理解的东西
  3. 可以指导思考或行动(进行想象或施加动作)的东西

怎么描述对象

以上的总结来自 Grady Booch 的《面向对象程序分析与设计》根据上面的总结,由此可以得出两种描述的方式:

  • 一种就是使用类的方式,描述一类事物。然后一个个的挂载到描述的类上,挂载的事物可以继承原定的类的属性及方法,同时也可以有自己特定的方法及属性。使用这种的有,C/C++/JAVA/汇编

    eg:还是拿水果举例,水果是一些事物总称,公共特点就是能吃,好吃。可以补充营养。。。。,梨子,苹果都是属于水果,那么可以归类于水果这个类上,但是每种水果有自己的一些特性。

  1. // 创建一个水果的类
  2. class Fruit {
  3. // 构造器
  4. constructor(color,type) {
  5. this.color = color;
  6. this.type = type ;
  7. },
  8. // 作用:营养
  9. action:nutrition,
  10. // 使用方法:吃
  11. instructions:eat
  12. };
  13. // 描述一个苹果
  14. class apple extends Fruit {
  15. constructor(color, type) {
  16. super(color, type);
  17. },
  18. // 形状: 椭圆
  19. shape:oval,
  20. // 种类: 苹果
  21. type:apple,
  22. // 颜色:暗红
  23. color: DarkRed,
  24. // 特点:脆
  25. feature: brittle,
  26. }
  • 还有一种就是原型的方式。简略的描述一个事物,之后可以慢慢的对他进行丰满的描述,这些之后丰满的描述都是挂载在最原始描述的原型上。
  1. // 创建一个原始对象
  2. let Apple = (){
  3. // 形状: 椭圆
  4. shape:oval,
  5. // 种类: 苹果
  6. type:apple,
  7. };
  8. // 给苹果这个对象添加个吃的方法。
  9. Apple.prototype.eat = function () {
  10. console.log("我要吧这个苹果吃完")
  11. };

但是在创造 JavaScript 之初,JavaScript 之父的公司要求模仿 Java ,于是在原本的原型基础上,引入 new 关键字,以及 this 的概念特性。使之更像 Java

JavaScript 的对象特征

从 Grandy Booch《面向对象分析与设计》可以总结出所有的语言对象应该都具有以下特征

  • 对象具有唯一标识性:即使完全相同的两个对象,也并非同一个对象。
  • 对象有状态:对象具有状态,同一对象可能处于不同状态之下。
  • 对象具有行为:即对象的状态,可能因为它的行为产生变迁。

从第一个特征来看,JavaScript 中的对象。即使是具有相同属性的,也不是相同的

  1. let a = {
  2. title: "我要吃素",
  3. };
  4. let b = {
  5. title: "我要吃素",
  6. };
  7. console.log(b === a) // 结果:false

这个为啥是 false 呢,学过 JavaScript 的都知道的存在,(堆栈思想应该也是窃取其他语言的吧,小声比比)。简单数据类型存在中,复杂数据类型存在中,如果是复杂数据浅拷贝的话,一般是将引用地址存在堆上

第二个特征和第三个特征来看,在 JavaScript 中,就抽象成了属性,不管是普通的属性还是函数,都是属于JavaScript的属性这个类别。

  1. let test = {
  2. code: 1,
  3. fun () {
  4. console.log(this.d);
  5. }
  6. }

上述代码中,code 和 fun 都是属于普通的属性。
在实现了对象基本特征的基础上,**JavaScript** 中对象独有的特色是:对象具有高度的动态性,这是因为 **JavaScript** 赋予了使用者在运行时为对象添改状态和行为的能力。
**

JavaScript 对象的属性类别

(0)数据属性
  • value:就是属性的值。
  • writable:决定属性能否被赋值。
  • enumerable:决定 for in 能否枚举该属性。
  • configurable:决定该属性能否被删除或者改变特征值。

    (1)访问器属性(getter/setter)
  • getter:函数或 undefined,在取属性值时被调用。

  • setter:函数或 undefined,在设置属性值时被调用。
  • enumerable:决定 for in 能否枚举该属性。
  • configurable:决定该属性能否被删除或者改变特征值。

    访问器属性使得属性在读和写时执行代码,它允许使用者在写和读属性时,得到完全不同的值,它可以视为一种函数的语法糖。
    那我们怎么查看一个对象的数据属性呢?

查看属性 Object.getOwnPropertyDescriptor

  1. let test = { a: 1 };
  2. test.b = 2;
  3. //a 和 b 皆为数据属性
  4. console.log( Object.getOwnPropertyDescriptor(test,"a") ) // {value: 1, writable: true, enumerable: true, configurable: true}
  5. console.log( Object.getOwnPropertyDescriptor(test,"b") ) // {value: 2, writable: true, enumerable: true, configurable: true}

改变属性:Object.defineProperty

  1. let test = { a: 1 };
  2. // 改变数据属性
  3. Object.defineProperty(test,"a",{value: 1, writable: false, enumerable: false, configurable: false });
  4. // 获取改变之后的数据属性
  5. console.log( Object.getOwnPropertyDescriptor(test,"b") ) // {value: 1, writable: false, enumerable: false, configurable: false }}

当然在创建对象的时候,也可以使用 get 和 set 关键字来创建访问器属性
  1. let test = {
  2. get a() {
  3. return 1
  4. }
  5. };
  6. console.log(test.a); // 1