javascript里边的继承

javascript里面的继承

/**
 * 构造对象
 * 通过构造函数操作this构造出的对象,不但具有各自的成员数据还有各自的方法数据,即方法的代码体在每个对象中都存在着一个副本
 * 也就是说每个对象是调用自己的方法,而不是像java等语言中所有对象都是调用的同一个方法的引用,
 * 即每个对象的方法的引用是不同的,尽管它们的逻辑是一样的
 * */

 

function Student(name){
 this.name = name;
 this.say = function(){
  alert(this.name);
 };
}

function Compute_Student(name,subject){
 Student.call(this,name);
 this.subject = subject;
 this.hello = function(){
  alert(this.name+" "+this.subject);
 };
}

var student = new Student("李四");
var compute_student = new Compute_Student("张三","物理");
student.say();
compute_student.say();
compute_student.hello();
alert(student.constructor==Student);
alert(compute_student.constructor==Compute_Student);
alert(student.say == compute_student.say);//false

 

//改进

function jump(){
 alert(this.name +" 跳啦");
}

function Human(name){
 this.name = name;
 this.jump = jump;
}

var human1 = new Human("王五");
var human2 = new Human("赵六");
human1.jump();
human2.jump();
alert(human1.jump == human2.jump);//结果为true

 
//缺点是看不出jump与Human的关系

 

继续改进使用prototype

 /**
  * prototype chain
  * 我们定义的对象都是继承自Object对象,Object.prototype的属性可以被我们定义的对象使用
  * 那么自定义的对象如何继承其它的类呢  myclass.prototype = new Object()相当于将myclass继承于Object,
  * 继承之后,myclass生成的对象可以使用Object.prototype里面的属性
  * */
 

function Worker(name){
  this.name = name;
 }
 Worker.prototype.say = function(){
  alert("我的名字是:"+this.name);
 };
 
 function Employee(name,age){
//  this.superclass(name);为什么不对
  Worker.call(this,name);
  this.age = age;
 }
// Employee.prototype.superclass = Worker;
 Employee.prototype = new Worker();//构成prototype chain
 Employee.prototype.goodbye = function(){
  alert(this.name+"年龄"+this.age+" goodbye");
 };
 var employee = new Employee("smiky",25);
 var worker = new Worker("monoxide");
 employee.goodbye();
 employee.say();
 alert(employee.say == worker.say);

 

/**
 * javascript用构造函数构造对象的步骤:
 * 1.新建一个对象new Object();
 * 2.将该对象内置的原型对象设置成构造函数引用的原型对象
 * 3.将该对象作为this参数调用构造函数
 * */
 
 /**
  * 基于上面的步骤,测试一
  * 构建一个对象(作为prototype对象使用),将其引用替代某构造函数的prototype对象
  * 即用prototype对象来描述类
  * */

 function Test1(){}
 var Cat = {
  init : function(name,age){
   this.name = name;
   this.age = age;
  },
  say : function(){
   alert("我的名字是:"+this.name +"  年龄:"+this.age);
  }
 };
 Test1.prototype = Cat;
 var test1 = new Test1();
 test1.init("小王",30);
 test1.say();

 
 /**
  * 这里的Test1感觉就是个过渡,什么作用都没有起到,这里的test1不管怎么样看都是Cat
  * 可能有人会想,那么我用var obj = new Object()构建一个对象,然后将这个对象的prototype属性找成自己需要的
  * 不就行了吗?
  * 问题在于无法获取到对象的prototype对象
  * */

 

/**
  * 更上一层楼,既然无法获取到prototype,那么我们是否可以构建一个通用的函数,
  * 将所需要的用于构建对象的临时function(如上面的Test1)内嵌
  * */
 

function Class(prototype,params){//根据传递进来的原型对象构建对象
  function new_(){
   prototype.init.apply(this,params);
  };
  new_.prototype = prototype;
  return new new_();
 }
 //定义用于述Dog的prototype对象
 var Dog = {
  init : function(name,age){
   this.name = name;
   this.age = age;
  },
  speak : function(){
   alert(this.name +" "+this.age);
  }
 };
 var dog = Class(Dog,["旺旺",2]);
 dog.speak();
 Dog.swim = function(){
  alert(this.name +"在游泳哦");
 };
 dog.swim();

 

/**
  * 最终版
  * */

 var object =//定义一个基础类,所有的类都继承自它
 {
  isClass : function(type)
  {
   var self = this;
   var _type = this.Type;
   if(_type == type)
   {
    return true;
   }
   return false;
  }
 };
 
 function CreateClass(superclass,classDefination){
  function class_(){
   this.Type = superclass;
   for(var obj in classDefination)//将类定义中的属性全部设定会当前生成的对象
   {
    this[obj]=classDefination[obj];
   }
  }
  class_.prototype = superclass;//将当前的prototype设成基类,构建prototype关联
  return new class_();//返回构建的对象
 }
 
 function CreateObject(prototype,params)//根据给定的类构建对象
 {
  function new_(){
   prototype.init.apply(this,params);//类中必须有个init方法专门用于被始化对象
  }
  new_.prototype = prototype;
  return new new_();
 }
 
 var Animal = CreateClass(object,//购建一个Animal类
  {
   init : function(type)
   {
    this.type = type;
   },
   song : function()
   {
    alert(this.type+"在唱歌哦");
   }
  }
 );
 
 var Mouse = CreateClass(Animal,//购建一个Mouse类
  {
   init : function(type,name)
   {
    Animal.init.apply(this,["老鼠"]);
    this.name = name;
   },
   eat : function()
   {
    alert(this.type+" "+this.name+"在吃东西哦");
   }
  }
 );
 
 var mouse = this.CreateObject(Mouse,["","小白"]);
 var animal = this.CreateObject(Animal,["猫"]);
 mouse.song();
 mouse.eat();
 animal.song();
 alert(animal.song == mouse.song);//true说明Mouse与Animal的对象调用的是同一个方法的引用

  
 /**
  * 可能对this会产生迷惑,this表示当前调用该方法的对象,而且同prototype一样,也存在着一个this chain
  * */
 function this_test(){
  this.alert('abc');//那么此方法在执行时,该方法体内并没有alert方法,
      //那么它就会向上一级的对象中查找alert,谁有alert,this将代表谁,如这里代表window
 }