zoukankan      html  css  js  c++  java
  • JavaScript笔记——面向对象与原型

    JavaScript也是一门面向对象的语言。面向对象的语言有一个标志,那就是类的概念,而通过类可以创建任意多个具有相同属性和方法的对象。但是,JavaScript竟然没有class,因此它的面向对象也与其他的OOP语言有所不同,创建对象和继承关系都显得很怪异很复杂难用

    创建对象

    JavaScript也采用了构造函数的概念:

    function Box(name, age) {   //构造函数模式
    this.name = name;
    this.age = age;
    this.run = function () {
    return this.name + this.age + '运行中...';
    };
    }
    var box1 = new Box('Lee', 100); 
    var box2 = new Box('Jack', 200);
    alert(box1.run());
    alert(box1 instanceof Box);   //很清晰的识别他从属于 Box

    构造函数的方法有一些规范:

    1.函数名和实例化构造名相同且大写,(非强制,但这么写有助于区分构造函数和普通函数)

    2.通过构造函数创建对象,必须使用 new 运算符(构造函数和普通函数的唯一区别,就是他们调用的方式不同。构造函数也是函 数,必须用 new 运算符来调用,否则就是普通函数了)

    构造函数示意图:

     

    原型的概念

    在创建类之前,先要有原型的概念,我们创建的每个函数都有一个 prototype(原型)属性,这个属性是一个对象,它的用途是 包含可以由特定类型的所有实例共享的属性和方法。简单地说原型就是实现共享的功能:比如说类里的方法和一些需要共享的属性(较少见)

    function Box() {}    //声明一个构造函数
    Box.prototype.name = 'Lee';    //在原型里添加属性
    Box.prototype.age = 100;
    Box.prototype.run = function () {    //在原型里添加方法
    return this.name + this.age + '运行中...';
    };
    var box1 = new Box();
    var box2 = new Box();
    alert(box1.run== box2.run);     //true,方法的引用地址保持一致

    在上面的run方法和name,age属性不论声明多少个对象都是相等的(共享了)


    原型示意图:

    在原型模式声明中,多了两个属性,这两个属性都是创建对象时自动生成的。__proto__ 属性是实例指向原型对象的一个指针,它的作用就是指向构造函数的原型属性 constructor。 通过这两个属性,就可以访问到原型里的属性和方法了。浏览器中无法获取其内部信息

    原型的声明是有先后顺序的,所以,重写的原型会切断之前的原型

    function Box() {};
    
    Box.prototype = { //使用原型创建属性和方法
    constructor : Box,
    name : 'Lee',
    age : 100,
    run : function () {
    return this.name + this.age + '运行中...';
         }
    };
    
    Box.prototype = {      //原型被重写了
    age :200
    };
    var box = new Box(); 
    alert(box.run());     //错误TypeError: box.run is not a function ,因为重写了原型,原来的原型方法,属性失效

    创建类与对象

    使用动态原型模式创建对象可以使方法成为共享的,而属性各是各的

    //动态原型模式创建对象
    function Box(name,age){
        this.name=name;
        this.age=age;
        
        if(typeof this.run!='function'){
            Box.prototype.run=function(){                //使用原型来实现方法共享
                return this.name+this.age+'运行时';
            };
        }
    }
    
    var box1=new Box('lz',21);
    var box2=new Box('Jack',20);
    alert(box1.run());
    alert(box2.run());

    继承

    继承是面向对象中一个比较核心的概念。其他正统面向对象语言都会用两种方式实现继承:一个是接口实现,一个是继承。而JavaScript只支持继承,不支持接口实现

    推荐使用寄生组合继承的方式:

    function obj(o) {           //传递一个字面量函数
    function F() {}             //创建一个构造函数
    F.prototype = o;          //把字面量函数赋值给构造函数的原型
    return new F();          //最终返回出实例化的构造函数
    }
    
    function create(box,desk){                 //将来传入父类和子类
        var f=obj(box.prototype);           //将父类的原型传入
        f.constructor=desk;                    //改变子类的constructor
        desk.prototype=f;                     //又将f传给子类的原型
    }
    
    function Box(name,age){            //父类
        this.name=name;
        this.age=age;
        this.arr=['爸爸','妈妈','儿子'];
        if(typeof this.run!='function'){
            Box.prototype.run=function(){
                return this.name+this.age+'运行时';
            }
        }
    }
    
    function Desk(name,age){                      //子类
        Box.call(this,name,age);                 //对象冒充
    }
    
    create(Box,Desk);                                  //通过这里实现继承
    
    
    //下面是证明不同子类对象互不影响(不同空间)
    var desk=new Desk('lz',21);
    desk.arr.push('女儿');
    alert(desk.arr);
    
    
    var desk2=new Desk('jack',20);
    alert(desk2.arr);
  • 相关阅读:
    _bzoj1061 [Noi2008]志愿者招募【最小费用最大流】
    _bzoj2243 [SDOI2011]染色【树链剖分】
    _bzoj1013 [JSOI2008]球形空间产生器sphere【高斯消元】
    _bzoj1002 [FJOI2007]轮状病毒【瞎搞】
    leetcode 273 Integer to English Words
    leetcode 12 Integer to Roman
    leetcode 1071 Greatest Common Divisor of Strings
    lc6 ZigZag Conversion
    lc13 Roman to Integer
    leetcode 171 Excel Sheet Column Number
  • 原文地址:https://www.cnblogs.com/lz2017/p/6786892.html
Copyright © 2011-2022 走看看