JavaScript中的面向对象

面向对象

  技术一般水平有限,有什么错的地方,望大家指正。

  面向对象只是一种编程模式并不是某一种语言特有的在很多种语言上都有体现。面向对象编程是用抽象方式创建基于现实世界模型的一种编程模式(很官方的一个定义),它有四个基本特性抽象、继承、封装、多态。在JS中我们运用的最多的就是封装和继承。

  面向对象编程即以对象为核心通过对象调用方法来完成一套处理流程,假如我们如下需求:生成两个随机数,计算这个两个随机数的和,我们通常这样写:

  function calculate(){
      var num1 = Math.floor(Math.random()*100);
      var num2 = Math.floor(Math.random()*100);
      var result = num1+num2;
      return result;
  }
  console.log(calculate());

  用面向对象的方式来进行改写:

  var factory = {
      create:function(){
          return Math.floor(Math.random()*100);
      }
  }
  var tool = {
      add:function(a,b){
          return a+b
      }
  }
  function calculate(){
      var num1 = factory.create();
      var num2 = factory.create();
      var rerult = tool.add(num1,num2);
      return rerult;
  }
  console.log(calculate());

  我们将生成随机数和计算过程由两个对象来完成,不过看起来更麻烦了,这是因为代码逻辑较为简单,在一个复杂的处理过程中它的优势就会显出来。

  面向对象最大的好处就是易于维护,假如我们现在要对产生的随机数加一个约束:产生的随机数自动加10,此时我们只需要在factory中改写create函数即可,calculate函数的处理过程不需要有任何更改,假如calculate里面创建10个随机数用原来的写法就需要改10处,而面向对象的写法只需要改一处即可。

  封装的一大好处就是进行复用,直接使用不用管它的内部处理流程,只要把参数传递进行就能达到我们预想的结果。

JS中的构造函数

  我们可以直接使用一个对象,为这个对象附加一些属性来达到面向对象的效果。但是用的最多的还是构造函数的形式,构造函数即用来生产对象的一个工厂,基本实现方式为:

  function Person(name,age){
      this.name = name;
      this.age = age;
  }
  Person.prototype.say = function(){
      console.log("你好,我是"+this.name)
  }
  Person.prototype.show = function(){
      console.log("年龄"+this.age+"一名小学生!");
  }

  我们将属性写在构造函数Person里面,将函数写在原型上面,这样在执行new操作时新创建出来的对象既有自己的属性也有自己的方法。new的一个处理流程:创建一个对象,将构造函数里面的this指向这个对象,同时新建对象的原型链指向构造函数的原型,最后执行构造函数。

  既然new的时候会将构造函数里面的this指向新创建的对象,为什么不将函数也定义在构造函数里面:this.say = function(){}?事实是为了避免新建对象变得太过臃肿,一般实例化对象的属性是不同的,而函数是相同的,函数会形成一个独立的作用域不会互相干扰,而JS通过原型链让实例化的对象使用原型上的函数,所以我们一般将属性定义在构造函数里面,函数定义在原型上。

原型链

  

  实例化出来的对象有一个__proto__属性指向构造函数的原型(Person.prototype)上面。

  对象的“.”操作就表示存取,比如obj.name = "zt",表示设置属性,在对象obj上创建一个属性,如果当前对象存在就重新赋值,如果不存在就进行创建并赋值。与存对应的就是取:obj.name,当取操作时原型链的作用就显示出来了,对象obj会优先在自身下面查找name属性,如果属性不存在就会沿着原型链查找,一直找到Object.prototype上面(原型链的末端),如果还是不存在就会返回undefined。

