对象:一切事物皆是对象。对象是一个整体,对外提供一些操作。比如说一个收音机是一个对象,我们不需要知道它的内部结构是什么,只需要会使用外部的按钮就可以使用收音机。

面向对象:面向对象语言的标志是他们都有类的概念,通过类可以创建任意多个具有相同属性的方法的对象。任何对象都是某一类事物的实例,简单的说就是使用对象时,只关注对象提供的功能,不关注其内部细节。

面向对象的特点:封装,继承,多态。

JS中面向对象的组成:1.方法(函数):过程,动态的 2.属性(有所属关系的变量):状态,静态的

对象是无序属性的集合,其属性可以包括基本值、函数、对象。每个属性都会有一个名字,每个名字映射到一个值上

下面是创建一个对象的一些方法

1.工厂模式

1 function createPerson (name,sex) {//工厂方式构造一个对象 2 3         //1.原料 4         var obj=new Object(); //new一个空白对象 5         6         //2.加工 7         obj.name=name; 8         obj.sex=sex;9 10         obj.showName=function(){11             console.log('我的名字叫:'+this.name)12         }1314         obj.showSex=function(){15             console.log('我是:'+this.sex+'的')16         }17         18         //3.出厂19         return obj;//这一步千万不能那下20     }21 22     var p1=createPerson('木木','女');//每用一次createPerson 就会new一个对象,每个对象都有一套自己的方法 造成资源浪费23     var p2=createPerson('扬扬','男');24 25     p1.showName();26     p1.showSex();27     p2.showName();28     p2.showSex();

使用工厂方式构造对象步骤:

1,原料

2.加工

3.出厂

工厂方式不常用,因为有缺点:1.没有new 2.每个对象都有一套自己的函数,造成资源的浪费

怎么解决这个两个问题呢?那么请看下面

2.构造函数模式

1 function Person (name,sex) {//构造函数   构造一个对象 2         this.name=name;//this:当前的方法属于谁(在函数前面有new时会失效) 3         this.sex=sex; 4 5         this.showName=function(){ 6             console.log('我的名字叫:'+this.name); 7         } 8 9         this.showSex=function(){10             console.log('我是:'+this.sex+'的');11         }12        13     }14 15     var p1=new Person('木木','女');  //外面加new后Person函数里面就不用new一个空白对象16     var p2=new Person('扬扬','男');17 18     console.log(p1.showName==p2.showName);//fase19 20     p1.showName();21     p1.showSex();22     p2.showName();23     p2.showSex();

注意:一般将Person称为构造函数,并且构造函数的名字首字母大写,这是编码规范。

this:表示当前的方法属于谁,但是在这里当this碰到New时就会失效。

用造函数模式解决了上面工厂模式没有New的问题

这时就要想一想了在使用new操作符调用构造函数创建一个新实例的过程中发生了什么呢?一个新实例是怎么生成的呢?

这种方式调用构造函数经历以下四个步骤:

1.创建一个新对象

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

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

4.返回新对象

1 function show(){2         alert(this);3     }4     show();//弹出window对象(当在全局作用域中调用一个函数时,this对象总指向window对象,全局函数属于window的一个方法)5     new show();//弹出obj (this会指向)新创建的一个对象

面这个例子会看得更加清楚

作为普通函数调用:

1 var name = "mumu"; 2         function Person(name){ 3             this.name = name; 4             this.show = function(){ 5             console.log("我是" + this.name); 6             } 7         } 8 9        Person("javascript");10         console.log(name);//结果是javascript

全局变量name被修改了

作为构造函数调用:

1 var name = "mumu"; 2         function Person(name){ 3             this.name = name; 4             this.show = function(){ 5             console.log("我是" + this.name); 6             } 7         } 8 9        var Name = new Person("HTML");10         console.log(Name.name);11         console.log(name);

this指向新对象Name,全局变量name也没有变化

那么问题又来了:

1 console.log(p1.showName==p2.showName);//fase

不同实例的showName()函数是不相同的,那么怎么解决这个问题呢?下面是一个解决办法

1 function Person (name,sex) {//构造函数   2         this.name=name;//this:当前的方法属于谁(在函数前面有new时会失效) 3         this.sex=sex; 4 5         this.showName=showName; 6         7     } 8     function showName(){ 9             console.log('我的名字叫:'+this.name+'我是:'+this.sex+'的');10         }11 12     var p1=new Person('木木','女');  //外面加new后Person函数里面就不用new一个空白对象13     var p2=new Person('扬扬','男');14 15     console.log(p1.showName==p2.showName);//ture16 17     p1.showName();18     p2.showName();

将showName定义成一个全局方法,这样每个实例共享的都是全局方法showName()。不相等的问题是解决了,可是如果构造函数里有大量的方法,这就造成代码中有大量的全局变量,这样我们自定义的引用类型就没有封装性了,资源还是照样浪费。那么怎么解决这个问题呢?请看原型模式

3.原型模式

1 function Person(name,sex) {//原型模式构造函数   2         Person.prototype.name=name; 3         Person.prototype.sex=sex; 4         Person.prototype.showName=function(){ 5             console.log('我的名字叫:'+this.name+'我是:'+this.sex+'的'); 6         } 7     } 8 9     var p1=new Person('木木','女');10     var p2=new Person('扬扬','男');11 12     console.log(p1.showName==p2.showName);//ture13     14     p1.showName();15     p2.showName();

prototype(原型)返回对象类型原型的引用。这个属性是一个指针,指向对象。可以让所有对象实例共享它所包含的属性和方法,可以扩展系统对象,节省系统资源,所以这里解决了上面资源浪费问题。

原型的问题:是当一个实例改变属性值时,所有实例对应的属性值也都跟着改变,无法初始化属性值,当为对象实例添加一个属性时,这个属性就会屏蔽原型对象中保存的同名属性,下面是个小例子:

1 function Person(name,sex) {//原型模式构造函数   2         Person.prototype.name=name; 3         Person.prototype.sex=sex; 4         Person.prototype.showName=function(){ 5             console.log('我的名字叫:'+this.name+'我是:'+this.sex+'的'); 6         } 7     } 8 9     var p1=new Person('木木','女');10     var p2=new Person('扬扬','男');11     12     p1.name="兮兮";13 14     p1.showName();//兮兮 来自实例15     p2.showName();//扬扬 来自原型

前面几种方法都各有各优缺点,那么把它们综合一下又会怎么样呢?

4.组合使用构造函数模式和原型模式

1 //构造函数模式定义实例属性 2     function Person (name,sex) {   3         this.name=name; 4         this.sex=sex; 5     } 6     7     //原型模式共用方法和共享属性 8     Person.prototype.showName=function(){9             console.log('我的名字叫:'+this.name+'我是'+this.sex+'的')10         }11 12     var p1=new Person('木木','女'); 13 14     p1.showName();

这种方法是最常用的,结合了两种方法的优点,最大限度地节省了内存

5.动态原型模式

1 function Person(name, age) { 2     this.name = name; 3     this.age = age; 4 5         //方法 6         if(typeof this.showName != 'function') { 7             Person.prototype.showname = function() { 8                 console.log("我的名字是: " + this.name); 9             }10         }11     }12     var person1 = new Person("mumu", 17);13     person1.showname();

动态原型方法可以通过检查方法是否有效,决定初始化的原型。这种方法堪称为完美,但是不能使用面向字面量重写原型,这样会切断现有实例与新原型之间的联系。

6.寄生构造函数模式

1 function createPerson(name, age) { 2         var obj=new Object(); 3         obj.name = name; 4         obj.age = age; 5         obj.showName = function() { 6             console.log("我的名字是:" + this.name); 7         } 8         return obj; 9     }10     var person = new createPerson("mumu", 17);11     person.showName();

此方法可以和工厂模式对比一下,创建实例方法与构造函数相同,其余与工厂模式相同。如果前面方法都不适用可以考虑一下这种方法,但是这种方法构造函数返回的对象与实例没有关系,也不能依赖instanceof判断对象类型,因此,如果可以使用其他模式这种方法建议还是不要使用。

7.稳妥构造函数模式

1 function Person(name, age) { 2         var obj = new Object(); 3         //定义一些私有变量和函数 4         obj.showName = function() { 5             console.log("我的名字是:" + name); //定义的私有变量等只能通过showName访问 6         } 7         return obj; 8     } 9     var person1 = Person("兮兮", 17);10     person1.showName();

所谓稳妥对象,指的是没有公共属性。这种方法适合用于在安全的环境下,因为它不使用new调用构造函数,也不使用this引用实例方法。若想访问其属性,只能通过showname方法来访问其内部私有属性。

解释型语言

一般来说,我们平常用到的大部分语言为分解释型语言和编译型语言。

还不太清楚这两种语言的同学可以看看下面的例子:

我们把一个程序的运行理解为听一个人演讲,听众是计算机,演讲人是程序员。他们使用不同的语言,让计算机直接这么听演讲,它肯定是听不懂的,于是我们有两个方案:

1、找人同步翻译

我们找翻译能力超强的人作为翻译官。每当我们说完一句话,翻译官立刻跟听演讲的计算机说“刚才他那句话的意思是………………”。

2、预先翻译好讲话稿

我们的演讲稿必须事先写好,然后让翻译官将我们写好的演讲稿翻译成指定的语言。等到真正演讲大会的时候,随便找个口语好的人读一下翻译后的稿子就可以了。


这两个方案分别就是解释型语言和编译型语言了。前者每读一行代码执行一行代码,后者需要有一个编译的过程,将我们的代码编译成计算机语言再执行。

JavaScript是一种解释型语言,解释型语言不需要编译也能立刻执行代码,非常适合用于变动性大的场景,比如浏览器,我们可以在任意一个时间将head中添加一个新的js引用,由于是解释型语言,浏览器能够立刻解释这段脚本并执行。

一般来说,从运行效率上讲,编译型语言是非常有优势的,就像已经把文章翻译好了一样,只需要不动脑子地去读就行了。

但是从灵活性上讲,解释型语言有着编译型语言无法超越的优势,只要有一个解析器,不需要任何翻译工作,就可以随时随地的执行任何语句。

面向对象

JavaScript在设计之初就是一种面向对象的语言,虽然我们在日常的开发中很少能体验到这一点。面向对象语言往往有个特征就是需要new一个实例。而JavaScript也确实如此:

  1. var dNow = new Date();

  2. var obj = new Object();

面向对象拥有三大特征

  1. 封装

  2. 继承

  3. 多态

JavaScript作为面向对象的语言,也实现了这三大特征,在本课程的其它章节中,会对它们进行逐一介绍。

基于原型

JavaScript是一款基于原型模式的面向对象语言。

我们可以把原型理解为是一个使用说明书,每一个类型都会有一个对应的使用说明书,凡是使用说明上规定的成员,都是可以使用的。

比如电视器的说明书上规定了开机、关机、换台等行为,那么每一台电视机都会具备这些功能。

并且我们还可以通过JavaScript代码为指定的类型的使用说明添加新的成员。

原型是JavaScript面向对象开发中最重要的一个概念。 关于原型的详细说明也会在本课程的其它章节中出现。

原始对象

我们都知道面向对象中最重要的环节是封装。JavaScript提供了定义一个原始对象的方法,详细代码请见右侧示例:

示例中我们发现,通过构建一个Object实例,我们可以为该实例手动添加任何成员,可以是字符、数字、布尔甚至于一个方法,定义的方式,即可以用实例名.成员名 = 内容,也可以使用实例名["成员名"] = 内容。

  1. worker.isWorking = false;        //通过明确的属性名添加成员

  2. var str = "phone";

  3. worker[str] = 13800000000;    //通过不明确的属性名添加成员(str可变,因此不明确)

  4. var phone = worker.phone;    //通过不明确添加的成员,可以进行明确的访问;也可以通过不明确的方式访问明确的成员。

  5. var name = worker["name"];

从上面的代码我们可以发现,明确访问成员和不明确访问成员,二者的效果是一样。


另外,JavaScript也提供了更快捷的定义一个原始对象的方法:

  1. var worker = {

  2. name : "John",

  3. age : 30,

  4. isWorking : false,

  5. startWork : function(){

  6. if(!this.isWorking){

  7. this.isWorking = true;

  8. }

  9. }

  10. };

通过上面的方法,我们可以定义一个对象,将对象上的属性定义后便完成了封装的工作。之后,我们只需要调用对象上的成员,就可以相应的操作了。

javascript面向对象编程笔记的更多相关文章

  1. javascript面向对象编程笔记(基本数据类型,数组,循环及条件表达式)

    javascript面向对象编程指南 最近在看这本书,以下是我的笔记,仅供参考. 第二章 基本数据类型.数组.循环及条件表达式 2.1 变量 区分大小写 2.3 基本数据类型 数字:包括浮点数与整数 ...

  2. javascript面向对象编程笔记(函数之闭包)

    3 函数 3.5 闭包(closures) 3.5.1 作用域链 与很多程序设计语言不同,javascript不存在大括号级的作用域,但它有函数作用域,即在函数内定义的变量在函数外是不可见的.但如果该 ...

  3. javascript面向对象编程笔记(函数)

    第三章 函数 3.1 什么是函数 一般来说,函数声明通常由以下几部分组成: function子句 函数名称 函数所需参数 函数体 return子句.如果某个函数没有显示的返回值,默认它的返回值为und ...

  4. 《JavaScript面向对象编程指南(第2版)》读书笔记(一)

    目录 一.对象 1.1 获取属性值的方式 1.2 获取动态生成的属性的值 二.数组 2.1 检测是否为数组 2.2 增加数组长度导致未赋值的位置为undefined 2.3 用闭包实现简易迭代器 三. ...

  5. 《JavaScript面向对象编程指南(第2版)》读书笔记(二)

    <JavaScript面向对象编程指南(第2版)>读书笔记(一) <JavaScript面向对象编程指南(第2版)>读书笔记(二) 目录 一.基本类型 1.1 字符串 1.2 ...

  6. 《JavaScript面向对象编程指南》读书笔记②

    概述 <JavaScript面向对象编程指南>读书笔记① 这里只记录一下我看JavaScript面向对象编程指南记录下的一些东西.那些简单的知识我没有记录,我只记录几个容易遗漏的或者精彩的 ...

  7. JavaScript面向对象编程学习笔记

    1  Javascript 面向对象编程 所谓"构造函数",其实就是一个普通函数,但是内部使用了this变量.对构造函数使用new运算符,就能生成实例,并且this变量会绑定在实例 ...

  8. 《JavaScript面向对象编程指南》读书笔记①

    概述 JavaScript快忘完了,想看一本专业书拾遗,所以看了这本<JavaScript面向对象编程指南>. 个人觉得这本书讲的很透彻很易懂,一些原来有疑惑的地方在这本书里面豁然开朗,看 ...

  9. Javascript 面向对象编程(一):封装 by 阮一峰

    <Javascript高级程序设计(第二版)>(Professional JavaScript for Web Developers, 2nd Edition) 它们都是非常优秀的Java ...

随机推荐

  1. sqlserver-4064

    早上忘记了SQLServer的sa帐户密码,在网上搜索才弄清楚了解决办法:1.在SQLServer企业管理器中输入以下命令:ALTER LOGIN sa ENABLE GO ALTER LOGIN s ...

  2. oracle多表连接查询竟然还有这种操作

    仔细观察上面几个图,比较下 oracle数据库中的+操作符竟然可以替换left join 和right join sql server暂时没用到过

  3. spring boot 登录注册 demo (四) -- 体验小结

    之前没有折腾过Spring,直接上来怼Spring Boot异常痛苦,参考着官网的guide(https://spring.io/guides)写了几个demo: spring boot 跑起来确是方 ...

  4. SVG交互动画制作

    前面我们已经说过了要怎样制作CSS3动画,但是SVG动画一直都没有时间研究过,正好趁现在有一点时间静下心来研究一下. 一般来说,常见前端动画实现方案分为三种,CSS3动画,HTML动画(SVG动画), ...

  5. sysctl -p 报错问题的解决方法

    最近执行sysctl -p 命令时一直报错,类似这种格式: error: permission denied on key...... 经过网上搜索, 原来这些问题都是因为openvz模版的问题,要进 ...

  6. redis集群搭建及注意事项

    上一篇:redis的安装及注意事项 这里,在一个Linux虚拟机上搭建6个节点的redis伪集群,思路很简单,一台虚拟机上开启6个redis实例,每个redis实例有自己的端口.这样的话,相当于模拟出 ...

  7. Java基础---IO(二)--File类、Properties类、打印流、序列流(合并流)

    第一讲     File类 一.概述 1.File类:文件和目录路径名的抽象表现形式 2.特点: 1)用来将文件或文件夹封装成对象 2)方便于对文件与文件夹的属性信息进行操作 3)File类的实例是不 ...

  8. Selenium 学习笔记(一)

    selenium 学习整理 初学者,如果有不当得地方请指出,非常感谢. 准备事项: 1. Python 安装包 安装Python,并勾选添加环境变量. 安装完成后,打开dos窗口,输入python,看 ...

  9. 分享一个 jmeter ant的build.xml

    <?xml version="1.0" encoding="UTF-8"?> <project name="ant-jmeter-t ...

  10. java使用字节流和字符流实现文件复制

    大家在Java开发中都会遇到文件复制的文件,众所周知,需要通过文件输入输出流实现. 那究竟该怎么做那,话不多说,直接上代码: 一,使用字节流复制文件 public class FileByteCopy ...