博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
构造函数的继承
阅读量:5095 次
发布时间:2019-06-13

本文共 4293 字,大约阅读时间需要 14 分钟。

1.构造函数其实就是一个普通函数,但是内部使用了this变量。对构造函数使用new运算符,就能生成实例,并且this变量会绑定在实例对象上。

 
function Cat(name,color){
    this.name=name;
    this.color=color;
      this.type = "猫科动物";
      this.eat = function(){
console.log("吃老鼠");};
  }
  var cat1 = new Cat("大毛","黄色");
  var cat2 = new Cat("二毛","黑色");
  console.log(cat1.name); // 大毛
  console.log(cat1.color); // 黄色
    //这时cat1和cat2会自动含有一个constructor属性,指向它们的构造函数。
    console.log(cat1.constructor == Cat); //true
    console.log(cat2.constructor == Cat); //true
    //instanceof运算符,验证原型对象与实例对象之间的关系。
    console.log(cat1 instanceof Cat); //true
    console.log(cat2 instanceof Cat); //true
    console.log(cat1.type); // 猫科动物
    cat1.eat(); // 吃老鼠

这样写的弊端:对于每一个实例对象,type属性和eat()方法都是一模一样的内容,每一次生成一个实例,都必须为重复的内容,多占用一些内存。这样既不环保,也缺乏效率。

 
console.log(cat1.eat == cat2.eat); //false

所以对于相同的属性和方法等,要用prototype去定义。上面的那两个公共部分应该如下写:

 
  Cat.prototype.type = "猫科动物";
  Cat.prototype.eat = function(){
console.log("吃老鼠")};

此时:

 
console.log(cat1.eat == cat2.eat); //true

其实这也是JavaScript继承机制的设计思想,所有实例对象需要共享的属性和方法,都放在prototype对象里面;那些不需要共享的属性和方法,就放在构造函数里面。

一些常用属性:

 
   console.log(Cat.prototype.isPrototypeOf(cat1)); //true
  console.log(Cat.prototype.isPrototypeOf(cat2)); //true
    //本地属性才为true,prototype继承的属性为false
  console.log(cat1.hasOwnProperty("name")); // true
  console.log(cat1.hasOwnProperty("type")); // false
  console.log("name" in cat1); // true
  console.log("type" in cat1); // true
    for(var prop in cat1) { //遍历属性,包括继承的
        console.log("cat1[" + prop + "]=" + cat1[prop]); 
    }
 

 

2.构造函数的继承

一、 构造函数绑定。使用call或apply方法,将父对象的构造函数绑定在子对象上。

 
    function Animal(){
    this.species = "动物";
  }
  function Cat(name,color){
    Animal.apply(thisarguments);
    this.name = name;
    this.color = color;
  }
  var cat1 = new Cat("大毛","黄色");
  console.log(cat1.species); // 动物

二、 prototype模式

 
 function Animal(){
    this.species = "动物";
  }
  function Cat(name,color){
    this.name = name;
    this.color = color;
  }
    console.log(Cat.prototype); //Object
    Cat.prototype = new Animal();
    console.log(Cat.prototype); //Animal
    //Cat的prototype对象指向一个Animal的实例,所以Cat也拥有constructor属性
    console.log(Cat.prototype.constructor);//function Animal(){this.species = "动物";}
    console.log(Cat.prototype.constructor == Animal);//true
    Cat.prototype.constructor=Cat;//如果没有这一句,cat1的构造函数就是上面的Animal,所以要把它更正为Cat
    console.log(Cat.prototype.constructor);//function Cat(name,color){this.name = name;this.color = color;}
  var cat1 = new Cat("大毛","黄色");
    console.log(cat1.species); // 动物
   console.log(cat1.constructor); //function Cat(name,color){this.name = name;this.color = color;}
    //也就是说,当替换了prototype对象
    //o.prototype = {};
    //必须要修正constructor
    //o.prototype.constructor = o;
 

 

前面两种方法是把属性直接定义在构造函数里,一般公共属性的话一般放在prototype,继承的方式如下

三、 直接继承prototype(不够完善)

 
 function Animal(){}
    Animal.prototype.species = "动物";
    function Cat(name,color){
    this.name = name;
    this.color = color;
  }
  Cat.prototype = Animal.prototype;
  Cat.prototype.constructor = Cat;
  var cat1 = new Cat("大毛","黄色");
  console.log(cat1.species); // 动物
    console.log(Cat.prototype.constructor);//function Cat(name,color){this.name = name;this.color = color;}
    console.log(Animal.prototype.constructor);//function Cat(name,color){this.name = name;this.color = color;}这样很混乱
    //与前一种方法相比,这样做的优点是效率比较高(不用执行和建立Animal的实例了),比较省内存。
    //缺点是 Cat.prototype和Animal.prototype现在指向了同一个对象,Cat.prototype与Animal.prototype永远保持一致,属性也是。

四、 利用空对象作为中介

 
    function Animal(){}
    Animal.prototype.species = "动物";
    function Cat(name,color){
    this.name = name;
    this.color = color;
  }
  function extend(ChildParent) {  //封装好
    var F = function(){};
    F.prototype = Parent.prototype;
    Child.prototype = new F();  //用空对象作为中介,避免了直接继承的弊端
    Child.prototype.constructor = Child;
    //Child.uber = Parent.prototype;//使之可以调用父对象的方法,实现继承的完备性
  }
    extend(Cat,Animal);
  var cat1 = new Cat("大毛","黄色");
  console.log(cat1.species); // 动物

五、 拷贝继承

 
   function Animal(){}
    Animal.prototype.species = "动物";
    function Cat(name,color){
    this.name = name;
    this.color = color;
  }
  function extend2(ChildParent) {
//封装好
    var p = Parent.prototype;
    var c = Child.prototype;
    for (var i in p) {
            console.log(i);
            console.log(p[i]);
      c[i] = p[i];
    }
    //c.uber = p;
  }
   extend2(CatAnimal);
  var cat1 = new Cat("大毛","黄色");
  console.log(cat1.species); // 动物

 

转载于:https://www.cnblogs.com/shen076/p/6556868.html

你可能感兴趣的文章
[HNOI2007]最小矩形覆盖
查看>>
人生难免有几次踩到大便的时候
查看>>
安卓开发利器 谷歌发布Android Studio工具
查看>>
超时设置
查看>>
工程代码目录结构及框架
查看>>
Ruby程序设计语言快速入门之变量与赋值
查看>>
比赛:小奔与不等四边形solution
查看>>
html块级元素和内联元素区别详解
查看>>
bzoj 1072状压DP
查看>>
用Java实现网络爬虫
查看>>
centos7部署DNS-1
查看>>
品牌和产品包装杂项
查看>>
三国反思录
查看>>
Win7 一键获得管理所有权限(最高权限)注册表
查看>>
清空Cookie
查看>>
电脑打开任务管理器出现卡顿
查看>>
[UE4]让箭头保持水平
查看>>
软件测试用例规范
查看>>
Mac常用软件推荐
查看>>
用keytool制作多域名证书
查看>>