js之类 面向对象的书写方式(详细篇)

下半年就要实习了,时不我待,开始为面试做准备,收罗一些需要掌握的知识,现在都忘的差不多了

类和对象(class)是两种以计算机为载体的计算机语言的合称。对象是对客观事物的抽象,类是对对象的抽象。类是一种抽象的数据类型。

它们的关系是,对象是类的实例,类是对象的模板。对象是通过new className产生的,用来调用类的方法;类的构造方法

面向对象是一种方法,用来封装功能,方便日后使用,避免大量的重复工作
大致有四种基本方式:工厂模式,构造函数方式,原型方式,混合方式

  javascript中类的概念
  工厂模式
  构造函数方式
  原型方式
  动态原型方式
  混合模式(原型模式 + 构造函数模式)

1,javascript中类的概念:

把具有共同性质的事物归结为一类,得出一个抽象的概念——类。 在面向对象的编程语言中,类是一个独立的程序单位,是具有相同属性和方法的一组对象的集合。类的概念使我们能对属于该类的全部对象进行统一的描述。

js 中的类:

js是一种弱类型语言,js本身是不支持”类”的,但可以模拟出”类”;

类的书写方式

工厂模式

概述:这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。=》需要生成的对象叫做产品 ,生成对象的地方叫做工厂 。
   在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。

意图:定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。

主要解决:主要解决接口选择的问题。

应用实例: 1、您需要一辆汽车,可以直接从工厂里面提货,而不用去管这辆汽车是怎么做出来的,以及这个汽车里面的具体实现。
      2、Hibernate 换数据库只需换方言和驱动就可以。

优点: 1、一个调用者想创建一个对象,只要知道其名称就可以了。
   2、扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。
   3、屏蔽产品的具体实现,调用者只关心产品的接口。

缺点:每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。这并不是什么好事。

书写方式:

    <script type="text/javascript">
        //总体的类型   工厂模式把所有的属性和方法写在一块
        function createObject(name,age){
            var obj = new Object();
            obj.name = name;
            obj.age = age;
            obj.sayHello = function(){
                console.log(this.name);
            }
            // 一般就返回对象,不怎么常用,至少我是这样
            return obj;
        }

        var obj1 = createObject("john1",20);
        var obj2 = createObject("john2",10);
        console.log(obj1);  //{name: "john1", age: 20, sayHello: ƒ}
        console.log(obj2);  //{name: "john2", age: 10, sayHello: ƒ}

        var obj3 = createObject("john3",30);
        obj3.sayHello();//john3

        console.log(obj3 instanceof Object);//true
    </script>

构造函数方式

构造函数的定义方法其实和普通的自定义函数相同。
  
构造函数的问题:

1.使用构造函数的最大的问题在于每次创建实例的时候都要重新创建一次方法(理论上每次创建对象的时候对象的属性均不同,而对象的方法是相同的),然而创建两次完全相同的方法是没有必要的,因此,我们可以将函数移到对象外面;

2.在全局作用域中定义了许多仅供特定对象使用的方法,浪费空间,显然失去了面向对象封装性了,因此可以通过原型来解决此问题。

        function Car(color, door) {
            this.color = color;
            this.doors = door;
            this.showColor = function () {
                console.log(this.color)
            };
        }

        var obj1 = new Car('red',1);
        var obj2 = new Car('blue',2);
        console.log(obj1);  //Car  都返回关于car的对象
        console.log(obj2);

        var obj3 = new Car('black',3);
        obj3.showColor();       //black
        
        console.log(obj3 instanceof Object);//true

原型(“prototype”)方式

创建的每个函数都有prototype(原型)属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法。使用原型对象的好处就是可以让所有对象实例共享它所包含的属性及方法

原型方式一般不会单独使用,一般结合构造函数方式使用,prototype填充类中未定义的属性和方法

        function Car() {  }
        Car.prototype.color='red';
        Car.prototype.door=1;
        Car.prototype.add=function(){
            console.log('demo')
        }
        Car.prototype.showColor=function(a){
            console.log(this.color)
            console.log(a)
        }
        var obj1 =new Car();        
        console.log(obj1);                   //包括car对象,car对象内包括一个原型__proto__: Object=》各种添加的在此显示
        console.log(obj1.add());            //demo
        console.log(obj1.showColor('123')); //red 123

动态原型方式

动态原型的方式同混合的构造函数/原型方式原理相似。唯一的区别就是赋予对象方法的位置。

动态原型方式是使用一个标志来判断是否已经给原型赋予了方法。这样可以保证该方法只创建一次


        function Car(color, door) {
            this.color = color;
            this.doors = door;
            this.arr = new Array('aa', 'bb');
            if (typeof Car.add == 'undefined') {
                Car.prototype.showColor = function () {
                    console.log(this.color);
                };
                Car.add = true;
            }
        }
        var obj1 = new Car();
        var obj2 = new Car('red');
        console.log(obj1);             // {color: undefined, doors: undefined, arr: Array(2)}都含有原型
        console.log(obj2);              // {color: red, doors: undefined, arr: Array(2)}
        console.log(obj2.showColor());  //red

        Car.prototype.showColor=1;
        var obj3 = new Car('red',1);
        console.log(obj3.showColor);  //1

混合模式(原型模式 + 构造函数模式)

function Blog(name, url, friend) {
  this.name = name;
  this.url = url;
  this.friend = friend;
}
 
Blog.prototype.alertInfo = function() {
  alert(this.name + this.url + this.friend);
}
 
var blog = new Blog('wuyuchang', 'http://tools.jb51.net/', ['fr1', 'fr2', 'fr3']),
  blog2 = new Blog('wyc', 'http://**.com', ['a', 'b']);
 
blog.friend.pop();
blog.alertInfo();  // wuyuchanghttp://tools.jb51.net/fr1,fr2
blog2.alertInfo();  // wychttp://**.coma,b
posted @ 2022-04-02 09:47  coderwcb  阅读(183)  评论(0编辑  收藏  举报