JavaScript - 面向对象编程一


开篇废话是一种情怀

在我们开始学习面向对象之前,首先得先想一个问题,那就是何为对象?

  • 在日常生活中我们有男朋友\女朋友,称之为对象。有了男朋友可以为你遮风挡雨,有了女朋友可以为你洗衣做饭,同理,在我们的二进制编程世界里,对象完全可以理解为工具或者工具包,当然,在某种特定情况下,我们也可以把人比作是工具。
  • 面向对象编程其实是一种思想、思维的转变,从面向过程转变成面呈对象。面向过程注重的是过程,而面向对象注重的是结果,两者的目的相同,但是实现方式却不尽相同。
  • 据说,面向对象思维最早是一个生物学家提出来的,他说:"我们编写的代码就好比生物的每一个细胞,我们的身体的每一个组件都代表一个工具,手供我们吃饭,腿供我们行走,不管那天手不能用了,但它不会影响脚的行走,如果能把每一类型的代码抽取成一个一个的工具,好比,钳子、镊子、锤子,那我们对代码、对工具的管理就会显得非常方便,只需要将这一类工具放到一个工具包里面即可。”
  • 天了噜,废话不多说了,好像开篇废点话,是一种习惯!下面就让我们开始认识面向对象编程。
  • 学习面向对象之前,得先把下面这些东西搞明白!

Js语言的回顾

  • 三个组成部分

    • BOM:全称Browser Object Model 浏览器对象模型,核心对象(window loacation);
    • DOM:Document Object Model 文档对象模型,DOM树,本身为我们操作页面元素提供了一套方法(API),API:application programming interface 应用程序编程接口
    • ECMAScript:规定js的核心语法,js语句,关键字,保留字
  • 数据类型

    • 基本数据类型(简单数据类型)

    string 字符串类型
    number 数值
    boolean 布尔类型(true | false)
    undefined 未定义
    null 空(对象) 这个类型有点特殊

    • 复杂数据类型(复合数据类型)

    Object 对象类型
    Array 数组类型
    Funcation 函数类型
    Date 日期类型
    String 对象
    Number
    Boolean

    • **判断数据类型的关键字是 typeof **
      注意
      复杂数据在使用typeof操作的时候,打印出来的结果都是object ,除了函数

    • 等于和全等

    • 赋值(=)
      等于符号(==):比较的时候只判断数值是否是相等的
      全等符号(===):比较的时候不仅要比较数据还需要比较类型
      不等于(!=)
      不全等于(!==)

    • 关系运算符

    • 返回值:布尔类型,要么是true要么是false

大于 >
小于 <
大于等于 >=
小于等于 <=

  • 逻辑运算符(重点)
  • 逻辑非( ! ) 取反
  • 逻辑或( || )
>**语法:表达式1 || 表达式2
结果:
    判断表达式1,如果表达式1为真,那么就返回表达式
    如果表达式1的值为假,那么就返回表达式2**
- **逻辑与(&&)**
>**语法:表达式1 && 表达式2
结果:
    如果表达式1为真,返回表达式2
    如果表达式1为假,返回表达式1**
- **返回值是表达式,而不是布尔值**
  • 值类型和引用类型(重点)
  • 值类型
>**string
number
boolean
undefined

值类型:存储的是具体的值
赋值:
1.把右边变量存储存储的值(具体的数据)复制一份给左边的变量
2.值类型的赋值,是简单数据的复制,他们保存在相对独立的空间中,彼此不会影响
**
- 引用类型
>**object类型
引用类型:存储的是指向具体值得地址(引用)
赋值:
1.把右边变量存储存储的值(指向具体数据的地址)复制一份给左边的变量
2.引用类型赋值:修改了某个对象的属性,对另外一个对象的属性会有影响
**
- 在函数中的使用
值类型作为函数的参数:
实参和形参他们的数据是相互独立的

<script>
        function func(param){
            console.log(param);  //我是字符串
            param = "我也是一个字符串";
            console.log(param);
        }
        var a = "我是字符串";
        func(a);
        console.log(a);
</script>

引用类型作为函数的参数:
形参和实参共享同一份数据,修改其中的某个对象对另外一个对象也会有影响

<script>
    //02 引用类型作为函数的参数传递
    var obj = {name:"小明"};
    function funcName(param) {
        param.name = "小王";
        param = {
            name:"张明明"
        };
        console.log(param.name);    // 张明明
    }
    funcName(obj);
    console.log(obj.name);   // 小王
    //
   //
    var arr1 = [1,2,3];
    var arr2 = arr1;
    console.log(arr1);
    console.log(arr2);
    //该行代码切断和arr1的关系,对象内保存的地址指向了另外一块内存空间
    arr1.push(4);
    arr2 = [1,2,3];    
    console.log(arr1);  //1,2,3,4
    console.log(arr2);  //1,2,3
