(17.05.31)(48)面向对象、类和实例、面向对象的特征、工厂模式、继承、类型的检测

面向对象:
    思想。
    什么是对象:男朋友,女朋友,狗,猫,电视,冰箱 ......
        什么都是对象 —— 万物皆对象 (everything is object)。
    什么是面向对象: 看着你的对象。和对象打交道。
        —— 使用对象,创建对象

使用 —— 方便,好用 —— 以前
写对象 —— $$$ ——现在


对象组成:
    属性:某个物体(对象)具有的特性(人的身高,体重...)。
        变量——有归属的变量。
    方法:某个对象会做什么事情(人会吃饭、睡觉...)。
        函数 —— 有归属的函数。
    事件:触发这个对象的一些行为,这个对象给出的反应。
        在JS的面向对象里,方法和事件不做严格区分(统一叫方法)

类和实例:
    类: 模板。 没有什么具体的功能。
        Date —— 类(本身也有一些功能)
        var oDate = new Date(); // Date -> 类
    实例:根据模板造出来的具体的东西。
        var oDate = new Date(); // oDate -> 实例

面向对象的特征:
    封装:把细节包起来,用户只管使用,不用关心是怎么实现的。
    继承:子类可以直接使用父类的功能(东西)
    多态:在JS中没有。


一、写一个对象
    组成:属性、方法

    一)属性
        弄一个对象,通过函数:

           function Person(){
               1、弄一个空对象
                   let obj = new Object();
               2、把属性放到对象身上
                   obj.name = name;
                   obj.age = age;
               3、返回对象
                   return obj;
           }

        使用:

            //根据Person类实例化一个对象
            var p1 = Person('zhangsan',20);
            //访问属性
            p1.name
            pa.age

工厂模式:
    现实:
        原料准备 ———> 加工 ———> 出厂
    JS:
        obj ———> obj.xxx = x ——> return obj;

系统中的类、对象: new
    var oDate = new Date();
    var reg = new RegExp();

咱们现在:函数调用
    var p1 = Person();

想通过 new 来得到一个对象:
    目标:var p1 = new Person();

  • 如果使用new,得到对象,new 做了一些事情,对Person的影响:
    1. 自动创建一个新的空白对象
    2. 把这个对象赋值给 this
    3. 自动返回 this

  • Person 实质上就是一个函数 —— 构造函数 (约定:首字母大写)

  • 能 new 出来的东西,都是函数 (Date, RegExp... Array,new Map()...)

  • new 一个类的实例时,构造函数自动执行。

函数:
    new Function()

    以前:
        function show(){}
    本质:
        var show = new Function('');

Array:
    1、 var arr = [1,2,3];
    2、 var arr = new Array(1,2,3);

    如果只有一个参数(值):
        arr=[3]; // 表示 一个元素,值是3
        arr=new Array(3); //表示 三个元素,值是空 —— 长度


二)方法:
    每个一函数身上(每个类身上),有一个东西叫 原型, prototype, 类的方法就是放在原型身上。

    function Person(name,age){
        this.name = name;
        this.age = age;
    }
    //给Person类加一个显示自己名字的方法
    Person.prototype.showName = function(){
        alert(this.name);
    };
  • 原型上的方法,属于类,而不属于实例。

  • 原型prototype 可以用于扩展系统方法
        数组:
            arr.indexOf(); //用法、作用 和 str.indexOf 一样
                —— 只支持高级浏览器(ie7,8.. 不支持)

  • 扩展系统方法时,原则: 能用系统的尽量用系统的

  • 关于浏览器判断 —— 尽量少用 navigator.userAgent
            (msie firefox chrome...)
                —— 建议使用支持的特性进行判断

上午回顾:

一、概念
    对象: 任何东西都是对象
    面向对象: 和对象打交道
1、对象的组成:
    属性:有归属的变量
    方法:有归属的函数
    事件:在JS的面向对象里,视同为方法
2、类、实例
    类:  模板,没有实际的功能
    实例:根据模板(类)造出来的一个具体的东西

    function Person(){} —— Person 类
    let p1 = new Person(); —— p1 实例

    类 —— 实例化 ——实例
