Js面向对象

作者: 高少辉_骚辉 | 来源:发表于2017-05-21 13:20 被阅读8次

    一、js中面向对象编程的几种形式

    1、静态类(直接json对象形式)

    var Person = {
        age : 15 ,
        name : "小明",
        say : function( msg ){
          console.log( msg );
        }
    };
    console.log( Person.age ); //=>15
    Person.say( "Person say" ); //=>"Person say"
    

    特点:

    • 书写方便,不容易扩展

    2、构造函数方式

    (1)公有属性,方法(prototype原型链方式)
    function Person( name, age ){
        this.init( name , age );
    }
    Person.prototype.init = function( name, age ){
        this.age = age;
        this.name = name;
    };
    Person.prototype.age = 0;
    Person.prototype.name = "";
    Person.prototype.say = function ( msg ){
        console.log( msg );
    };
    
    var xiaoming = new Person( 'xm', 10 );
    console.log(xiaoming.age); //=>10
    console.log(xiaoming.name); //=>'xm'
    xiaoming.say( "say xm ok" ); //=>"say xm ok"
    

    特点:

    • 比较像其它有class面向对象编程语言的书写方法,容易接受
    • 在内存中只有一份,提高了程序的执行效率,减少了存储空间
    • prototype写的方法不能访问,构造函数里面声明的私有方法(缺点)
    (2)特权属性、方法
    function Person( name , age ){
        this.name = name;
        this.age = age;
        this.say = function( msg ){
            console.log( msg );
        };
    }
    
    var xiaoming = new Person( 'xm', 25 );
    console.log( xiaoming.name ); //=>'xm'
    console.log( xiaoming.age ); //=>25
    xiaoming.say( "say xm ok" ); //=>"say xm ok"
    

    特点:

    • 每实例化一个对象,就都在内存中挂载上属性和方法,比较浪费内存,程序执行效率会变低
    (3)私有属性、方法(闭包)
    function Person( nameInit, ageInit ){
     var name = nameInit;
     var age = ageInit;
     var say = function( msg ){
        console.log( msg );
     };
     this.print = function(){
        console.log(name);
        console.log(age);
     };
    }
    
    var xm = new Person( "xm", 111 );
    xm.print(); //=>"xm" => 111
    

    在js中由于没有专门写类的class,所以没有private这个私有属性和方法,但是利用js的作用于的特性我们可以在js构造函数中定义的变量,外部无法访问,所以后人称这为私有属性和方法
    特点:

    • 这里的私有属性方法能被,构造函数、特权方法、私有方法进行访问,公有方法(prototype原型)不可以访问,说的更简单一点就是,只能被在构造函数里面定义的函数进行访问

    3、另一种构造函数,不用new出来的实例对象,用js的特性:

    function Person( nameInit, ageInit, heightInit ){
        var name = nameInit,
            age = ageInit,
            height = heightInit, //私有
            say = function( msg ){
                console.log( msg );
            };
    
        return { //这边放出接口(返回公有属性和方法)
            name : name,
            age : age,
            say : say
        };
    }
    
    var xm = Person( 'xm', 20 , 175 );
    console.log( xm.height ); //=>undefined
    console.log( xm.name ); //=>'xm'
    xm.say("say xm"); //=>"say xm"
    

    特点:和特权方式一样

    二、js继承

    //先写一个父亲
    function Person( name, age ){
        this.age = age;
        this.name = name;
    }
    Person.prototype.age = 15;
    Person.prototype.name = '用来继承Person';
    Person.prototype.say = function( msg ){
        console.log( msg );
    }
    

    继承方式1:公有的方式继承

    function Student( name , age ){}
    Student.prototype = new Person( '', 23 );
    
    var obj = new Student( 'xx', 555 );
    
    console.log(obj.name); //=>'用来继承Person'
    console.log(obj.age); //=>15
    obj.say('aa');
    

    原理:new 出父亲的得实例,这样这个实例拥有父亲的所以属性、方法,利用js特性,直接赋值给Student的原型,这里因为new出来的实例的属性和方法也是在原型上的,故出现了一个原型链,以后有机会在探讨

    继承方式2:利用内部函数,call(),apply()函数进行函数进行属性的拷贝

    function Student( name , age ){
        Person.apply( this, [name,age] );
    }
    
    var obj = new Student( 'xm' , 1 );
    console.log( obj.name ); //=>'xm'
    obj.say( 'bb' ); //=>'bb'
    

    原理:拷贝 Person实例化出来的特权的属性、方法给子类的 实例化对象
    缺点:不能拷贝Person的公有属性、方法(原型上)
    call()和apply() 的区别只是 传参数父类的构造函数的方式不同:

    function Student( name, age ){
       // Person.apply( this, [name,age] );
       Person.call( this, name, age );
    }
    

    call():直接在在传实例化this,后面跟着参数
    apply():把参数,放到一个数组里
    ps:两个传参数的顺序都要和Person这个构造函数的参数顺序一致

    继承方式3:遍历方式

    function Student( name, age ){
        var Child = new Person( name, age );
        for( var i in Child ){
            this[i] = Child[i];
        }
    }
    
    var obj = new Student( 'xm', 1 );
    
    console.log(obj.name); //=>'xm'
    obj.say('aa'); //=>'aa'
    

    原理:利用js的对象特性,在构造函数中创建一个对象,把这个对象上面的非私有的属性、方法全部拷贝给实例化出来的对象

    ps:上面写出的继承方式,都是单独列出来的,他们各有各的优点,所以你在运用的过程中,也可以随意的组合,结合他们各自的优势,这样写出更漂亮的代码

    相关文章

      网友评论

        本文标题:Js面向对象

        本文链接:https://www.haomeiwen.com/subject/sfnmxxtx.html