美文网首页
27-第二十七章 面向对象oop 构造函数(一)

27-第二十七章 面向对象oop 构造函数(一)

作者: 晚溪呀 | 来源:发表于2019-02-22 01:18 被阅读0次

Javascript是一种基于对象(object-based)的语言。但是,它又不是一种真正的面向对象编程(OOP)语言,因为它的语法中没有 class(类)—– es6以前是这样的
面向对象程序设计具有许多优点:
1、开发时间短,效率高,可靠性高,所开发的程序更强壮。由于面向对象编程的可重用性,可以在应用程序中大量采用成熟的类库,从而缩短了开发时间。
2、应用程序更易于维护、更新和升级。继承和封装使得应用程序的修改带来的影响更加局部化。

new 执行的函数,函数内部默认生成了一个对象
函数内部的this默认指向了这个new生成的对象
new执行函数生成的这个对象,是函数的默认返回值

一、 面向对象四个基本特征

对象:对象这个词,本身就是抽象的,也就是把客观事物抽象的成类
封装:封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。
继承:通过继承创建的新类称为“子类”或“派生类”。继承的过程,就是从一般到特殊的过程。
多态:对象的多功能,多方法,及方法

二、对象是什么?

对象有”属性“(property)和”方法“(method)

三 对象实例化方式

原始模式
       var Car = {
            color: 'red', // 车的颜色
            wheel: 4, // 车轮数量
        }
        alert(Car.color); // red

生成两个实例对象

        var Car = {
            color: 'red',
            wheel: 4,
        }
        var Car2 = {
            color: 'blue',
            wheel: 4,
        }    

这样的写法有两个缺点,一是如果多生成几个(100个!)实例,写起来就非常麻烦;二是实例与原型之间,没有任何办法,可以看出有什么联系。

二、 原始模式的改进

我们可以写一个函数,解决代码重复的问题。

        function createCar(color,wheel) {
        return {
          color: color,
          wheel: wheel
        }
      }
    
        // 然后生成实例对象,就等于是在调用函数:
        var cat1 = createCar("红色","4");
        var cat2 = createCar("蓝色","4");
        
        alert(cat1.color) // 红色    

三、 工厂模式

        function createCar(color,wheel){ // createCar工厂
            var obj = new Object; // 或obj = {} 原材料阶段
            obj.color = color; // 加工
            obj.wheel = wheel; // 加工
            return obj; // 输出产品
        }
        // 实例化
        var cat1 = createCar("红色","4");
        var cat2 = createCar("蓝色","4");
        alert(cat1.color); //红色    

四、 构造函数模式

为了解决从原型对象生成实例的问题,Javascript提供了一个构造函数(Constructor)模式。
所谓”构造函数”,其实就是一个普通函数,但是内部使用了 this变量。对构造函数使用new运算符,就能生成实例,并且this变量会绑定在实例对象上。

        function CreateCar(color,wheel){ // 构造函数首字母大写
            // 不需要自己创建对象了
            this.color = color; // 添加属性,this指向构造函数的实例对象
            this.wheel = wheel; // 添加属性
        
            // 不需要自己return了
        }
        
        // 实例化
        var cat1 = new CreateCar("红色","4");
        var cat2 = new CreateCar("蓝色","4");
        alert(cat1.color); // 红色    

new 函数构造内部变化:

自动生成一个对象
this指向这个对象
函数自动返回这个对象

五、 构造函数注意事项

1、此时 CreateCar 称之为构造函数,也可以称之类,构造函数就是类
2 、cat1,cat2均为CreateCar的实例对象
3、 CreateCar 构造函数中 this 指向CreateCar实例对象即 new CreateCar( )出来的对象
4、 必须带 new
5、 构造函数首字母大写,这是规范,官方都遵循这一个规范,如 Number() Array()
6、 constructor
这时 cat1cat2 会自动含有一个constructor 属性,指向它们的构造函数,即CreateCar。 /kənˈstrʌktə(r)/构造函数

要看一个实例的原型是哪一个构造函数的,只需要看 constructor 即可

      alert(cat1.constructor === CreateCar); // true
      alert(cat2.constructor === CreateCar); // true

7、object instanceof constructor 运算符,验证构造函数与实例对象之间的关系。
instanceof 运算符用于测试构造函数的 prototype 属性是否出现在对象的原型链中的任何位置
instanceof 运算符 /'ɪnst(ə)ns/ 实例,例子

        alert(cat1 instanceof CreateCar );  // true
        alert(cat2 instanceof CreateCar );  // true

obj1 instanceof obj2
用于确定 obj2 对象是否在 obj1 对象的原型上

8、实例的 __proto__ 等于 实例对象对应的类的 prototype

9、要扩展多个方法采用重新赋值,重新赋值 要修改constructor的指向
单个方法直接 . 扩展就行了

10、for in 不仅会遍历对象,还会遍历原型

        function CreateFun(name, len) {
            this.name = name,
            this.len = len
            // 实例的 `__proto__` 等于 实例对象对应的类的 `prototype`
            // p1.__proto__ = CreateFun.prototype
        }

        CreateFun.prototype = {
            constructor: CreateFun, // 对应的类(构造函数),
            add(){}
        }

11、原型可以改变
CreateFun.prototype = Array.prototype;
这个实例的原型拥有数组所有的方法
这个实例对象被 CreateFun 实例出来的,也被 Array 实例出来的

