JavaScript高级教程(面向对象编程)

3 篇文章 0 订阅
3 篇文章 0 订阅

目录

面向对象编程

ES6中的类和对象

构造函数和原型

对象原型__proto__

constructor构造函数

构造函数、实例、原型对象三者之间的关系

原型链

扩展内置对象

继承


面向对象编程

有两大编程思想:面向过程和面向对象;

面向过程编程POP(Process-oriented programming)

面向过程即分析出解决问题所需要的步骤,然后用函数将这些步骤一步步实现,使用的时候再一个个的一次调用就可以了;

即将大象装进冰箱,从面向过程来看,需要打开冰箱门、装进去大象、关上冰箱门

面向对象编程OOP(Object Oriented Programming)

面向对象即把事务分解成为一个个对象,然后由对象之间分工与合作;是以对象功能来划分问题,而不是步骤;在面向对象程序开发思想中,每一个对象都是功能中心,具有明确分工;

面向对象编程具有灵活、代码可复用、容易维护和开发的优点,更适合多人合作的大型软件项目;

具有封装性、继承性、多态性等特性;

即将大象装进冰箱,从面向对象来看,要先找出对象,并写出 这些对象的功能;如大象对象,冰箱对象;

面向过程与面向对象编程思想两种方式对比:

面向过程

面向对象

优点

性能比面向对象高,适合跟硬件联系很紧密的东西,如单片机就采用的面向过程编程

易维护、易复用、易拓展,可设计出低耦合的系统,使系统更加灵活、更加易于维护

缺点

没有面向对象易维护、易复用、易拓展

性能比面向对象低

面向对象的思维特点:

1、抽取(抽象)对象共用的属性和行为组织(封装)成一个类(模板);

2、对类进行实例化,获取类的对象

面向对象编程我们考虑的是有哪些对象,按照面向对象的思维特点,不断的创建对象,使用对象,指挥对象做事情;

ES6中的类和对象

  • 对象

在JavaScript中,对象是一组无序的相关属性和方法的集合,所有的事物都是对象,如字符串、数值、数组、函数等;

对象是由属性和方法组成的:

属性:事物的特征,在对象中用属性来表示(名词);

方法:事物的行为,在对象中用方法来表示(动词);

  • 类(class):

在ES6中新增了类的概念,可用class关键字声明一个类,之后用该类实例化对象;

类和对象关系:

类抽象了对象的公共部分,它泛指某一大类(class);

对象特指某一个,通过类实例化一个具体的对象

创建类

class 类名 { // 此处类名不要加括号

// 类中的函数体

}

创建实例:

var xx = new 类名(); // 类必须使用new实例化对象

类constructor构造函数

constructor()方法是类的构造函数(默认方法),用于传递参数,返回实例对象,通过new命令生成对象实例,自动调用该方法。若没有显示定义,类内部会自动给我们创建一个constructor()。

 <script>
        // 创建类
        class Person {
            constructor(uname, sex, age) {
                this.uname = uname;
                this.sex = sex;
                this.age = age;
            }
        }
        // 创建实例对象
        var xm = new Person('小明', 'female', 19);
        var xs = new Person('小衫', 'male', 18);
        console.log(xm, xs);
 </script>

输出结果如下:

类中添加方法:

类中所有函数均不需要写function,且多个函数方法之间不需要添加符号分隔;

 <script>
        // 创建类
        class Person {
            constructor(uname, sex, age) {
                    this.uname = uname;
                    this.sex = sex;
                    this.age = age;
                }
                // 类中添加方法
            Say() {
                console.log('我叫' + this.uname, '性别' + this.sex, '今年' + this.age);
            }
        }
        // 创建实例对象
        var xm = new Person('小明', '女', 19);
        var xs = new Person('小衫', '男', 18);
        console.log(xm, xs);
        // 通过实例调用方法
        xm.Say(); // 我叫小明 性别女 今年19
        xs.Say(); // 我叫小衫 性别男 今年18
    </script>

继承

继承是指子类可以继承父类的一些属性和方法,语法如下;

class Father {
  // 父类
}
class Son extends Father {
  // 子类继承父类
}

看下面一个错误示例:

<script>
        class Father {
            constructor(x, y) {
                this.x = x;
                this.y = y;
            }
            sum() {
                console.log(this.x + this.y);
            }
        }
        class Son extends Father {
            constructor(x, y) {
                this.x = x;
                this.y = y;
            }
        }
        var son = new Son(1, 2);
        son.sum();
