Headfirst JS :使用原型:超强的对象创建方式

原型式继承:javascript根本没有类,对象从其他对象那里继承方法(成员函数),我们称之为原型式继承或者基于原型的继承。其中,其 成员函数 被继承的对象称为 原型;

一、再谈构造函数:它能让我们重用代码,但是效率如何呢?

function Dog(name,breed,weight){
  this.name=name;
  this.breed = breed;
  this.weight = weight;
  this.bark = function(){
   if(this.weight > 25) alert(this.name +"says Woof!");
   else alert(this.name + "says Yip!");
  };
}

var fido = new Dog("Fido","Mixed",38);
var fluffy = new Dog("fluffy","Poodle",30);
var spot = new Dog("Spot","Chihuahua",10);

//每一次new 都会执行一次构造函数的代码,每执行一次构造函数的代码,都会在内存中开辟一块来存储匿名函
//数function(),然后将其地址返回。这样执行三次,相当于开辟了三块内存来存function,占用了不必要的内存。

二、原型式继承:

继承的工作原理:对对象调用方法或者属性时,如果在对象中找不到,将在原型中查找它。

重写原型:因为js总是 先在对象实例中查找属性,如果找不到,再沿着原型链上移,在原型中查找,因此,如果在对象实例中重写原型中的属性或者方法,js查找时在对象实例中找到了它,就不会费神去原型中查找了。

原型从哪里来?

Dog.prototype 

如果你查看构造函数Dog,将发现它有一个prototype属性,这是一个指向原型的指针变量。
PS:js中函数也是对象,实际上,js中万物皆对象

如何设置原型?

    function Dog(name,breed,weight){
           this.name = name;
           this.breed = breed;
           this.weight=weight;
       }
      
   //设置小狗原型对象
       Dog.prototype.bark = function(){
           if(this.weight > 25){
               console.log(this.name + "says Woof!");
           }else{
               console.log(this.name + "says Yip!");
           }
       };
    //你可能会错误地认为 原型对象中的this指向原型对象,其实,原型对象的this仍然指向调用该方法的对象。
       Dog.prototype.run = function(){
           console.log("run!");
       };
       Dog.prototype.wag=function(){
          console.log("Wag!");
       };

      var fido= new Dog("Fido","Mixed",38);
      var fluffy = new Dog("Fluffy","Poodle",30);
      var spot = new Dog("Spot","Chihuahua",10);
     
     //重写原型
      spot.bark = function(){
        console.log(this.name+"says Woof!");
      }

      fido.bark();
      fido.run();
      fido.wag();

      fluffy.bark();
      fluffy.run();
      fluffy.wag();

      spot.bark();
      spot.run();
//在代码中判断使用的属性包含在实例还是原型中
     spot.hasOwnProperty("name");
//属于实例则返回true

建立原型链:

     function Dog(name,breed,weight){
           this.name = name;
           this.breed = breed;
           this.weight=weight;
        //方法
           this.bark = function(){
           if(this.weight > 25){
               console.log(this.name + "says Woof!");
           }else{
               console.log(this.name + "says Yip!");
           }
       };
       this.run = function(){
           console.log("run!");
       };
       this.wag=function(){
          console.log("Wag!");
       };

    }
       
       
       function ShowDog(name,breed,weight,handler){
           Dog.call(this,name,breed,weight);
          /*
          call是一个内置方法,可以对任何函数调用它,Dog.call调用
          函数Dog,将一个用作this的对象指针以及函数Dog的所有实参
          传递给它。
          形参中的this(ShowDog的对象实例的地址)将被赋值给Dog函数中的this,
          这样Dog函数将被用来初始化ShowDog的实例对象。 
          */
           this.handler=handler;
       }
       
       //1.设置ShowDog的对象实例的原型 的原型 为一个Dog的实例对象
       ShowDog.prototype = new Dog();
       /*
        这里没有给Dog传参,那么Dog创建的对象实例中属性值都是未定义的。
       */

       //2.设置ShowDog的对象实例的原型
       ShowDog.prototype.league="Webville";
       ShowDog.prototype.stack =function(){
          console.log("stack");
       };
    
    //3.创建对象实例  
      var fido= new Dog("Fido","Mixed",38);
      var fluffy = new Dog("Fluffy","Poodle",30);
      var spot = new Dog("Spot","Chihuahua",10);
      spot.bark = function(){
        console.log(this.name+"says Woof!");
      }
      var scotty = new ShowDog("scotty","scottish terrier",15,"Cookie");


      fido.bark();
      fluffy.run();
      spot.wag();
      scotty.stack();
      scotty.run();

小狗原型并非原型链的终点,因为小狗原型是从Object派生出来的,你创建的每个原型链的终点都是Object,这是因为对于你创建的任何实例,其默认原型都是Object。

Object对象的toStirng方法常常被重写

function Robot(name,year,owner){
  this.name = name;
  this.year =year;
  this.owner = owner;
 }

var toy = new Robot("Toy",2013,"Aray");
console.log(toy.toString);//[Object]

//重写toString

Robot.prototype.toString = function(){
  return this.name + "Robot belongs to"+ this.owner;
}

var toy = new Robot("Toy",2013,"Aray");
console.log(toy.toString);//[Object]

有些情况下,会自动调用方法toString,无须你直接调用它,例如,如果你使用运算符+来拼接字符串和对象,js将会自动调用toString将对象转换成字符串,再将该字符串与另一个字符串拼接起来。

console.log("Robot is:"+toy);

如果toString 被重写,这里将调用重写后的方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
自动控制节水灌溉技术的高低代表着农业现代化的发展状况,灌溉系统自动化水平较低是制约我国高效农业发展的主要原因。本文就此问题研究了单片机控制的滴灌节水灌溉系统,该系统可对不同土壤的湿度进行监控,并按照作物对土壤湿度的要求进行适时、适量灌水,其核心是单片机和PC机构成的控制部分,主要对土壤湿度与灌水量之间的关系、灌溉控制技术及设备系统的硬件、软件编程各个部分进行了深入的研究。 单片机控制部分采用上下位机的形式。下位机硬件部分选用AT89C51单片机为核心,主要由土壤湿度传感器,信号处理电路,显示电路,输出控制电路,故障报警电路等组成,软件选用汇编语言编程。上位机选用586型以上PC机,通过MAX232芯片实现同下位机的电平转换功能,上下位机之间通过串行通信方式进行数据的双向传输,软件选用VB高级编程语言以建立友好的人机界面。系统主要具有以下功能:可在PC机提供的人机对话界面上设置作物要求的土壤湿度相关参数;单片机可将土壤湿度传感器检测到的土壤湿度模拟量转换成数字量,显示于LED显示器上,同时单片机可采用串行通信方式将此湿度值传输到PC机上;PC机通过其内设程序计算出所需的灌水量和灌水时间,且显示于界面上,并将有关的灌水信息反馈给单片机,若需灌水,则单片机系统启动鸣音报警,发出灌水信号,并经放大驱动设备,开启电磁阀进行倒计时定时灌水,若不需灌水,即PC机上显示的灌水量和灌水时间均为0,系统不进行灌水。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值