</script>
  • 对象的动态特性
  • 已经定义好的对象,我们对它进行增删改查的操作
  • 访问对象有两种形式:

**
1.点语法
在使用点语法设置对象的属性的时候,如果对象中不存在改属性,就是增加操作
如果对象中已经存在该属性,那么就是修改操作
2.[ ] 中括号语法
对象:键 - 值(key-value)对的集合

注意点:在使用[]语法的时候,键应该使用双引用
**

  • in关键词的使用

  • 作用:
    1.遍历对象的key
    2.判断某个对象中是否存在指定的属性

  • 语法
    键 in 对象 返回值:布尔类型的值
    注意点:在使用in关键字的时候,key是字符串,需要加上双引号

  • 遍历数组
    遍历对象 在这里必须使用[ ]语法不能直接使用点语法
    在数组中索引是key ,数组的元素是value

  • delete关键字

    • 作用:
      (1) 删除对象中的属性
      (2) 删除没有使用var关键字声明的全局变量

      注意:
      (1)返回值 布尔类型的值(我们可以通过该值来判断是否删除成功)
      (2)使用var关键字声明的变量无法被删除
      (3)删除对象中不存在的属性没有任何变化,但是返回值为true
      (4)不能删除window下面的全局变量(使用var声明),但是可以删除直接定义在window上面的属性
  • 循环对象

for循环
while
do...while(至少会执行一次)
for...in(主要用于遍历对象)

  • 函数的几种创建
    声明函数
<script>
    function 函数名称 (形参1,形参2)
    {
        //函数体
    }

    //调用
    //函数的名称();

    function funcName (){

    }
</script>

函数表达式

<script>
    //01 匿名函数
    var func01 = function (){
    };
    //02 命名的函数表达式
    var func02 = function func(){
    };
</script>

使用构造函数创建函数对象

<script>
    var func = new Function();   //没有内容(没有函数体)
    func();

    function funcTest (){};     //等价

    var func02 = new Function("console.log('demo');");
    func02();
</script>
<script>
    var obj = {name:"zhangsan"};
    var obj2 = new Object();
    var obj3 = {};
</script>

回顾前面这些呢,就是想让接下来看面向对象的时候,脑海中有个印象和回忆,当然,这也是想到会有一些编程小白理解起来困难的原因。知识点有点枯燥,学编程嘛 得有点耐心才行.

面向过程 & 面向对象

  • 都是一种解决问题的思路(思想)
  • 面向过程在解决问题的时候,关注的是解决问题需要的一个接着一个的过程(步骤)
  • 面向对象在解决问题的时候,关注的是解决问题所需要的对象.
  • 举例
    就用洗衣服来形象的打个比方

如果你是用手洗的话,那就不得不考虑 倒水-搓衣服-加洗衣液-清水涮-手拧干-晾起来 这就是面向过程
但如果你忽略这些步骤 直接放洗衣机洗的话 可能都不用考虑晾干的步骤 这就是面向对象

什么是对象
  • 对象的特征 (静态的描述信息),比如:学号 - 性别 - 年龄 - 家庭住址 - 身高 - 体重 ... 等等
  • 有的对象有行为 (动态的特征), 比如:吃饭 - 睡觉 - 开车 - 玩游戏 - 谈恋爱
  • 代码示例
    var zhangsan = {
            name:"张三",
            sex:"男",
            age:18,
            address:"天上人间1号公馆",

            eat:function () {
                console.log('能吃');
            },
            sleep:function () {
                console.log("能睡");
            },
            say:function () {
                console.log("能说话");
            },
            run:function () {
                console.log("能运动");
            },
            song:function () {
                console.log("能唱歌");
            }
        };

        //打印对象的属性并调用相关的方法
        console.log(zhangsan.name,zhangsan.age,zhangsan.address);
        zhangsan.say();
        zhangsan.sleep();
现实中的对象和编码中的对象
  • 静态的描述信息:属性
  • 动态的行为特征:方法
  • 面向对象和面向过程都是解决问题的一种方式(思想),没有孰优孰劣之分
  • 面向对象本身是对面向过程的封装
为什么要使用面向对象编程?
  • 更方便
  • 复用性会更好
    高内聚和低耦合(电路)
    冗余(重复的东西)-->封装(提取相同的部分作为函数体,抽取不同的部分作为参数)
js对象是由两个对象组成的
  • 一个叫构造函数对象
  • 一个叫原型对象