</script>

运行该代码,会报如下错误:

Uncaught ReferenceError: Must call super constructor in derived class before accessing 'this' or returning from derived constructor
    at new Son (ObjTsting.html:24:17)

这是因为子类中无法使用父类的sum方法,在父类方法中this.x和this.y中的this指代的是父类,而子类中传过来的参数中,this.x和this.y指代的是子类,所有会报错;

那要如何继承父类中的参数和方法呢?此时则需要super关键字~

super关键字

它用于访问和调用对象父类上的函数,可以调用父类的构造函数,也可以调用父类的普通函数,上述例子就可以改造成:

 <script>
        class Father {
            constructor(x, y) {
                this.x = x;
                this.y = y;
            }
            sum() {
                console.log(this.x + this.y);
            }
        }
        class Son extends Father {
            constructor(x, y) {
                super(x, y); // 调用父类的构造函数
            }
        }
        var son = new Son(1, 2);
        son.sum(); // 3
</script>

继承是指若子类有属性和方法,则用子类的属性和方法,若无,则继承父类方法;

子类在构造函数中使用super,必须放到this前面(即必须先调用父类的构造方法,再使用子类的构造方法);

<script>
        class Father {
            constructor(uname, sex) {
                this.uname = uname;
                this.sex = sex;
            }
        }
        class Son extends Father {
            constructor(uname, age) {
                super(uname); // 调用父类的构造函数(uname)
                this.age = age; // 定义子类独有的属性
            }
        }
</script>

类里面共有的属性和方法一定要加this使用;构造函数中的this 指向的是创建的实例对象;谁调用类中的方法,this就指向谁;

在ES6中类没有变量提升,所以必须要先定义类,才能通过类实例化对象;

构造函数和原型

构造函数和原型是在ES6出来之前存在的,后被类取代;在ES6之前,对象不是基于类创建的,而是用一种成为构造函数的特殊函数来定义对象和它们的特征。

创建对象可通过如下三种方式:

1、对象字面量

2、new Object()

3、自定义构造函数

<script>
        var obj1 = {}; // 通过字面量创建对象
        var obj2 = new Object(); // 利用new创建对象
        function Obj3(uname, age) { // 利用构造函数创建对象
            this.uname = uname;
            this.age = age;
            this.sing = function() {
                console.log('这是构造函数中包含的方法');
            }
        }
        var dog = new Obj3('小狗', 1);
        var cat = new Obj3('小猫', 1.5);
</script>

构造函数是一种特殊的函数,主要用于初始化对象,即为对象成员变量赋初始值,它总与new一起使用,他们可把对象中一些公共的属性和方法抽取出来,然后封装到这个函数里面;

在JS中,使用构造函数时要注意以下两点:

1、构造函数用于创建某一类对象,其首字母要大写;

2、构造函数要和new一起使用才有意义

new 在执行时会做四件事情:

1、在内存中创建一个新的空对象;

2、让this指向这个新的对象;

3、执行构造函数里面的代码,给这个新对象添加属性和方法;

4、返回这个新对象(所以构造函数里面不需要return)

实例成员与静态成员

构造函数中的属性和方法我们称为成员,成员可以添加;

实例成员就是构造函数内部通过this添加的成员;实例成员只能通过实例化的对象来访问;不可以通过构造函数来访问实例成员;

静态成员及在构造函数本身上添加的成员;静态成员只能通过构造函数来访问

<script>
        function Obj3(uname, age) { // 利用构造函数创建对象
            this.uname = uname;
            this.age = age;
            this.sing = function() {
                console.log('这是构造函数中包含的方法');
            }
        }
        var dog = new Obj3('小狗', 1);
        console.log(dog.uname); // 小狗 // 只能通过实例化的对象来访问实例成员
        console.log(Obj3.uname); // undefined 不可以通过构造函数访问实例成员
        // 静态成员是指在构造函数本身上添加的成员,静态成员只能通过构造函数来访问
        Obj3.sex = 'male';
        console.log(Obj3.sex); // male
</script>

构造函数的问题

构造函数方法很好用,但是存在浪费内存的问题;

不同实例对象会开辟多个空间用于存放同一个函数,这样就会造成内存浪费;

