美文网首页Web前端之路
review javascript 24:面向对象

review javascript 24:面向对象

作者: 蝴蝶结199007 | 来源:发表于2017-05-08 21:28 被阅读28次

    (1)知识点

    • (1.1)定义
    • (1.2)创建对象
    • (1.3)原型与原型链
    • (1.4)特点

    (2)细化

    (2.1)定义

    对象:程序中描述一个现实中具体事物的属性和方法的结构
    比如汽车是一个对象,车的品牌,颜色就是属性;启动,停止,加速,双闪,刹车都是车子的方法
    面向对象:面向对象编程中,描述一个具体事物都需要用对象来封装对象的属性和方法
    比如:rest软件架构中,都是按照对象的模块进行划分,比如人员管理,资源管理
    /user/id1234

    写任何程序,都要先找对象,再识别对象的属性和功能

    (2.2)创建对象

    (a)json对象

    var obj = {"属性名":"值","属性名":"值",...};
    

    (b)定义一个空的对象:

    var obj = new Object();
    var obj =  {};
    

    (c)定义function
    定义一个构造函数:

      function 类型名(属性参数列表) {
            this.属性名 = 参数值;
            this.属性名 = 参数值;
            this.方法名 = function () {
                ......
            }
        }
    

    用new调用构造函数,装饰一个新创建的对象:

    var obj = new 类型名(属性值,... ...);
    

    (2.3)原型与原型链

    link:http://www.jianshu.com/p/1526fcdc4466

    (2.4)特点

    面向对象三大特点:【封装】、【继承】、【多态】;
    多态又包括重写和重载;

    封装

    将描述一个事物的属性和方法集中定义在一个对象中。
    原因:
    1.单独的属性和方法是没有意义的,只有放在对象上才有意义;
    2.便于反复调用——代码重用!便于维护!参考下面的例子Car();

    继承

    inherit父对象中的属性和方法,子对象可直接使用!
    原因:代码重用;便于维护;节约内存空间。
    Tips:js中的继承都是用 __proto__

    那如何修改继承呢?参考资料,总结四种修改继承的方法:

    1. 仅修改一个对象的父对象:
    子对象.__proto__ = 父对象;
    Object.setPrototypeOf(子对象,父对象);
    
    1. 替换构造函数的原型对象(prototype)为新父对象
      结果:将来再创建的子对象,所有新创建的子对象都继承新父对象
      时机:在刚刚定义完构造函数后,立刻修改!在修改原prototype对象和创建新子对象之前
      步骤:
      (a)构造函数.prototype = 新父对象
      (b)构造函数.prototype.constructor = 构造函数对象

    2. 用一个已有的父对象作为参照,创建一个新子对象,同时,扩展子对象自有属性。
      在创建一个子对象时,希望随意扩展子对象的自有属性时,使用该继承方法。

    var son = Object.create(父对象);
    

    两件事:
    a. 创建空对象son
    b. 设置son的__proto__指向父对象

      var son = Object.create(父对象, {
            扩展属性名1: {
                writable: true,
                value: 属性值,
                configurable: true
            },
            扩展属性名2: {
                ...
           }
        });
    

    (上面的1,2,3方式的实例可以参见例2)

    1. 推荐的继承方式:既继承结构,又继承原型
      何时使用:两种类型间的继承
      使用:
      a. 子类型构造函数开始位置,借用父类型构造函数:
    父类型构造函数.call(this,参数列表)
    父类型构造函数.apply(this,[参数列表])
    

    Tips:仅完成第一步,只是借用构造函数中的语句而已,没有实现任何对象间的继承
    b. 定义构造函数后,设置子类型构造函数的prototype继承父类型的prototype:

    Object.setPrototypeOf(子类型.prototype,父类型.prototype)
    

    (4方式的实例可以参见例3)


    (3)实践

    例1:

    <script type="text/javascript">
        init();
        function init() {
            var obj = {name: 'panhf', age: 28};
            // hash数组,传入的key必须是字符串
            console.log(obj["name"]);
            console.log(obj["age"]);
    
            // in
            for (var key in obj) {
                console.log(key + ":" + obj[key]);
            }
    
    
            var obj1 = new Object();
            obj1.name = "zjl";
            obj1["age"] = 4;
            // 将对象转换成字符串
            console.log(JSON.stringify(obj1));
    
            var car = new Car("white", "buick");
            var car2 = new Car("black", "benz");
    
            console.log(JSON.stringify(car));
            car.launch();
            car.stop();
            // 原型的使用
            Car.prototype.info = function () {
                console.log(JSON.stringify(this));
            };
    
            console.log("=====");
            car.info();
            car2.info();
    
            console.log("=====");
            /**
             *
             * 使用jquery加载json文件
             */
            var dataroot = "../json/test.json";
            var carArr = new Array();
            /**
             * 异步执行
             * http://www.cnblogs.com/chenxizhang/archive/2009/07/02/1515151.html
             *
             */
            $.getJSON(dataroot, {}, function (data) {
                //console.log(data);
                for (var i = 0; i < data.length; i++) {
                    var car = new Car(data[i].color, data[i]["brand"]);
                    carArr.push(car);
                }
    
                //console.log(JSON.stringify(carArr));
            });
    
            console.log("=====");
            console.log(new Person("phf"));
            console.log(new Person("phf", 28));
    
        }
    
        function Person() {
            /**
             * 参数列表封装在arguments内置对象数组中
             */
            console.log(JSON.stringify(arguments));
        }
    
        function Car(color, brand) {
    
            this.color = color;
            this.brand = brand;
    
            this.launch = function () {
                console.log("car is launch");
            };
    
            this.stop = function () {
                console.log("car is stop");
            }
        }
    
        function Car(color, brand, createDate) {
            this.color = color;
            this.brand = brand;
            this.createDate = createDate;
    
            this.launch = function () {
                console.log("car is launch");
            };
    
            this.stop = function () {
                console.log("car is stop");
            }
        }
    </script>
    

    例2:

    <script type="text/javascript">
        /**
         * 修改继承的方法
         * (1)仅修改一个对象的父对象
         * (2)替换构造函数的原型对象(prototype),为新父对象
         * (3)用一个已有的父对象作为参照,创建一个新子对象,同时,扩展子对象自有属性
         */
        var father = {balance: 100, car: "=B="};
        var son = Object.create(father, {//修改继承方法三,用一个已有的父对象作为参照,创建一个新子对象,同时,扩展子对象自有属性
            favorite: {value: "坑爹"/*,writable:true*/}
        });
        console.log(son.balance);//100
        console.log(son.favorite);//坑爹
        console.log(son.hasOwnProperty("favorite"));//true//自由属性
        son.favorite = "飙车";
        console.log(son.favorite);//坑爹
    
        function Student(sname, sage) {//this-->刚创建的空对象
            this.sname = sname;
            this.sage = sage;
        }//prototype-->Student.prototype
        Student.prototype = father;             //(1)修改继承方法二
        Student.prototype.constructor = Student;//(2)修改继承方法二
        //prototype-->father
        //凡是子对象共有的属性值和方法,都要放在构造函数的原型中
        Student.prototype.intrSelf = function () {
            console.log("I'm " + this.sname + ",I'm " + this.sage);
        }//prototype.intrSelf
         //father.intrSelf
    
        var lilei = new Student("Li Lei", 18);
        var hmm = new Student("Han Meimei", 19);
    
    
        /*仅修改一个子对象的父对象*/
        //hmm.__proto__=father;             //(1)修改继承方法一
        //Object.setPrototypeOf(hmm,father);//(2)修改继承方法一
        console.log(hmm.balance); //100
        console.log(lilei.balance);//100
        lilei.intrSelf();//I'm Li Lei,I'm 18
        hmm.intrSelf();//I'm Han Meimei,I'm 19
    </script>
    

    例3:

    <script type="text/javascript">
        /**
         * 修改继承的方法
         * 用于两种类型间的继承
         */
        //定义所有飞行物类型的构造函数
        function Flyer(fname, speed) {
            this.fname = fname;
            this.speed = speed;
        }
    
        Flyer.prototype.fly = function () {//所有飞行物都能飞行
            console.log(this.fname + " 以 " + this.speed + " 时速飞行");
        };
    
        var bird = new Flyer("小麻雀", 60);
        bird.fly();//小麻雀 以 60 时速飞行
    
        /*定义飞机类型的构造函数:名称,速度,载客数*/
        function Plane(fname, speed, capacity) {
            Flyer.call(this, fname, speed);//——借用构造函数
    //        this.fname = fname;
    //        this.speed = speed;
            this.capacity = capacity;
        }
    
        //Plane.prototype 继承 Flyer.prototype
        Object.setPrototypeOf(Plane.prototype, Flyer.prototype);
    
        var A380 = new Plane("A380", 1000, 555);
        A380.fly();
    
        Plane.prototype.fly = function () {
            console.log(this.fname + " 搭载 " +
                this.capacity + " 名乘客以 " +
                this.speed + " 时速飞行");
        }
    
        A380.fly();//A380 搭载 555 名乘客以 1000 时速飞行
    </script>
    

    相关文章

      网友评论

        本文标题:review javascript 24:面向对象

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