编程语言
  • ** 汇编语言是对内存的地址进行编程的**
  • ** C语言是第一款比较流行的面向过程语言 **
  • ** C语言和面向对象是编程世界一个划时代的里程碑**
  • ** 构造函数和普通函数是一回事,只不过构造函数是通过普通函数实现的**
面向对象的特性:
  • 封装
    作用:方便代码的维护,提高代码的复用性,更安全的访问数据的方式
    注意: js中的封装多了一层意思,就是使用对象来封装变量和函数
  • 继承
    • 现实生活中的继承:继承遗产,一个人获得另一个人所拥有的财富或者是资源的方式。
    • 编程语言中的继承:一个类(对象)获得另外一个类(对象)的属性和方法的一种方式。
    • 面向对象的语言特征:类(C++)C(没有类)
    • js中没有类(class),支持面向对象的语言。
  • 多态
    • 表现:
      对于相同的操作,不同的对象表现出不同的行为。
      隐藏不同。
    • 实现:
      js天生具备多态的特性(弱类型的语言)
创建对象的四种方法
  • 字面量的方式
var book1 = {
        name:"悟空传",
        author:"今何在",
        press:"湖南文艺出版社",
        price:"28.00",
        logDes:function(){
            console.log("书名:" + this.name + "作者:" + this.author);
        }
    }
    var book2 = {
        name:"什么是批判",
        author:"福柯",
        press:"北京大学出版社",
        price:"52.00",
        logDes:function(){
            console.log("书名:" + this.name + "作者:" + this.author);
        }
    }
    var book3 = {
        name:"数据结构",
        author:"严蔚敏",
        press:"清华大学出版社",
        price:"30.00",
        logDes:function(){
            console.log("书名:" + this.name + "作者:" + this.author);
        }
    }

    console.log(book1.name);
    boo1.logDes();

存在的问题:
创建的对象无法复用,复用性差
如果需要创建多个相似的对象,那么代码中冗余度太高(重复的代码太多)

  • 内置的构造函数
    //01 创建空的对象
    var book1 = new Object();
    //02 设置属性
    book1.name = "花田半亩";
    book1.author = "田维";
    book1.price = "40.01";

    //03 设置方法
    book1.logDes = function (){
        console.log("书名:" + this.name);
    }

    book1.logDes();

    //创建多个对象
    var book2 = new Object();
    book2.name = "三国演义";
    book2.author = "罗贯中";
    book2.price = "34.01";
    book2.logDes = function (){
        console.log("书名:" + this.name);
    }
    console.log(book1);
    console.log(book2);

存在的问题:
创建的对象无法复用,复用性差
如果需要创建多个相似的对象,那么代码中冗余度太高(重复的代码太多)

  • 简单工厂函数创建对象
    //01 封装创建对象的过程
    function createBook () {

        var book = new Object();
        book.name = "声名狼藉者的生活";
        book.price = 42.00;
        book.author = "福柯";
        book.press = "北京大学出版社";
        book.read = function () {
            console.log("我的书名为:声名狼藉者的的生活,作者为福柯....");
        };
        return book;
    }

    //02 使用封装好的工厂函数来创建对象
    var book1 = createBook();
    var book2 = createBook();

    //03 打印对象的属性并调用对象的方法
    console.log(book1.name);
    console.log(book2.name);
    book1.read();
    book2.read();

    console.log("_________________________");
    //04 说明:以上代码确实能够快速简单的创建出新的对象,但是创建出来的对象内部的属性和方法相同,这并不是我们想要的。

    //05 对上面的工厂函数进行改进
    //改进思路:封装不变的部分,提取变化的部分作为参数
    function createBookNew (name,price,author,press) {

        var book = new Object();
        book.name = name;
        book.price = price;
        book.author = author;
        book.press = press;
        book.read = function () {
            console.log("我的书名为:"+book.name+",作者为"+book.author+"....");
        };

        return book;
    }

    //06 使用新的工厂函数来创建对象
    var book1 = createBookNew("声名狼藉者的的生活","42.00","福柯","北京大学出版社");
    var book2 = createBookNew("人性的枷锁","49.00","毛姆","华东师范大学出版社");
    var book3 = createBookNew("悟空传","28.00","今何在","湖南文艺出版社");

    //07 打印对象的属性,调用对象的方法
    console.log(book1.name);
    console.log(book2.name);
    console.log(book3.name);

    book1.read();
    book2.read();
    book3.read();

