• JavaScript学习3:原型和继承


            原型

            我们创建的每个函数都有一个prototype(原型)属性,这个属性是一个对象,它的用途是包括能够由特定类型的全部实例共享的属性和方法。逻辑上能够这么理解:prototype是通过调用构造函数而创建的那个对象的原型对象。

            为什么要引入原型的概念呢?使用原型的目的。也是他的优点是能够让全部的对象实例共享它所包括的属性和方法。换句话说,就是不必再构造函数中定义对象信息,而是能够直接将这些信息加入到原型中。

            详细怎么用,我们来看代码实例:   

    <span style="font-size:18px;">//原型实例
    function Person(){}   //声明一个构造函数
    
    Person.prototype.name='Lian';   //在原型里加入属性
    Person.prototype.age=100;
    Person.prototype.run=function(){    //在原型里加入方法
    	return this.name + this.age + '奋斗中……';
    };
    
    var person1=new Person();
    var person2=new Person();
    alert(person1.run==person2.run);   //返回true,说明方法的引用地址是一致的。即两个对象共享了一个方法</span>

            为了更好的理解构造函数的声明方式和原型模式的声明方式的差别,我找了两张图分享给大家。帮助大家理解:

            

            我们从图中能够看到,在原型模式声明中。多了两个属性,这两个属性都是创建对象时自己主动生成的。_proto_属性是实例指向原型对象的一个指针,它的作用就是指向构造函数的原型属性constructor。通过这两个属性,就能够訪问到原型里的属相和方法了。

            看到这里你会认为奇怪。上面代码实例中的构造函数的函数体中什么也没有。才干訪问到原型对象里的值,假设函数体中有属性或者方法呢?这里就要涉及一个原型模式运行流程的问题了:是先去查找构造函数实例里面的属性和方法,假设有。立马返回,若没有,则去它的原型对象中找。若有,则返回。

            使用原型模式创建对象也有其缺点,那就是它省略了构造函数传參初始化这一过程。带来的缺点就是初始化的值都是一样的。可是这恰恰是它最大的长处,那就是共享。

            继承

            继承是面向对象中的一个核心概念,在比較正统的面向对象的语言中一般都会採用两种方式实现继承:一个是接口实现,一个是类继承。而我们的JavaScript仅仅支持继承。而不支持接口实现,继承是怎样实现的,这里要引入原型链的概念了。什么是原形链。我们看一段代码就会知道。

    <span style="font-size:18px;">//继承实例
    function A(){
    	this.name ='Lian';
    }
    
    function B(){
    	this.age=100;
    }
    
    function C(){
    	this.address='中国';
    }
    B.prototype.age =200;
    B.prototype =new A();  //B继承了A
    
    C.prototype =new B();  //C又继承了B
    
    var c=new C();
    alert(c.name+' '+ c.age);  //C具有了A和B的属性</span>

            在JavaScript中,被继承的函数称为超类型(也就是面向对象中说的父类或者说是基类),继承的函数称为子类型(即子类或者派生类)。继承有优点。可是也有其自己的问题,比方字面量重写原型会中断关系,使用引用类型的原型,而且子类型无法给超类型传递參数。

            综合考虑,我们使用原形链加上构造函数,这样产生了组合继承。      

    <span style="font-size:18px;">//组合继承
    function Box(age){
    	this.name='Lee';
    	this.age=age;
    }
    
    Box.prototype.run=function(){
    	return this.name +this.age;
    };
    
    function Desk(age ){
    	Box.call(this,age);   //对象冒充,给超类型传參
    }
    
    Desk.prototype =new Box();   //原形链继承
    
    var desk =new Desk(100);
    alert (desk.run());   //显然Desk继承了Box的run方法</span>

            组合继承是JavaScript最经常使用的继承方式,可是,组合继承也有一点问题。那就是超类型在使用过程中会被调用两次。一次是创建子类型的时候。一次是在子类型构造函数的内部。

    这样会带来性能上的开销,怎样解决?留给读者去思考……

  • 相关阅读:
    dwSun带你选Python的编辑器/IDE
    ubuntu中文乱码解决
    解决matplotlib中文显示
    1506.01186-Cyclical Learning Rates for Training Neural Networks
    1503.02531-Distilling the Knowledge in a Neural Network.md
    1804.03235-Large scale distributed neural network training through online distillation.md
    mysql导入太慢解决方法
    已某个时间单位(日月周年)来分割时间段
    阿里云邮件推送
    阿里云短信推送服务
  • 原文地址:https://www.cnblogs.com/tlnshuju/p/6884104.html
Copyright © 2020-2023  润新知