3、面向对象的三个特性:
    封装:包起来。用户只管用,不关心内部的具体实现。
    继承:子类可以使用父类的东西
    多态:JS中没有

* 能new出来的,肯定是函数
* 任何东西都是对象
* new 一个类的实例时,这个类的构造函数自动执行
* 函数的本质:  new Function();
* Array 
    arr = [3]; //3 表示的 数组中有一个3
    arr = new Array(3);  //3 表示的是数组的长度

二、写一个对象

    1、写法
    //Person —— 构造函数(约定:首字母大写)
    //属性 : 放到构造函数里
    function Person(name,age){
        //给属性赋值
        this.name = name;
        this.age = age;
    }
    //方法:放到原型身上
    Person.prototype.showName=function(){
        //return this.name;
        return '张先生';
    };
    Person.prototype.showAge = function(){};

    2、实例化
    
    let p1 = new Person('zhangsan',20);
        //p1.name = 'zhangsan'
        p1.showName() ——> 'zhangsan'
    let p2 = new Person('lisi',18);
        
* prototype: 原型
    可以扩展系统方法:
        1、arr.indexOf
        //arr.indexOf = 
        Array.prototype.indexOf=
        2、str.trim —— 去除首尾空格
            String.prototype.trim = String.prototype.trim || function(){}

三、继承
    子类可以使用父类的东西,父类有什么子类就有什么。

现在有一个类: Person —— 人
想有一个新类: Worker —— 工人

1、直接写       ×
    function Worker(name,age,job){}...  
2、把Person改成 Worker , 不行, 原来对  Person 的调用都会报错  ×
3、把Person复制一份,改个名  ×
4、继承    √

父类到底有什么,或说 ,子类需要继承什么:
    1. 属性
    2. 方法

一) 属性的继承
    在子类的构造函数里,调用了父级的构造函数:

        function Worker(name,age,job){
            Person(name,age);
            this.job = job;
        }
    以上写法,Person中this 出问题了 ——>  指向了  Window

this的问题:
    有问题的地方:
        1. 定时器
        2. 箭头函数里this 指向 父级作用域。
    解决:
        1. 在this正确的地方,存一下, var _this = this;
        2. call
            函数名.call(this的指向,参数1,参数2...);
        3. apply
            函数名.apply(this的指向,[参数1,参数2...]);
        4. bind:本身并不执行函数,只是完成this的绑定

            1)  let a = fn.bind(this的指向,参数1,参数2);
                a();
            2)  let a = fn.bind(this的指向,参数1);
                a(参数2);

属性继承:
    子类的构造函数里,调用父类的构造函数, 注意this, call/apply

    function Person(){}
    function Worder(){
        Person.call(this,name.....);
        Person.apply(this,arguments);
    }

继承:
1、父类所具有的东西,子类天然具有
2、子类修改了,不能影响父类
3、父类修改了,子类自动修改

二) 方法的继承

    1、子类的原型 = 父类的原型    ×
        Worker.prototype = Person.prototype
    2、子类的原型 = new Person();     //父类的实例 √


类型的检测:

JS ,是一种弱类型的语言。

1、typeof
    基本类型    √
    对象类型 ——  object
2、instanceof
    检测 某个对象是不是某个类的实例,一直向上检查
    oDate instanceof Date   //true
3、constructor
    obj.constructor == Date
    某个对象的亲爹是谁,到底是由谁构造出来的。

=============2017年5月31日 星期三 16:43:30 =============
总结: 写一个类,带继承

    1、写父类
        属性:构造函数里
        方法:原型上
    2、继承
        属性:
            在子类的构造函数里,调用父类的构造函数(注意this)
                function Worker(){
                    Person.apply(this,arguments);
                }
        方法:
            1.子类的原型 = 父级的一个实例
                Worker.prototype = new Person();
            2.纠正构造函数
                Worker.prototype.constructor = Worker;

你可能感兴趣的:((17.05.31)(48)面向对象、类和实例、面向对象的特征、工厂模式、继承、类型的检测)