既然使用同一个对象构建出来的实例对象,那么该函数和属性应该是所有对象所共享的,JavaScript规定,每一个构造函数都有一个prototype属性,指向另一个对象。注意,这个prototype就是一个对象,这个对象的所有属性和方法,都会被构造函数所拥有。因此可以将那些不变的方法,直接定义在prototype上,这样所有对象的实例就可以共享这些方法。

对象原型__proto__

对象都会有一个属性__proto__指向构造函数的prototype原型对象,之所以我们对象可使用构造函数prototype原型对象的属性和方法,就是因为对象有__proto__原型的存在。

  • __proto__对象原型和原型对象prototype是等价的
  • __proto__对象原型的意义就在于为对象的查找机制提供一个方向,或者说一条路线,但是它是一个非标准属性,因此实际开发中,不可以使用这个属性,它只是内部指向原型对象prototype,即如下示意图:

constructor构造函数

对象原型(__proto__)和构造函数(prototype)原型对象里面都有一个属性constructor属性,constructor我们称为构造函数,因为它指回构造函数本身。

他主要用于记录该对象引用于哪个构造函数,它可以让原型对象重新指向原来的构造函数。

<script>
        function Obj3(uname, age) { // 利用构造函数创建对象
            this.uname = uname;
            this.age = age;
        }
        Obj3.prototype = {
            sing: function() {
                console.log('wangwang');
            }
        }
        var dog = new Obj3('小狗', 1);
        console.log(Obj3.prototype); 
        console.log(dog.__proto__);
        console.log(Obj3.prototype === dog.__proto__); // true
</script>

构造函数、实例、原型对象三者之间的关系

原型链

(图来自黑马程序员pink老师前端教程~)

只要是对象,就有原型对;

当访问一个对象的属性(包括方法)时,首先查找这个对象自身有没有该属性;

若没有则查找它的原型(即__proto__指向的prototype对象);

如果还没有就查找原型对象的原型,以此类推一直找到Object为止;

__proto__对象原型的意义就在于为对象成员查找机制提供一个方向,或者说是一条路线

扩展内置对象

可以通过原型对象,对原来的内置对象进行扩展自定义的方法,比如给数组增加自定义求偶数和的功能;

<script>
        console.log(Array.prototype);
        Array.prototype.sum = function() {
            var sum = 0;
            for (var i = 0; i < this.length; i++) {
                sum += this[i];
            }
            return sum;
        }
        var arr = [1, 2, 3, 4];
        console.log(arr.sum()); // 10
</script>

注意:数组和字符串内置对象不能给原型对象覆盖操作Array.prototype = {},只能是Array.prototype.xxx = function() {}的方法

继承

同理,ES6之前亦没有extends继承,我们可以通过构造函数+原型对象模拟实现继承,被称为组合继承;

  • 使用call()方法

调用call()方法可以修改函数运行时的this指向,语法如下:

函数名.call(thisArg, arg1, arg2,....)

其中,thisArg为当前调用函数this的指向对象,args等为传递的其它参数;

<script>
        function fn(x, y) {
            console.log('看看这个数是多少');
            console.log(this);
        }
        var o = {
            sum: 12
        }
        fn.call(o, 1, 2); // this指向了o,里面含有sum
