zoukankan      html  css  js  c++  java
  • 面向对象之构造函数、实例对象、原型

    一、面向对象
    首先有一个需求,点击按钮改变div的样式。按照常规的思维来写,我们可能是先获取到目标元素,然后给目标元素添加事件,在事件中书写div需要改变的样式属性。如下:

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script type="text/javascript">
    window.onload = function(){
    var btn = document.getElementById('btn');
    btn.onclick = function(){
    var div = document.getElementById('div1');
    div.style.height = '300px';
    div.style.width = '300px';
    div.style.backgroundColor = 'green';
    }
    }
    </script>
    </head>
    <body>
    <div style=" 200px;height: 200px;border:1px solid red;" id="div1"></div>
    <input type="button" value="点击" id="btn">
    </body>
    </html>


    但是随着事件的增多,代码的量也随之加大,如果点击的按钮不止一个,是不是又得将点击事件的代码重写一遍?这样维护起来也不方便;但如果换种思维考虑:是哪个元素要添加何种事件?这个事件是怎样的?就好比如何将大象装进冰箱,首先打开冰箱门,把大象装进去,关闭冰箱门;如果是一万头大象呢,是不是要开关一万次?这时要是大象来了冰箱门能自动开关就好了。所以,换种思维重写代码:

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script type="text/javascript">
    window.onload = function(){
    function ChangeStyle(divId,btnId){
    //构造函数中this是谁?就是实例化对象cs
    this.div = document.getElementById(divId);
    this.btn = document.getElementById(btnId);
    }
    ChangeStyle.prototype.init = function(){
    //原型方法里面this指向谁?就是具体的某个通过构造函数实例化的对象cs
    var _this = this
    this.btn.onclick = function(){
    // 这个功能加到change方法里面,怎么办?
    // this.style.backgroundColor = 'orange';
    _this.change(this);
    //假设这里的代码比价复杂,代码量比较大
    }
    }
    ChangeStyle.prototype.change = function(obj){
    //这里能得到按钮吗?
    // this.btn.style.backgroundColor = 'orange';
    obj.style.backgroundColor = 'pink';
    this.div.style.width = '300px';
    this.div.style.height = '300px';
    this.div.style.border = '1px yellow solid';
    this.div.style.backgroundColor = 'green';
    } 
    //...............
    var cs = new ChangeStyle('div1','btn');
    cs.init();
    }
    </script>
    </head>
    <body>
    <div style=" 200px;height: 200px;border:1px solid red;" id="div1"></div>
    <input type="button" value="点击" id="btn">
    </body>
    </html>


    虽然就单一功能来讲,看似代码量要复杂一些,但是将来拓展功能,很多代码是可以复用的。相对于面向过程编程来讲,面向对象的在一定程度上避免了变量命名冲突,而且复用性强。
    二、对象

    所谓对象就是某种事物;JavaScript对象的实质是无序键值对的集合。产生对象的方式有两种:字面量和构造函数。
    2.1字面量
    通过各种数据类型的字面量表示:

    var num = 12; var num = 1.2;
    
    var str = 'hello'; var flag = true; 
    var arr = [1,2,3]; var reg = /d+/; 
    var obj = {};
    
    //‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ 
    var person = {}; 
    person.name = '胡琦'; 
    person.age = 18; 
    person.sex = '男';

    这里的数据类型可以是基本类型和引用类型。
    2.2构造函数
    内置对象和自定义对象;

    var arr = new Array(); 
    var obj = new Object();
    
    var Obj = new RegExp('d+');
    //‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ 
    function Person(name,age){
    
    this.name = name;
    this.age = age; 
    This.doing = function(){
    
    console.log(this.name + ':撸码');
    
    }
    
    }
    
    var p1 = new Person('胡琦',18);

    三、函数
    JavaScript中函数的三种角色:普通函数,作为构造函数,作为对象;

    <!DOCTYPE html>
    <html>
    <head lang="en">
        <meta charset="UTF-8">
        <title></title>
        <script type='text/javascript'>
    //3.1普通函数
    
    
    function foo(){ 'use strict'
    
    console.log(this);
    
    }
    
    foo();//ES3中,this就是window;ES5的严格模式下,this为undefined
    
    
    3.2对象方法
    
    
    var obj = {}; obj.info = 'hello';
    
    obj.showInfo = function(){ console.log(this.info);
    
    }
    
    foo.showInfo();//对象方法中的this就是调用方法的对象
    
    
    //3.3构造函数
    
    
    function Foo(info){ this.info = info;
    
    this.showInfo = function(){ console.log(this.info);
    
    }
    
    }
    
    Foo.prototype.fn = function(){ //原型对象中的this就是实例对象 console.log(this.info);
    
    }
    
    var foo = new Foo('hello'); foo.showInfo();//对象方法中的this就是实例对象
    
    
    call/apply/bind
    function foo(a,b){ console.log(a + b);
    
    }
    
    foo.call(null,1,2);
    
    foo.apply(null,[1,2]); //改变this指向 var obj1 = {
    
    info : 'Tom'
    
    };
    
    var obj2 = {
    
    info : 'Jerry'
    
    }
    
    window.info = 'Spike';
    
    var    showInfo = function(){ console.log(this.info);
    
    };
    
    showInfo();
    
    showInfo.call(obj1);
    
    showInfo.call(obj2);
    
    //调用call或apply都会自动执行对应的函数,而bind不会执行对应的函数,只是返回了对函数的引用。
    
    
    //高阶函数
    
    //函数作为参数
    
    
    function foo(fn) { var data = {
    
    info: 'hello'
    
    }
    
    fn(data);
    
    }
    
    var    fn = function(data) { console.log(data.info);
    
    };
    
    foo(fn);
    
    
    //函数作为返回值
    
    
    function foo(){ var num = 1;
    
    return function(){ return num++;
    
    }
    
    }
    
    var fn = foo(); var r1 = fn(); var r2 = fn();
    
    console.log(r1,r2);
     </script>
    </head>
    <body>
    
    </body>
    </html>

    四、构造函数、实例对象、原型

    4.1构造函数、原型与实例的关系

    1.每个构造函数都有一个原型对象prototype

    2.原型对象包含一个指向构造函数的指针constructor

    3.原型对象都包含一个指向构造函数的内部指针__proto__


    4.1.1 _proto__

    在函数里有一个属性prototype
    由该函数创建的对象默认会连接到该属性上
    4.1.2 prototype与__proto__的关系

    __proto__是站在对象角度来说的
    prototype是站在构造函数角度说的

    4.2原型链


    原型链是一个由对象组成的有限对象链,用于实现继承和共享属性。

    var obj = new Object();

    对象是有原型对象的,原型对象也有原型对象
    obj.__proto__.__proto__.__proto__

    原型对象也有原型对象,对象的原型对象一直往上找,会找到一个null var arr = [];
    arr -> Array.prototype -> Object.prototype -> null var o = new Object();
    o -> Object.prototype -> null

     
    
    function Foo1(){ this.name1 = '1';
    
    }
    
    function Foo2(){ this.name2 = '2';
    
    }
    Foo2.prototype = new Foo1(); function Foo3(){
    
    this.name3 = '3';
    
    }
    
    Foo3.prototype = new Foo2(); var foo3 = new Foo3(); console.dir(foo3);
    
     

    原型链:实例与原型的链条

    foo3 -> foo2 -> foo1 -> Foo1.prototype -> Object.prototype -> null

    原型链示例

    var arr = [];

    1.arr ‐> Array.prototype ‐> Object.prototype ‐> null var obj = {};
    2.obj ‐> Object.prototype ‐> null

    构造函数、实例对象、原型对象之间额关系:

     总结:

  • 相关阅读:
    一致性哈希算法
    Discourse 的标签(Tag)只能是小写的原因
    JIRA 链接 bitbucket 提示错误 Invalid OAuth credentials
    JIRA 如何连接到云平台的 bitbucket
    Apache Druid 能够支持即席查询
    如何在 Discourse 中配置使用 GitHub 登录和创建用户
    Apache Druid 是什么
    Xshell 如何导入 PuTTYgen 生成的 key
    windows下配置Nginx支持php
    laravel连接数据库提示mysql_connect() :Connection refused...
  • 原文地址:https://www.cnblogs.com/hu-qi/p/5558027.html
Copyright © 2011-2022 走看看