面向对象和面向过程

面向对象编程和面向过程编程

共同点:都是解决问题的一种思路;
区别:面向过程关注的是解决问题需要的一个个的步骤(细节).
面向对象关注是解决问题所需要的对象

什么是对象?

万物皆对象,一般对象是指具体的事物。面向对象和面向过程一样,都是解决问题的思路,无优劣之分,但是面向对象更加方便,代码的结构性更好,更方便维护,代码的复用性更好。

  • 现实中的对象:
    1.对象的静态的描述信息:

张三(姓名,性别,身高,体重,头发的颜色..)
张三家的狗(姓名,性别,品种...)

  1. 对象的动态的行为:

张三(吃饭,睡觉,打游戏,谈恋爱,打呼噜..)
张三家的狗(吃饭,睡,咬人,流口水...)

  • 现实中的对象和JS中的对象的关系

对象的静态的描述信息--->对象的属性(定义在对象中的变量)
对象的动态的行为------->对象的方法(定义在对象中的函数)

面向对象的三大特性
  • 封装:JS中使用对象封装一些变量和函数;
    优点:信息隐蔽,代码复用性好,更方便维护。
var name = '战狼2';
var actors = ['吴京',‘张翰’,‘达康书记’,‘弗兰克’]
var  type = '动作片'
var showTime = '2017-7-28'
var  play = function (){
console.log('play');
}
var film = {
   name : '战狼2',
   actors :['吴京',‘张翰’,‘达康书记’,‘弗兰克’],
   type :'动作片',
   showTime : '2017-7-28',
   play = function (){
   console.log('play');
     }
}
  • 继承:
    生活中的继承:一个人获取另一个人的财富或者资源的一种方法。
    程序中的继承:一个类获取另一个类属性或者方法的一种方式。
    面向对象的特点:有没有类(Java c++ oc)
    Js 没有类,支持面向对象的语言,基于对象的语言。
  • 多态:polymorphism = poly(复数) + morph(形态) + ism
    多用于强类型语言中,JavaScript具备与生俱来的多态特性。
    表现:1. 对同一个操作,不同对象有不同的反应;
    2. 隐蔽不同

对象的创建:

  1. 字面量的方式创建对象(key-value):
    场合:只需要创建少量的对象。
    问题:1. 创建的对象无法复用;
    2. 有大量的重复代码(代码的冗余度太高)。
 var stu1 = {
        name : '张三',
        num : 1001,
        className : '如何成为科学家',
        study : function () {
            console.log('我的名字是' + this.name);
        }
    };

    var stu2 = {
        name : '宝宝',
        num : 1190,
        className : '葵花宝典班',
        study : function () {
            console.log('我的名字是' + this.name);
        }
    };

    var stu3 = {
       name : '瓜皮',
       num : '2345',
       className : '三分钟精通JS',
        study : function () {
            console.log('我的名字是' + this.name);
        }
    };
  1. 通过内置的构造函数:
    问题:内置的构造函数和字面量的方式存在一样的问题
    1.创建的对象无法复用
    2.创建多个同类型的对象时,有大量重复的代码,代码的冗余度太高

Object | Array | Function | Date
String | Number | Boolean

//1.创建对象
var obj = new Object();// var obj = {};
//2. 利用对象的动态特性设置属性和方法
  obj.name = 'zs';
   obj.num = 1001;
   obj.className = '暴雨梨花针班';
   obj.study = function () {
       console.log(this.name + this.className);
   }

   var obj1 = new Object();
   obj.name = 'ls';
   obj.num = 2001;
   obj.className = '葵花宝典班';
   obj.study = function () {
       console.log(this.name + this.className);
   }

   var obj2 = new Object();
   obj.name = '老王';
   obj.num = 3001;
   obj.className = '三分钟精通C++';
   obj.study = function () {
       console.log(this.name + this.className);
   }
  1. 简单的工厂函数:
// 1.提供一个函数(工厂函数)封装对象的创建过程
 function createStudent(name,age) {
// 2.原料:创建对象
     var stu = new Object();
// 3.加工:设置属性和方法
     stu.name = name;
     stu.age = age;
     stu.logDes = function () {
         console.log(this.name);
     };
//4. 出厂:返回这个对象
     return stu;
 }

 var stu1 = creatStudent('zs',20);
 var stu2 = creatStudent('ls',18);
 console.log(stu1, stu2);
  1. 自定义构造函数:
    自定义构造函数的返回值:
    1.如果构造函数内部没有return,返回构造函数内部新创建的对象;

    1. 如果是构造函数内部有return,要看具体情况:
    • 如果返回的是值类型的数据,直接忽略,返回构造函数内部新建的对象;
    • 如果返回是引用类型的数据,返回该引用类型的数据。
    1. 提供一个构造函数;

    1.做一些初始化的设置;
    2. 首字母大写 ;使用new 关键字调用构造函数

    1. 通过this设置属性和方法;
    2. 使用new 创建对象。
// 1.提供一个构造函数
    function Person(name,age) {
         // 默认会创建一个新的对象
        // var obj = new Object();
        // 默认会把这个新的对象赋值给this
       // this = obj;
// 2.通过this设置属性和方法
        this.name = name; // this->构造函数内部新创建的对象;
        this.age = age;
        // 默认会返回新创建的对象
       // return obj;
    }
// 3.使用new 创建对象
    var p1 = new Person('zs',20);
    var p2 = new Person('ls',18);
    console.log(p1, p2);

