zoukankan      html  css  js  c++  java
  • JavaScript课程——Day15(编程思想、对象的读写、面向对象的创建、面向对象的案例)

    1、编程思想

    • 面向过程:面向过程思想强调的是步骤,当碰见问题时,思考的是“我该怎么做”,分析出解决问题所需的步骤,一步步的去实现。
    • 面向对象:面向对象思想强调的是对象,当碰见问题时,思考的是“我该让谁来做”。这个“谁”其实就是对象。找合适的对象做合适的事情。而对象如何去做(采用什么样的步骤)我们就不关心了,最终把问题解决掉就可以了。

      相关概念:

    var 对象 = {
        key1: value1,
        key2: value2,
        ...
    }

      1.1、对象:无序的明值对

      1.2、对象组成:

      • 属性:对象的特征描述,静态,名词
      • 方法:对象的行为,动态(函数)

      1.3、对象的基本特征:封装、继承、多态(了解)

      1.4、类和示例

      • 类:类是对象的类型模板
      • 实例:实例是根据类创建的对象
      • 面向对象学习,就是学习创建类(模板),利用类生成实例(月饼)

    2、对象的读写

    var obj = {
        name: 'zs',
        age: 3,
        aa: undefined,
        job: function () {
            console.log(this);
            console.log('前端开发');
        }
    };
    
    //
    console.log(obj.name); // 点的形式
    console.log(obj['age']); // 中括号的形式
    obj.job();
    var v = obj.job;
    v();
    
    // -------------------
    //
    // 如果原来存在这个属性,则就是修改,如果不存在,则是添加
    obj.name = 'ls';
    obj.sex = '男';
    console.log(obj);
    
    // ----------------------
    // 遍历
    for (var attr in obj) {
        console.log(attr, '-----', obj[attr]);
    }
    
    // -----------------------
    // in操作符:检查对象有某个属性没,返回布尔值
    // 格式:key in 对象
    // 区分清楚属性有不有和值没有一点关系
    console.log('name' in obj); // true
    console.log('abc' in obj); // false
    console.log('aa' in obj); // true
    
    // ----------------------
    // 删除对象的某个属性
    // 格式:delete 对象.属性名;
    delete obj.aa;
    delete obj.job;
    console.log(obj);

    3、面向对象的创建

      3.1、字面量创建

    var obj = {
        name: 'zs',
        age: 3,
        showNmae: function () {
            console.log(this.name);
        }
    }
    obj.showNmae();
    
    var obj2 = {
        name: 'ls',
        age: 5,
        showNmae: function () {
            console.log(this.name);
        }
    }
    console.log(obj2.age);
    obj2.showNmae();
    
    // 不足:适用于单个对象的创建,如果要创建多个对象,会代码冗余

      3.2、实例创建

    var obj = new Object(); // 实例
    obj.name = 'zs';
    obj.age = 3;
    obj.showName = function () {
        console.log(this.name);
    }
    console.log(obj);
    
    
    
    var obj2 = new Object(); // 实例
    obj2.name = 'ls';
    obj2.age = 5;
    obj2.showName = function () {
        console.log(this.name);
    }
    console.log(obj2);
    
    // 不足:适用于单个对象的创建,如果要创建多个对象,会代码冗余

      3.3、工厂模式

    // 工厂模式:归根到底是一个封装函数
    function createPerson(name, age) {
        // 1、准备原料
        var obj = new Object();
    
        // 2、加工
        obj.name = name;
        obj.age = age;
        obj.showNmae = function () {
            console.log(this.name);
        }
    
        // 3、出厂
        return obj;
    }
    
    var o1 = createPerson('zs', 3);
    console.log(o1);
    
    var o2 = createPerson('ls', 5);
    console.log(o2);
    
    // 优点:可以大量创建
    // 不足:不能标识出它是由谁创建的

    instanceof

    // 格式:对象 instanceof 函数
    // 作用:运算符,一个对象是否为指定的构造函数的实例,返回布尔值
    
    console.log([] instanceof Array); // true
    console.log([] instanceof Object); // true  因为Object是我们js世界里的老大,一切对象都是由它创建的
    
    console.log(o1 instanceof createPerson); // false 这是工厂模式的不足,不能标识出由谁创建的
    console.log(o1 instanceof Object); // true

      3.4、构造函数模式

      构造函数的特点:

      1、构造函数名首字母大写(为了区分普通函数,不是必须,是约定)

      2、构造函数方法没有显示的创建对象(new object())

      3、直接将属性和方法赋值给this对象

      4、没有return语句,不需要返回对象

      5、通过构造函数创建对象,必须使用new运算符(直接调用跟普通函数一样)

    function CreatePerson(name, age) {
        this.name = name;
        this.age = age;
        this.showName = function () {
            console.log('小张');
        }
    }
    var p1 = new CreatePerson('zs', 3);
    console.log(p1);
    console.log(p1.showName)
    console.log(p1.name);
    p1.showName();
    
    var p2 = new CreatePerson('ls', 5);
    console.log(p2);
    console.log(p2.showName)
    
    // 问题:同样的方法,在每个实例上都要重新生成,耗内存
    console.log(p1.showName == p2.showName); // false

      以这种方式调用构造函数实际上会经历以下4个步骤

      (1)创建一个新对象;

      (2)将构造函数的作用域赋给新对象(因此this就指向了这个新对象);

      (3)执行构造函数中的代码(为这个新对象添加属性);

      (4)返回新对象(隐式返回)。(因此p1就是这个新对象,同时p1也是this)

    var o = CreatePerson('zs', 3); // 直接调用就是普通函数调用,则这些属性和方法加给了window,同时没有返回值,所以o是undefined。所以构造函数一定要能过new调用

      对象的比较

    // 基本类型,基本类型的比较,是值的比较
    console.log(5 == 5); // true
    
    // 引用类型,引用类型的比较,是地址的比较
    var a = [];
    var b = [];
    console.log(a == b); // false

      3.5、原型创建对象

      (1)原型

      js每声明一个function,都有prototype原型,prototype原型是函数的一个默认属性,在函数的创建过程中由js编译器自动添加。

      也就是说,当生产一个function对象的时候,就有一个原型prototype。原型中存储对象共享的属性和方法。

      (2)原型链

      当查找对象的属性的时候,先找自身,如果自身没有,则顺着__prototype__找到原型,如果原型也没有,则继续向上找,一直找到Object的原型。这个查找链表就是原型链。

    // 原型对象:存储对象公共属性和方法的地方
    // 每写一个函数,都会有一个原型对象prototype
    
    var arr = new Array(); // Array就是构造函数
    console.log(arr); // arr就是实例
    
    console.log(arr.__proto__); // 原型对象,通过实例找到原型
    console.log(Array.prototype); // 原型对象,通过构造函数找到原型
    
    console.log(arr.__proto__ == Array.prototype); // true

      原型创建对象

    function CreatePerson() { }
    
    // 每声明一个函数,都会有一个原型对象,原型对象默认有一个constructor的属性,它又指向构造函数
    // console.log(CreatePerson.prototype); // CreatePerson的原型   {constructor: ƒ}
    // console.log(CreatePerson.prototype.constructor); // constructor
    
    CreatePerson.prototype.name = 'zs';
    CreatePerson.prototype.age = 3;
    CreatePerson.prototype.showName = function () {
        console.log('小张');
    }
    
    // console.log(CreatePerson.prototype);
    
    // --------------------------
    var p1 = new CreatePerson();
    console.log(p1);
    // console.log(p1.name);
    // p1.showName()
    // console.log(p1.constructor);
    // console.log(p1.toString);
    
    var p2 = new CreatePerson();
    console.log(p2);
    
    console.log(p1.showName == p2.showName); // true
    // 优点:原型方法完美的解决了构造函数会方法会重复创建的问题
    // 不足:不能似参,创建的结果都一样
    
    
    console.log(p2.abc); // undefined

      3.6、混合模式创建对象

    // 是我们创建对象的标准方法
    // 混合模式:构造函数+原型
    // 每个对象独有的写在构造函数里,公有的写在原型上
    function CreatePerson(name, age) {
        this.name = name;
        this.age = age;
    }
    CreatePerson.prototype.showName = function () {
        console.log(this.name);
    }
    
    var p1 = new CreatePerson('zs', 3);
    console.log(p1);
    // console.log(p1.name);
    // p1.showName();
    
    var p2 = new CreatePerson('ls', 5);
    console.log(p2);

      3.7、动态混合模式

    // 动态混合模式
    // 好处:代码有一个封装的感觉
    // 执地原理:同混合模式
    function CreatePerson(name, age) {
        this.name = name;
        this.age = age;
        if (typeof CreatePerson.prototype.showName !== 'function') {
            CreatePerson.prototype.showName = function () {
                console.log(this.name);
            }
            CreatePerson.prototype.showAge = function () {
                console.log(this.age);
            }
        }
    }
    
    var p1 = new CreatePerson('zs', 3);
    console.log(p1);
    
    var p2 = new CreatePerson('ls', 5);
    console.log(p2);

    4、面向对象的案例

      面向对象的选项卡

      原则:先写出普通的写法,然后改成面向对象方法

      1、普通方法变型

      尽量不要出现函数嵌套函数

      可以有全局变量

      把onload中不是赋值的语句放到单独函数中(init)

      2、改成面向对象()

      先写构造函数

      onload中创建对象,并init调用

      全局变量就是属性

      函数就是方法

      (属性和方法前面,都要加this)

      改this指向问题(尽量让this指向对象)

      结论:我们改成面向对象之后,感觉是不是更复杂了?确实是这样,确实是复杂了,但是我们这个面向对象特别适合复杂的开发,对于简单的,不太推荐使用面向对象。面对复杂开发时,它特别容易扩展,同时,复用性特别强。上面的例子,多添加几个,就可以发现特别方便复用和扩展。

      普通方法实现和变形

    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <style>
            span {
                display: inline-block;
                width: 100px;
                height: 30px;
                background-color: #ccc;
                line-height: 30px;
                text-align: center;
                color: white;
                cursor: pointer;
            }
    
            .active {
                background-color: red;
            }
    
            #box div {
                width: 330px;
                height: 150px;
                border: 2px solid #ccc;
                font-size: 40px;
                line-height: 150px;
                text-align: center;
                display: none;
            }
        </style>
        <script>
            // 普通方法实现
            // window.onload = function () {
            //     var box = document.getElementById('box');
            //     var span = box.querySelectorAll('span');
            //     var div = box.querySelectorAll('div');
    
            //     for (var i = 0; i < span.length; i++) {
            //         span[i].index = i; // 自定义下标
    
            //         span[i].onclick = function () {
            //             // 1、所有的span去掉样式,所有的div隐藏
            //             for (var i = 0; i < span.length; i++) {
            //                 span[i].className = '';
            //                 div[i].style.display = 'none';
            //             }
    
            //             // 2、当前的span加上样式,对应的div显示
            //             this.className = 'active';
            //             div[this.index].style.display = 'block';
    
            //         }
            //     }
            // }
    
    
            // ---------------------------------------
            // 普通方法变形
            var box = null;
            var span = null;
            var div = null;
    
            window.onload = function () {
                box = document.getElementById('box');
                span = box.querySelectorAll('span');
                div = box.querySelectorAll('div');
                init();
            }
    
            function init() {
                for (var i = 0; i < span.length; i++) {
                    span[i].index = i; // 自定义下标
    
                    span[i].onclick = change;
                }
            }
    
            function change() {
                // 1、所有的span去掉样式,所有的div隐藏
                for (var i = 0; i < span.length; i++) {
                    span[i].className = '';
                    div[i].style.display = 'none';
                }
    
                // 2、当前的span加上样式,对应的div显示
                this.className = 'active';
                div[this.index].style.display = 'block';
            }
        </script>
    </head>
    
    <body>
        <div id="box">
            <span class="active">html</span>
            <span>css</span>
            <span>js</span>
            <div style="display: block;">html</div>
            <div>css</div>
            <div>js</div>
        </div>
    </body>

      改成面向对象

    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <style>
            span {
                display: inline-block;
                width: 100px;
                height: 30px;
                background-color: #ccc;
                line-height: 30px;
                text-align: center;
                color: white;
                cursor: pointer;
            }
    
            .active {
                background-color: red;
            }
    
            #box div {
                width: 330px;
                height: 150px;
                border: 2px solid #ccc;
                font-size: 40px;
                line-height: 150px;
                text-align: center;
                display: none;
            }
        </style>
        <script>
            // var box = null;
            // var span = null;
            // var div = null;
    
            // window.onload = function () {
            //     box = document.getElementById('box');
            //     span = box.querySelectorAll('span');
            //     div = box.querySelectorAll('div');
            //     init();
            // }
    
            // function init() {
            //     for (var i = 0; i < span.length; i++) {
            //         span[i].index = i; // 自定义下标
    
            //         span[i].onclick = change;
            //     }
            // }
    
            // function change() {
            //     // 1、所有的span去掉样式,所有的div隐藏
            //     for (var i = 0; i < span.length; i++) {
            //         span[i].className = '';
            //         div[i].style.display = 'none';
            //     }
    
            //     // 2、当前的span加上样式,对应的div显示
            //     this.className = 'active';
            //     div[this.index].style.display = 'block';
            // }
    
            // -------------------------------------
            function Tab() {
                this.box = document.getElementById('box');
                this.span = this.box.querySelectorAll('span');
                this.div = this.box.querySelectorAll('div');
            }
            Tab.prototype.init = function () {
                var that = this; // 对象存给了that
                for (var i = 0; i < this.span.length; i++) {
                    this.span[i].index = i; // 自定义下标
                    this.span[i].onclick = function () {
                        // this--span
                        that.change(this);
                    }
                }
            }
            Tab.prototype.change = function (ele) {
                // 1、所有的span去掉样式,所有的div隐藏
                for (var i = 0; i < this.span.length; i++) {
                    this.span[i].className = '';
                    this.div[i].style.display = 'none';
                }
                // 2、当前的span加上样式,对应的div显示
                ele.className = 'active';
                this.div[ele.index].style.display = 'block';
            }
    
            window.onload = function () {
                var t1 = new Tab();
                t1.init();
            }
        </script>
    </head>
    
    <body>
        <div id="box">
            <span class="active">html</span>
            <span>css</span>
            <span>js</span>
            <div style="display: block;">html</div>
            <div>css</div>
            <div>js</div>
        </div>
    </body>
  • 相关阅读:
    PostgreSQL 数据库备份与恢复 pd_dump pg_restore
    给数据库减负的7个技巧
    添加二级域名 配置多站点 阿里云
    PHP 循环输出多重数组元素
    CentOS 7 yum Loaded plugins: fastestmirror, langpacks Loading mirror speeds from cached hostfile
    CentOS 7 配置 nginx php-fpm 详细教程
    Centos7 卸载 Nginx 并重新安装 Nginx
    centos7 取消自动锁屏
    composer 安装以及使用教程
    MacBook Pro设置外接显示器竖屏显示 切换主显示器
  • 原文地址:https://www.cnblogs.com/miaochaofan/p/14753017.html
Copyright © 2011-2022 走看看