</script>
欢迎您继续学习Javascript高级教程。我还将向你们展示<br>Javascript的许多神奇功能,使你能够制作真正对多媒体应用<br>程序。 <br>今天我们将学习一项很有用而且很有趣的内容:cookies - 这<br>是用来记录访问过你的网页的人的信息。利用Cookies你能记录<br>访问者的姓名,并且在该访问者再次访问你的站点时向他发出<br>热情的欢迎信息。你还可以利用cookie记忆用户端的特点 - 如<br>果访问者的所接入的网线的速度慢,cookie可以自动告诉你在<br>给其发送网页的时候只发送尽可能少的图片内容。<br><br>只要你在合理的范围内使用cookies(不要用它探询用户的个人<br>隐私),cookies还是相当实用得。所以我要向你们介绍cookies<br>的工作原理,但是在正式开始之前,我们先谈两个JavaScript<br>内容:有趣的字符串处理以及相关数组。>><br>由于cookies牵扯到向用户的硬盘写盘和读取信息,所以就涉及<br>一个保密性的问题.如果你需要大量什么cookies,你应该阅读<br>一下Marc Slayton写的cooikies揭密以及重新考察cookies.这<br>些文章将告诉你cookie的实质和作用范围以及其内在的局限性.<br>其最重要的局限性在于:不是每个人的浏览器都欢迎cookies.<br>即便是用户的浏览器欢迎cookies,但用户也有可能拒绝cookies<br>的访问(大部分人还是欢迎的)每个域名只分配20个cookies,<br>所以要节省着什么它们.Cookies不得大于4 KB,当然4,000字<br>节的容量是足够的了.<br><br>cookie路径和域 这是掌握cookie最后的一个障碍:缺省情况下cookie只能被在同一个Web服务器上同一个路径下设置了该cookie的网页读取.<br><br>对象和方法的识别 <br>最佳的方法是你先确定某一段代码具备什么功能,然后搞清楚<br>浏览器具备什么功能。 <br><br>对象给我们组织信息提供了一个很好的手段。首先我们看<br>看现实生活中的对象。比如说,一只猴子就是一个对象。它有<br>高度,宽度,毛发等等属性。所有的猴子都有相同的这些属性<br>类型,是属性的值的不同才使一只猴子与其它猴子区别开来。<br>猴子也有自己的方法,如玩儿play(),吃eat(),睡sleep()等。<br><br>对象很好理解还因为它能够保持有关词的“感觉”。例如<br>JavaScript中的聚焦方法focus(),很显然就是使什么东西成为<br>焦点。当聚焦方法作用到窗口对象时,它使该窗口弹到前面。<br>
第1 章 JavaScript 基 础 1.1 关 于JavaScript 1.2 了 解JavaScript 1.3 World Wide Web 1.4 Web 应用程序结构 1.5 JavaScript 与VBScript 第2 章 JavaScript 与HTML 2.6 HTML 基 础 2.7 在HTML 文档中嵌入JavaScript 2.8 编写JavaScript 脚本 第3 章 JavaScript 基本语法 3.9 JavaScript 基本数据结构 3.10 JavaScript 运算符和表达式 3.11 JavaScript 控制结构和循环 第4 章 Window 窗口对象 4.12 Window 窗口对象的属性 4.13 Window 窗口对象的方法 4.14 创建和关闭窗口 第5 章 document 对 象 5.15 document 对象的属性 5.16 document 对象的方法 第6 章 文 本 对 象 6.17 文本对象属性 6.18 文本对象的方法 6.19 文本对象的事件 6.20 文本区域对象 第7 章 按 钮 对 象 7.21 button submit reset 对 象 7.22 复选框对象 7.23 Radio 对 象 第8 章 选择和隐藏对象 8.24 select 对 象 8.25 隐 含 对 象 第9 章 location 对 象 9.26 hash 属 性 9.27 Href 属 性 9.28 pathname 属 性 9.29 Protocol 属 性 第10 章 history 对 象 第11 章 layer 对 象 11.30 layer 属 性 11.31 layer 对象的方法 11.32 JavaScript 操作层 第12 章 字符串对象 12.33 转 义 字 符 12.34 字符串对象的属性 12.35 字符串对象的方法 第13 章 日期对象 13.36 时间对象的属性 13.37 时间对象的设置 第14 章 数 学 对 象 14.38 math 对象的属性 14.39 math 对象的方法 第15 章 数 组 对 象 15.40 数组对象的创建 15.41 数组对象的扩充 15.42 对象类数组 第16 章 样式单实例 16.43 样式单的实用 16.44 样式单的定义 16.45 样式单的使用 第17 章 实用小程序 17.46 导 言 17.47 状态栏滚动信息 17.48 计算用户来访次数 17.49 散布页面的星星 17.50 永在顶端的图片 第18 章 JavaScript 语言的扩展 18.51 ActiveX 通 信 18.52 调用插入件 第19 章 网上购物系统 19.53 示 例 特 性 19.54 源 代 码 19.55 功 能 概 述 19.56 程 序 详 解 第20 章 2000 珍藏版 20.57 Cookie 入 门 20.58 实 例 特 性 20.59 程序源代码 20.60 功 能 概 述 20.61 程 序 详 解 第21 章 时 钟 日 历 21.62 示 例 特 性 21.63 源 代 码 21.64 功 能 概 述 21.65 程 序 详 解 第22 章 JavaScript 服务器端编程 22.66 预 备 知 识 22.67 实 例 学 习 22.68 功 能 概 述 22.69 脚 本 详 解 第23 章 网络安全性 23.70 安全性破坏的种类 23.71 安 全 服 务
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值