我转过几个弯 绕过那个小雨楼
拿着蒲扇摆着衣衫渡着紧箍咒
不问天涯不停留 喝过几壶酒
不过年少白头道义放胸口
倘若明天之后 遥看前尘剑封侯
似那天上神仙无所求
朝朝暮暮君如梦醒十分不为何理由
是真是假是惶恐是无休
路过这风雨花满楼 片刻都不停留
我本这书生进京赶考留下许多愁
你问有没有时候 我叹这天道默悠悠
能否与我一醉方休
又过了几个弯 算尽天量道莫慌
踏这田园闻这芳草香
跌跌撞撞仗剑天涯折煞不枉无笔良
是梦是幻是温柔是家乡
路过这风雨花满楼 片刻都不停留
我本这书生进京赶考留下许多愁
你问有没有时候 我叹这天道默悠悠
能否与我一醉方休
路过这风雨花满楼 片刻都不停留
我本这书生进京赶考留下许多愁
你问有没有时候 我叹这天道默悠悠
能否与我一醉方休
谁能与我一醉方休
Javascript对象是面向对象还是基于对象
什么是面向对象?
不同的语言,他们对于对象的解释都不相同,但无论如何,我们应该认识到,对象并不是只存在于计算机领域的一个概念,它是顺应人类思维模式产生的一种抽象。
那么,我们先来了解下人类思维模式下,对象是什么?
对象这一概念在人类的幼儿期形成,这远远早于我们编程逻辑中常用的值、过程等概念。在幼年期,我们总是先认识到某一个苹果能吃(这里的某一个苹果就是一个对象),继而认识到所有的苹果都可以吃(这里的所有苹果,就是一个类),再到后来我们才能意识到三个苹果和三个梨之间的联系,进而产生数字“3”(值)的概念
在《面向对象分析与设计》这本书中,Grady Booch替我们做了总结,他认为,从人类的认知角度来说,对
象应该是下列事物之一:
- 一个可以触摸或者可以看见的东西;
- 人的智力可以理解的东西;
- 可以指导思考或行动(进行想象或施加动作)的东西
有了对象的自然定义后,我们就可以描述编程语言中的对象了。在不同的编程语言中,设计者也利用各种不
同的语言特性来抽象描述对象,最为成功的流派是使用“类”的方式来描述对象,这诞生了诸如 C++、Java
等流行的编程语言
而 JavaScript 早年却选择了一个更为冷门的方式:原型
Javascript 对象特征
在我看来,不论我们使用什么样的编程语言,我们都先应该去理解对象的本质特征(参考GrandyBooch《面向对象分析与设计》)。总结来看,对象有如下几个特点。
- 对象具有唯一标识性:即使完全相同的两个对象,也并非同一个对象。
- 对象有状态:对象具有状态,同一对象可能处于不同状态之下。
- 对象具有行为:即对象的状态,可能因为它的行为产生变
对象具有唯一标识性
在js中,对象的唯一标识就是他在内存中的地址,因此我们知道,即便两个对象的内容相同,但是他们也不是相同的。
var o1 = { a: 1 };
var o2 = { a: 1 };
console.log(o1 == o2); // false
对象有状态和对象具有行为
在javascript中,模糊了状态和行为,他们统称为:属性;所以 JavaScript中的行为和状态都能用属性来
抽象。
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,o.b); //1,2
o被声明后就已经运行了,运行后我们还给他添加了b属性,这就是运行时为对象添改状态和行为的能力。
Javascript对象的两类属性
对JavaScript来说,属性并非只是简单的名称和值,JavaScript用一组特征(attribute)来描述属性(property)。
先来说第一类属性,数据属性。它比较接近于其它语言的属性概念。数据属性具有四个特征:
- value:就是属性的值
- writable:决定属性能否被赋值
- enumerable:决定for in能否枚举该属性
- configurable:决定该属性能否被删除或者改变特征值
在大多数情况下,我们只关心数据属性的值即可
第二类属性是访问器(getter/setter)属性,它也有四个特征:
- getter:函数或undefined,在取属性值时被调用
- setter:函数或undefined,在设置属性值时被调用
- enumerable:决定for in能否枚举该属性
- configurable:决定该属性能否被删除或者改变特征值
访问器属性使得属性值在读写时得到完全不同的值。
我们通常用于定义属性的代码会产生数据属性,其中的writable、enumerable、configurable都默认为true。我们可以使用内置函数 Object.getOwnPropertyDescripter来查看,如以下代码所示:
var o = { a: 1 };
o.b = 2;
//a和b皆为数据属性
Object.getOwnPropertyDescriptor(o,"a");
//{value: 1, writable: true, enumerable: true,configurable:true}
Object.getOwnPropertyDescriptor(o,"b");
//{value: 2, writable: true, enumerable: true,configurable:true}
如果我们要想改变属性的特征,或者定义访问器属性,我们可以使用 Object.defineProperty,示例如下:
var o = { a: 1 };
//修改
Object.defineProperty(o, "b", {value: 2, writable: false, enumerable: false, configurable: true});
//获取
Object.getOwnPropertyDescriptor(o,"a");
//{value: 1, writable: true, enumerable: true,configurable:true}
Object.getOwnPropertyDescriptor(o,"b");
//{value: 2, writable: false, enumerable: false,configurable:true}
//我们定义b属性设置为是不能被修改的
o.b = 3;
console.log(o.b); //2
在创建对象时,也可以使用 get 和 set 关键字来创建访问器属性,代码如下所示:
var o = {
get a() { return 1 }
};
console.log(o.a); //1
访问器属性跟数据属性不同,每次访问属性都会执行getter或者setter函数。
这里我们的getter函数返回了1,所以o.a每次都得到1。
这样,我们就理解了,实际上JavaScript 对象的运行时是一个“属性的集合”,属性以字符串或者Symbol为key,以数据属性特征值或者访问器属性特征值为valu
对象是一个属性的索引结构(索引结构是一类常见的数据结构,我们可以把它理解为一个能够以比较快的速
度用key来查找value的字典)。我们以上面的对象o为例,你可以想象一下“a”是key
{writable:true,value:1,configurable:true,enumerable:true}是value。我们在前面的类型课程中,已经介绍了Symbol类型,能够以Symbol为属性名,这是JavaScript对象的一个特色。
到这里,我们可以知道,javascript的面向对象和目前主流的基于类的面向对象差异非常大。
但是它就是面向对象的语言。
评论(5)

杰哥
木灵鱼儿
杰哥
杰哥
木灵鱼儿