函数的继承

  如果我们需要一个新的函数,而现在存在一个相似度80%的函数,我们就可以继承该函数,然后在改写一部分内容,节约我们的开发时间。

  假如我们有一个构造函数Person:

 function Person(name,age){
     this.name = name;
     this.age = age;
 }
 Person.prototype.say = function(){
     console.log("我是"+this.name);
 }

  现在我们需要一个动物类:Animal它name和age属性say函数,另外动物还有一个毛色color的属性,同时不用工作(work),现在我们用继承来实现Animal:

 function Animal(name,age,color){
     Person.call(this,name,age);
     this.color = color;
 }
 Animal.prototype = Object.create(Person.prototype);
 Animal.prototype.work = function(){
     console.log("我不用工作");
 }

  现在测试一下结果:

 var me = new Person("zt",23);
 me.say();//我是zt
 me.work();//报错提示不存在work方法
 console.log(me.age)//23
 var dog = new Animal("旺财",2,"黑毛");
 dog.say();//我是旺财
 dog.work();//我不用工作
 console.log(dog.age);//2

  哪个都能正常使用说明继承是成功的。

  Person构造函数分为两个部分:属性和方法,所以继承的时候我们分别继承属性和方法即可。

  属性继承我们采用对象属性扩展的方式来实现,我们把Person函数里面的this通过call函数改为Animal函数里面的this,这样Person函数执行完成的时候就会为Animal函数的this添加name和age属性,然后Animal函数在为自己添加一个color属性。

  方法的继承我们采用Object.create()来实现,Object.create(arg)该函数会创建一个对象,并且创建对象的原型链指向参数arg,看我们上面的代码,Animal的原型的原型链指向Person的原型,实例化对象dog原型链指向Animal的原型:

  实例化Animal会产生一个dog对象,dog对象原型链指向Animal.prototype,Animal.prototype对象的原型链指向Person.prototype,这样就将这几个对象串联起来了,比如dog.say(),dog对象优先在自身下面查找该属性,不存在就会沿着原型链去Animal.prototype上查找,还是不存在继续沿着原型链查找,直到找到该属性,或者查找到尽头还是不存在就会返回undefined。

  上面的继承方式还存在一个缺陷,我们看上面的代码:

 dog.constructor;//Person函数

  所以我们还要修复这个问题,手动控制改变dog对象的构造器,在继承完原型函数之后修正构造器指向即可解决:

 Animal.prototype.constructor = Animal;

  另外常用的一种函数的继承就是将Person.prototype上面的方法拷贝到Animal.prototype上。

转载 地址:http://www.cnblogs.com/shinhwazt/

时间: 2025-01-01 21:01:36

JavaScript中的面向对象的相关文章

如何理解并学习javascript中的面向对象(OOP) [转]

如果你想让你的javascript代码变得更加优美,性能更加卓越.或者,你想像jQuery的作者一样,写出属于自己优秀的类库(哪怕是基于 jquery的插件).那么,你请务必要学习javascript面向对象,否则你无法更灵活的使用javascript这门语言. 什么事闭包?到底什么是原型?(知道闭包和原型的,就算得上是javascript的高手了.但真正能够理解,并且灵活运用的人并不多)到底该如何学习javascript中的面向对象呢?在javascript这么语言正如日中天,相信不少人正在为

前端开发:面向对象与javascript中的面向对象实现(一)

前端开发:面向对象与javascript中的面向对象实现(一) 前言: 人生在世,这找不到对象是万万不行的.咱们生活中,找不到对象要挨骂,代码里也一样.朋友问我说:“嘿,在干嘛呢......”,我:“找不到对象!”,他:“就你那样也能找得到对象?”.我一脸黑线...... 废话不多说,今天博主要跟大家聊的是<面向对象与javascript中的面向对象实现>”. 面向对象理解: 面向对象是一种对现实世界理解和抽象的方法,是一种先进的程序设计理念,是一种比较抽象的,多形态的设计模式.我们可以这么理

前端开发:面向对象与javascript中的面向对象实现(二)构造函数与原型

前端开发:面向对象与javascript中的面向对象实现(二)构造函数与原型 前言(题外话): 有人说拖延症是一个绝症,哎呀治不好了.先不说这是一个每个人都多多少少会有的,也不管它究竟对生活有多么大的影响,单单是自己的念想受到了一定得局限,想法不能够像平地而起的高楼大厦建成一样.可是那大楼也是有烂尾的呀,我觉得最重要的还是外在环境与个人观念的先决条件,决定了拖延症的症状的好坏,有那么一些人,它也有拖延症,但是它在拖的中间,想的更多,看的更远.事情在做的时候更加有条不紊,这拖延症这样看来,它也是好