自定义构造函数和工厂函数的区别
  1. 构造函数首字母大写;
  2. 使用new 调用构造函数;
  3. 构造函数默认会返回新创建的对象,工厂函数需要手动返回.

instanceof:判断对象是否是由制定的构造函数创建的。

 function Person() {
    }

    function Dog() {
    }
    var p = new Person();
    var d = new Dog();
 console.log(p instanceof Person); // true
 console.log(d instanceof Dog); // true
 console.log(p instanceof Dog); // false

获取对象的类型(获取对象是由哪一个构造函数创建出来的)-->构造器属性(constructor)

 function Person() {
    }
    var p = new Person();
    // 每一个对象都有构造器属性
    console.log(p.constructor);//function Person() {}

原型对象:在构造函数创建出来的时候,系统会默认创建一个对象与这个构造函数相关联,这个对象就叫该构造函数的原型对象。

  • 作用:通过构造函数创建出来的对象,默认就可以使用该构造函数原型对象的属性和方法。
  • 如何访问:构造函数.prototype
  • 如何设置:1. 原型对象本质是一个对象,利用对象的动态特性设置原型对象的属性和方法;2. 使用字面量的方式(替换原型);
实例和实例化:
  • 实例化:通过构造函数创建对象的过程称为实例化;
  • 实例:通过构造函数创建出来的对象就是一个实例.一般情况我们在说实例需要说明是哪一个构造函数的实例. 某个对象是XXX构造函数的实例。
原型的使用方法:

利用对象的动态特性设置原型对象。

  • 实例成员:实例属性和实例方法。
  • 原型成员:原型的属性和方法。
 function Person(name) {
        this.name =name
    }
    //增加成员
    Person.prototype.des ='des';
    Person.prototype.showName =function () {
        console.log(this.name);
    }
    //修改成员
    Person.prototype.des = 'log';
    Person.prototype.log = 'des';
    var p1 =new Person('zs');
    console.log(p1.des);//log;
    p1.showName();//zs
  //删除成员
    delete  p1.des;//只能删除实例上的属性而不能删
    除原型对象的属性。
    console.log(p1.des);//log
    delete  Person.prototype.des;
    console.log(p1.des);//undefined
替换原型对象的注意点:
  1. 替换原型对象之前和替换原型对象之后创建的对象,他们的原型对象不是同一个对象;
    建议: 替换原型对象完毕后 在创建对象。
  2. 需要修正构造器属性:替换之后创建的对象的 constructor指向Object,并不是Person。
//构造函数
    function Person(name) {
        this.name = name;
    }
    var p2 = new Person('ls');
    //设置原型对象
    Person.prototype = {
     constructor :Person,//给替换的原型对象设置constructor属性
     des:'des',
     showName:function () {
          console.log(this.name);
        }
    }
   var p1 = new Person('zs');
   console.log(p1.constructor ==p2.constructor);
属性的访问原则

通过对象.属性访问属性的时候,首先会查找自己有没有这个属性,如果有就直接使用;如果没有会查找原型对象上有没有这个属性,如果有就直接使用,如果没有就返回undefined 或者报错;

设置原型属性的注意点:
1.通过对象.属性设置属性的时候,如果没有这个属性就是添加一个新的属性,如果有就是修改;但是不会修改原型对象的属性
2.怎么修改原型对象的属性
1).通过构造函数.prototype.属性修改属性或者替换原型;
2).如果有个属性是引用类型的属性,可以通过对象.属性.属性的方式修改;

 function Person(name) {
        this.name = name;
    }
    Person.prototype.des = 'des';
    Person.prototype.dog = {
        name:'huahua',
        age:3
    };
    var p1 = new Person('zs');
    p1.des = '111';
    console.log(p1.des);
    //有两个操作,先访问p1的dog属性,由于构造函数没有这个属性,所以访问其原型对象的dog属性,再操作dog.name = 'baobao',修改了原型对象的属性。
    p1.dog.name = 'baobao';
    console.log(Person.prototype.dog.name);

__ proto __属性:对象中指向对象的原型对象。
访问原型对象:
1.构造函数.prototype;
2.对象. __ proto __ 。

  1. Object.getPrototypeOf();
    注意点:
  2. __ proto __在正式开发中不要使用;
  3. __ proto __ 是非标准的,ECMA不支持.部分浏览器厂商为了方便程序员调试程序提供的。
 function Person() {
    }
    var p1 = new Person();
  console.log(Person.prototype == p1.__proto__);//true

hasOwnProperty:用于判断对象中是否存在指定的属性(实例属性);

   function  Person(name,age) {
        this.name = name;
        this.age = age;
    }
    Person.prototype.des  ='des';
    Person.prototype.age = 10;
    var  p1 = new Person('zs',20)
    console.log(p1.hasOwnProperty('des'))//false des为原型对象的属性,不属于p1自己的属性。

构造一个函数:判断属性是不是原型属性,并且只能是原型属性。

 function isPrototypeProperty(objName,obj) {
        return (objName in obj) && !obj.hasOwnProperty(objName);
    }

isPrototypeOf:判断一个对象是否是指定对象的原型对象。


    function Person() {
            }
    var obj = {};
    Person.prototype = obj;
    var p1 =new Person();
    console.log(obj.isPrototypeOf(p1));//true
    console.log(p1 instanceof Person);//true

你可能感兴趣的:(面向对象和面向过程)