存在的问题:
如果创建多个不同类型的对象,那么我们无法分辨

  • 自定义构造函数创建对象
    • 提供一个构造函数
    • 通过this指针来设置属性和方法
    • 通过new操作符创建对象
    //1.提供一个构造函数
    //构造函数简单介绍:
    //作用:对对象进行一些初始化的设置
    //和普通函数区别:(01)首字母大写(02)调用方式不一样和new配合使用
    function Person(name,age){
        // 默认 创建对象
        //var o = new Object();
        //默认会赋值给this
        //this = o;
        //2. 通过this指针来设置属性和方法
        this.name = name;
        this.age = age;
        this.showName = function(){
            console.log(this.name);
        };
        this.showAge = function(){
            console.log(this.age);
        }
        //默认返回
        //return this;
    }
    //3. 使用new操作符来创建对象
    var p1 = new Person("张三",20);
    var p2 = new Person("张老汉",200);
    console.log(p1);
    console.log(p2);
/*
 1.  自定义构造函数方式创建对象内部的实现细节
1.1 我们在使用new关键字调用构造哈函数的时候,内部默认会创建一个空的对象
1.2 默认会把这个空的对象赋值给this
1.3 通过this来设置新对象的属性和方法
1.4 在构造函数的最后,默认会把新创建的对象返回
2.自定义构造函数和工厂函数对比
2.1 函数的名称不一样,构造函数首字母大写
2.2 自定义构造函数创建方式内部会自动的创建空对象并且赋值给this
2.3 默认会自动返回新创建的对象
3.返回值
3.1. 没有显示的return ,默认会把新创建的对象返回
3.2. 显示的执行了return语句,就得看具体的情况
3.2.1 返回的是值类型,那么直接忽略该返回,把新创建的对象返回
3.2.2 返回的是引用类型的数据,会覆盖掉新创建的对象,直接返回引用数据类型的值
*/
        function Dog(name)
        {
            this.name = name;
            //return "demo";  忽略
            //return function (){};
        }

        var dog = new Dog("阿黄");
        console.log(dog);
构造函数的的注意事项
  • 函数传值
function Student(number,className,log){
        this.number = number;
        this.className = className;
        this.log = log;
    }

    var stu1 = new Student("201601","九阴真经修炼01班",function(){
       console.log("学号:" + this.number);
    });

    var stu2 = new Student("201602","九阴真经修炼01班",function(){
        console.log("班级名称:" + this.className);
    });

    stu1.log();
    stu2.log();
  • 对象的类型(判断)
function Person(){};
    function Dog(){};

    var p1 = new Person();
    var dog1 = new Dog();

    //关键字 instanceOf 用来判断当前对象是否是某个类型的实例(检查某个对象是否是使用指定构造函数创建的)
    //语法: 对象 instanceOf 构造函数(类型)
    console.log(p1 instanceof Person);
    console.log(p1 instanceof Dog);
    console.log(dog1 instanceof Person);
    console.log(dog1 instanceof Dog);
  • 构造器属性(获取
function Person(){};
    function Dog(){};
    var p1 = new Person();
    var dog1 = new Dog();

    //在所有的对象中,都拥有一个构造器属性:constructor
    console.log(p1.constructor);
    console.log(dog1.constructor);
  • 函数调用
    new :创建对象,并在最后返回该对象
    构造函数:用于初始化对象
    以普通函数的方式来调用构造函数,那么内部的this指向的是window
function Person(name)
    {
        if(this instanceof Person)
        {
            this.name = name;
        }else
        {
            return new Person(name);
        }
    }

    var p1 = new Person("哔哩哔哩");

    //构造函数本身是一个函数,在调用可以直接调用
    var p2 =  Person("哗啦哗啦");  //这是一个错误的演示(不要这样写代码)
    console.log(p2);  //undefined
  • 存在问题
    ** 把函数写在外部,破坏了封装性。
    增加一个全局变量。**
var showName = function(){
            console.log("姓名:");
    }

    function Person(name,age){
        this.name = name;
        this.age = age;
        this.showName = showName;
    }

    //创建对象
    var p1 = new Person("张小花",18);
    var p2 = new Person("张全蛋",99);
    p1.showName();
    p2.showName();

    //每创建一个对象,内部都会声明一个showName函数
    console.log(p1.showName == p2.showName);  //false

思维导图 --> 如果图片不是很清晰的话 请下载到本地查看 !

**Js - 面向对象编程一**

未完待续! 接下来会讲解构造函数的原型对象!!
内容枯燥, 但是每一个牛逼的工程师都是这样一步一步走过来的.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,117评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,328评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,839评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,007评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,384评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,629评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,880评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,593评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,313评论 1 243
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,575评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,066评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,392评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,052评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,082评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,844评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,662评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,575评论 2 270

推荐阅读更多精彩内容