六、 JavaScript值类型(基本类型)和引用类型:

(1)值类型:数字、字符串、布尔值、null、undefined。
值类型理解:对变量赋值 会开辟新的内存地址
变量的交换等于在一个新的地方按照连锁店的规范标准(统一店面理解为相同的变量内容)新开一个分店,这样新开的店与其它旧店互不相关、各自运营。
(2)引用类型:对象、数组、函数。
引用类型理解:对变量赋值 指向相同的内存地址
变量的交换等于把现有一间店的钥匙(变量引用地址)复制一把给了另外一个老板,此时两个老板同时管理一间店,两个老板的行为都有可能对一间店的运营造成影响。
但是函数不会造成影响,因为函数内部的逻辑是不会被改变的

七、 构造函数的问题:

构造函数方法很好用,但是存在一个浪费内存的问题。
请看,我们现在为再添加一个方法 ·showWheel·。那么,·CreateCar·就变成了下面这样:

        function CreateCar(color, wheel) {
            this.color = color;
            this.wheel = wheel;
            this.showWheel = function () { // 添加一个新方法
                alert(this.wheel);
            }
        }

        //还是采用同样的方法,生成实例:
        var cat1 = new CreateCar("红色", "4");
        var cat2 = new CreateCar("蓝色", "4");    

表面上好像没什么问题,但是实际上这样做,有一个很大的弊端。那就是对于每一个实例对象, type 属性和 eat() 方法都是一模一样的内容,每一次生成一个实例,都必须为重复的内容,多占用一些内存。这样既不环保,也缺乏效率。

        alert(cat1.showWheel == cat2.showWheel);  // false

八、 Prototype 原型

Javascript 规定,每一个构造函数都有一个 prototype 属性,指向另一个对象。这个对象的所有属性和方法,都会被构造函数的实例继承。
这意味着,我们可以把那些不变的属性和方法,直接定义在 prototype 对象上。

        function CreateCar(color, wheel) {
            // 属性写构造函数里面
            this.color = color;
            this.wheel = wheel;
        }

        // 方法写原型里面
        CreateCar.prototype.showWheel = function () {
            alert(this.wheel);
        }
        CreateCar.prototype.showName = function () {
            alert('车');
        }

        //然后,生成实例。
        var cat1 = new CreateCar("红色", "4");
        var cat2 = new CreateCar("蓝色", "4");
        alert(cat1.showName); // '车'
        alert(cat1.showWheel == cat2.showWheel); // true
        alert(cat1.showName == cat2.showName); // true
        // 这时所有实例的showWheel属性和showName方法,
        // 实都是同一个内存地址,指向prototype对象,因此就提高了运行效率。
       
        alert(cat1.showWheel == cat2.showWheel); // true

九、面向对象 ES6 写法

class( ES5 保留字, ES6 就是关键字) ES6 定义一个类
ES6 实例的时候还是 new
ES5 原型上可以定义普通属性,但是不推荐
ES6 是不可以的,constructor 以外的只能是函数
私有属性后面不要加任何符号
公有属性后面也不要加任何符号

        class CreateFun{
            constructor(name, age) { // 私有属性
                this.name = name,
                this.age = age
            } // 不能加符号
            // 下面是公有属性
            add(value) {
                console.log(value);
            } // 不能加符号
            sub(value) {
                console.log(value);
            }
        }

        // 实例对象是被对应的类实例出来的
        const obj = new CreateFun('大帅逼', '18'); 

十、面向过程 改写面向对象:

要求:不要出现函数嵌套
变量-> 属性
函数->方法
难点:this指向

案例:用面向对象改写 拖拽
案例:用面向对象改写 轮播

相关文章

  • 27-第二十七章 面向对象oop 构造函数(一)

    Javascript是一种基于对象(object-based)的语言。但是,它又不是一种真正的面向对象编程(OOP...

  • js原型链和继承的理解

    Object() Function() Array() 等等都为构造函数。Js 面向对象与传统oop 有些不同,语...

  • Day06 JavaScript面向对象

    面向对象OOP JavaScript中的object类1、直接使用变量定义object对象 2、使用构造函数来创建...

  • 01 面向对象

    -------------------【面向对象】------- ----《构造函数》--- 简介:所有的构造函数...

  • 02-对象与类

    1.面向对象的程序设计:oop 1.1 面向对象关注的是数据本身 类:构造对象的蓝图或模板,类构造 ( const...

  • 030_wz_hm_面向对象(OOP)基本概念

    面向对象基本概念 面向对象编程——Object Oriented Programming简写OOP 过程与函数 我...

  • Python OOP-1

    0. OOP-Python面向对象 Python面向对象 面向对象编程基础公有私有继承组合,Mixin 魔法函数魔...

  • jQuery源码解读-核心机制(1)

    核心机制——对象的构建 1、构造函数 面向对象(OOP)的语言都有一个特点,它们都会有类的这一概念,通过类可以抽象...

  • RYF javascript笔记3

    4. 面向对象编程 4.1面向对象编程概述 4.1.1简介 4.1.1.1构造函数 js没有“类”,而改用构造函数...

  • 构造函数和原型对象

    javascript使用构造函数和原型对象来进行面向对象编程 构造函数 在 JavaScript 中,构造器其实就...

网友评论

      本文标题:27-第二十七章 面向对象oop 构造函数(一)

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