面相对象?从js谈起
面向对象是主流语言的核心思想。
一说起面相对象,我们就想到了,封装,继承,多态,java这类语言面向对象的三大基本特征,这几个概念不好理解暂且不说,那按照这个定义,javascript这样连类的概念都没有的语言难道不算面相对象的语言了吗?
1
英文单词object被中文翻译为对象,愿意是"所有事物"的总称。事实上,人类天生就具有对万事万物抽象的能力,有了这样的能力我们才能便于去描述一个或一类事物,例如我们能通过一套直觉系统来迅速判断出一个跟拳头差不多大、外边圆滑、味道很甜、含丰富水分的东西与曾经吃过的某种东西很像,为了便于描述这个东西,我们就把它命名为"苹果"好了,它一定具有很多我们的经验中的共同特点,比如大小怎样,颜色怎样,味道怎样,等等。
换句话说对象的描述就是对具体事物的抽象描述(在java中这个描述就叫类,类就是对对象的抽象),只不过我们设计很多套不同的描述规则来更好的描述万事万物,于是就可能不断产生出更好的标准(例如java通过属性和方法来描述类,c通过成员变量和成员函数来描述类)。
这样看来,面相对象的编程就是一种更接近于人类思维的编程范式。
而javascript是一种很特别的语言,有对象的概念,却没有类的概念。
2
或许我们可以从javascript的基本语法中来重新理解下这一思想的内核。
无论怎样的编程语言,对象都具有以下特点。
有唯一标识,有状态,有行为。
1.各种语言对象的唯一标识都是用内存地址来体现的。这意味着任何两个对象都是不相等的。
2.状态就是指C++的成员变量,java的属性。
3.行为就是指C++的成员函数,java的方法。
只不过javascript的属性状态和行为都用属性来抽象。
例如:
var o = {
d: 1,
f() {
console.log(this.d);
}
};
对象o,d和f都是它的属性。
与java不同的是,javascript具有高度的动态性,这是因为它没有类的概念,不像java一样当类定义好后,就不能变了,而是可以在运行时动态改变对象的状态和行为。
也就是说,javascript丢弃了类,获得了更大的灵活性!
例如:
var o = { a: 1 };
o.b = 2;
console.log(o.a, o.b); //1 2
就像这样,我们定义好一个拥有属性a的对象o之后,还可以再给它添加一个属性b。
实际上javascript对象在运行时就是属性的集合,属性以字符串或symbol为key,以数据属性特征值或访问器属性特征值为value。
事实上我们又可以说,javascript的对象是一个属性的索引结构(一种常见的数据结构,能通过key快速查找到value的字典)。
总之,虽然以属性为核心来描述对象与其他语言用类来描述对象有着很大不同,实际使用起来可能各有利弊,但本质上,都是面相对象的基本思想。