javascript中的面向对象(object-oriented)编程

本文原发于我的个人博客,经多次修改放到csdn上,主要是做备份用,为了更好的阅读体验,请到我的个人博客上阅读. 最近工作一直在用nodejs做开发,有了nodejs,前端.后端.脚本全都可以用javascript搞定,很是方便.但是javascript的很多语法,比如对象,就和我们常用的面向对象的编程语言不同:看某个javascript开源项目,也经常会看到使用this关键字,而这个this关键字在javascript中因上下文不同而意义不同:还有让人奇怪的原型链.这些零零碎碎的东西加起来就很容

javascript 中的面向对象中比较好的资料

http://www.ruanyifeng.com/blog/2011/06/designing_ideas_of_inheritance_mechanism_in_javascript.html http://www.ruanyifeng.com/blog/2010/05/object-oriented_javascript_encapsulation.html http://www.ruanyifeng.com/blog/2010/05/object-oriented_javascript_

JavaScript中OOP——&gt;&gt;&gt;面向对象中的继承/闭包

  前  言  OOP  JavaScript中OOP-->>>面向对象中的继承/闭包 1.1面向对象的概念 使用一个子类继承另一个父类,子类可以自动拥有父类的属性和方法.      >>> 继承的两方,发生在两个类之间. 1.2JS模拟实现继承的三种方式:        首先,了解一下call/apply/binb:通过函数名调用方法,强行将函数中的this指向某个对象:            call写法:  func.call(func的this指向的obj,参数

javaScript中的面向对象表示

我们知道,面向对象的语言都有一个特点,那就是一般都有类的概念,进而有类的属性和方法等概念. 然而javaScript中并没有类的概念,那我们怎么去通过这个语言本身去实现一些面向对象的特性呢? (1)一个最简单的方式 创建Object的实例,为它添加属性和方法 var car = new Object(); //创建实例 car.color = "red"; //为car这个对象增加颜色的属性 car.showColor= function(){ //car的方法 alert(this.

javascript 中的面向对象实现 如何封装

面向对象的手法来封装javascript ,javascript是没有类的概念的. 所以今天谈到的封装,其实就是用javascript的函数来实现的. 1 2 3 4 var People{ name:’一介布衣’, age:’30' }; 这就是javascript中的一个对象,里面封装了2个属性. 实例化一个对象的实例 people 1 2 var people=new People(); console.log(people.name,people.age);  //一介布衣,30 如果我

深入理解javascript中实现面向对象编程方法

介绍Javascript中面向对象编程思想之前,需要对以下几个概念有了解: 1. 浅拷贝和深拷贝:程序在运行过程中使用的变量有在栈上的变量和在堆上的变量,在对象或者变量的赋值操作过程中,大多数情况先是复制栈上的信息,这样就会出现以下情况,如果变量是对象,那么这一操作,复制的只是真正对象所在 的堆内存空间的起始地址,这就是所谓的浅拷贝,如果是深拷贝,则是在内存堆空间中重新分配一个内存,并把分配的内存的起始地址复制过去. 2. 引用类型数据和值类型数据:谈到引用类型数据和值类型数据,自然而然的联想到

深入JavaScript(一)——JavaScript中的面向对象(一)

面向对象的语言有一个标志,那就是它们都有"类"的概念,通过类可以创建任意多个具有相同属性和方法的对象.JavaScript 中没有类的概念,因此它的面向对象与基于类的语言中的对象有所不同. JavaScript 对对象的定义是:无序属性的集合,其属性可以包含基本值.对象或者函数.可以把 JavaScript 对象理解成散列表,即一组名值对,其中的值可以是数据或函数. 那么想要创建自定义对象,有以下几种常用方法: 1.使用 Object 构造函数: var person = new Ob