重学前端(五)--JavaScript对象

  • 为什么JavaScript有对象概念,但是却没有类的概念?
  • 为什么JavaScript对象可以自由添加属性,而其他语言不行?

一、什么是面向对象?

对象是一切事物的总称,它不是计算机领域凭空制造出来的概念,它是顺着人类的思维模式产生的一种抽象,所以面向对象编程也被认为是更接近人类思维模式的一种编程方式。

对象这一概念在人类的幼儿期形成,这远远早于我们编程逻辑中常用的值、过程等概念。

在幼年期,我们总是先认识到某一个苹果能吃(这里的某一个苹果就是一个对象),继而认识到所有的苹果都可以吃(这里的所有苹果,就是一个类),再到后来我们才能意识到三个苹果和三个梨之间的联系,进而产生数字“3”(值)的概念。

在《面向对象分析与设计》这本书中,Grady Booch 替我们做了总结,他认为,从人类的认知角度来说,对象应该是下列事物之一:

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

在不同的编程语言中,设计者利用不同的语言特性抽象的描述对象,最终成功的使用“类”的方式来描述对象,即产生了C++、Java等流行的编程语言。

ES6之前JavaScript程序员试图将JavaScript变得更像是基于类的编程,所以才产生了Dojo、prototypeJS。

二、JavaScript对象的特征

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

1、唯一标识性

var o1={a:1};
var o2={a:1};
consoel.log(o1==o2);//false

复制代码

o1和o2初看时是两个一模一样的对象,但是他们打印出的却是false。

2、状态+行为

状态+行为=属性。

    var o = {
        d:1,
        f(){
            console.log(this.d)
        }
    }
复制代码

其中 o 是对象,d 是一个属性,而函数 f 也是一个属性,尽管写法不太相同,但是对 JavaScript 来说,d 和 f 就是两个普通属性。

所以,总结一句话来看,在 JavaScript 中,对象的状态和行为其实都被抽象为了属性。如果你用过 Java,一定不要觉得奇怪,尽管设计思路有一定差别,但是二者都很好地表现了对象的基本特征:标识性、状态和行为。

在对象基本特征的基础上,JavaScript对象具有高度的动态性,这是因为 JavaScript 赋予了使用者在运行时为对象添改状态和行为的能力。

var o={a:1};
o.b=2;
console.log(o);{a:1,b:2}
复制代码

为了提高抽象能力,JavaScript 的属性被设计成比别的语言更加复杂的形式,它提供了数据属性和访问器属性(getter/setter)两类。

三、JavaScript对象的两类属性

对 JavaScript 来说,属性并非只是简单的名称和值,JavaScript 用一组特征(attribute)来描述属性(property)。

1、数据属性

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

2、访问器(setter、getter)属性

  • getter:函数或 undefined,在取属性值时被调用。
  • setter:函数或 undefined,在设置属性值时被调用。
  • enumerable:决定 for in 能否枚举该属性。
  • configurable:决定该属性能否被删除或者改变特征值。
Object.getOwnPropertyDescriptor(o,'a')
获得
{
    value: 1, 
    writable: true, //默认true
    enumerable: true, //默认true
    configurable: true//默认true
}
复制代码
Object.defineProperty(o,'a',{value:6,writable: false, enumerable: false, configurable: true});
o.a=11;
console.log(o.a)//6
Object.getOwnPropertyDescriptor(o,'a')//{value:6,writable: false, enumerable: false, configurable: true}
复制代码

先用Object.defineProperty定义属性,改变了value、writable和 enumerable,用Object.getOwnPropertyDescriptor查看的时候给a赋值a的值不会发生变化。

在创建对象时,也可以使用get和set关键字来创建访问器属性:

var h={ get a(){ return 1}};
console.log(h.a)//1
复制代码

访问器属性跟数据属性不同,每次访问属性都会执行 getter 或者 setter 函数。这里我们的 getter 函数返回了 1,所以 h.a 每次都得到 1。

JavaScript 对象的运行时是一个“属性的集合”,属性以字符串或者 Symbol 为 key,以数据属性特征值或者访问器属性特征值为 value。

为什么会有“JavaScript 不是面向对象” ?

这是由于 JavaScript 的对象设计跟目前主流基于类的面向对象差异非常大。

对于我而言面向对象是一个很广泛的定义,我也感觉我从未理解过面向对象,只是单从字面上解释就是,基于对象的对象以及一切的延伸。

转载于:https://juejin.im/post/5cef8797f265da1b8e7083a9

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值