正确理解javascript当中的面向对象

时间:2021-02-27 19:31:59

认识面向对象:

  为了说明 JavaScript 是一门彻底的面向对象的语言,首先有必要从面向对象的概念着手 , 探讨一下面向对象中的几个概念:

  1.万物皆为空;万物皆对象 

  2.对象具有封装和继承特性

  3.对象与对象之间使用消息通信,各自存在信息隐藏

面向对象仅仅是一个概念或者编程思想而已,它不应该依赖于某个语言存在。比如 Java 采用面向对象思想构造其语言,它实现了类、继承、派生、多态、接口等机制。但是这些机制,只是实现面向对象编程的一种手段,而非必须。换言之,一门语言可以根据其自身特性选择合适的方式来实现面向对象。所以,由于大多数程序员首先学习或者使用的是类似 Java、C++ 等高级编译型语言(Java 虽然是半编译半解释,但一般做为编译型来讲解),因而先入为主地接受了“类”这个面向对象实现方式,从而在学习脚本语言的时候,习惯性地用类式面向对象语言中的概念来判断该语言是否是面向对象语言,或者是否具备面向对象特性。这也是阻碍程序员深入学习并掌握 JavaScript 的重要原因之一。

实际上,JavaScript 语言是通过一种叫做 原型(prototype的方式来实现面向对象编程的。下面就来讨论 基于类的(class-based)面向对象和 基于原型的 (prototype-based) 面向对象这两种方式在构造客观世界的方式上的差别。

基于类的面向对象和基于原型的面向对象方式比较

在基于类的面向对象方式中,对象(object依靠 类(class来产生。而在基于原型的面向对象方式中,对象(object则是依靠 构造器(constructor利用 原型(prototype构造出来的。举个客观世界的例子来说明二种方式认知的差异。例如工厂造一辆车,一方面,工人必须参照一张工程图纸,设计规定这辆车应该如何制造。这里的工程图纸就好比是语言中的 类 (class),而车就是按照这个 类(class制造出来的;另一方面,工人和机器 ( 相当于 constructor) 利用各种零部件如发动机,轮胎,方向盘 ( 相当于 prototype 的各个属性 ) 将汽车构造出来。

首先,客观世界中的对象的产生都是其它实物对象构造的结果,而抽象的“图纸”是不能产生“汽车”的,也就是说,类是一个抽象概念而并非实体,而对象的产生是一个实体的产生;

其次,按照一切事物皆对象这个最基本的面向对象的法则来看,类 (class) 本身并不是一个对象,然而原型方式中的构造器 (constructor) 和原型 (prototype) 本身也是其他对象通过原型方式构造出来的对象。

再次,在类式面向对象语言中,对象的状态 (state) 由对象实例 (instance) 所持有,对象的行为方法 (method) 则由声明该对象的类所持有,并且只有对象的结构和方法能够被继承;而在原型式面向对象语言中,对象的行为、状态都属于对象本身,并且能够一起被继承(参考资源),这也更贴近客观实际。

最后,类式面向对象语言比如 Java,为了弥补无法使用面向过程语言中全局函数和变量的不便,允许在类中声明静态 (static) 属性和静态方法。而实际上,客观世界不存在所谓静态概念,因为一切事物皆对象!而在原型式面向对象语言中,除内建对象 (build-in object) 外,不允许全局对象、方法或者属性的存在,也没有静态概念。所有语言元素 (primitive) 必须依赖对象存在。但由于函数式语言的特点,语言元素所依赖的对象是随着运行时 (runtime) 上下文 (context) 变化而变化的,具体体现在 this 指针的变化。正是这种特点更贴近 “万物皆有所属,宇宙乃万物生存之根本”的自然观点。

面向对象具有继承性。,它又分为冒充继承和真实继承。如例子:

function People(name,age,lover){               //用构造函数的方式构造一个名为people的类;从这个类当中我们可以构造许多子类。但是子类如何继承这个类的属性呢。请看下面例子

  this.name=name;

  this.age=age;

  this.lover=lover;

  this.run=function(){

  alert(this.name+"快对着天空大声说爱我")

  };

//构造一个子类man

function man(){

  this.figt="PK" //这个子类单独一个属性

  this.constructor(name,age,lover);//这一步相当重要,constructor就好比一个构造器,

//对象冒充法一

  this.inherit=people;

  this.inherit(name,age,lover);

  delete.this.inherit

}

//对象冒充法2,就是call()方法,这个方法就相当简单

people.call(this,name,age,lover)

//对象冒充法3,就是

people.apply(this,[name,age,lover])

简单吧!!这些对象冒充法就好比你伪装了自己,去继承别人的财产一样,

现在我门来讲讲真实继承

Man.prototype=new People();//这句话就是要说明man的原型就指向了people;所以他就会继承

var man=new man(“小胖”,18,“打飞机”);

console.log(man)