本博客目标:- 理解面向对象开发思想 - 掌握 JavaScript 面向对象开发相关模式 - 掌握在 JavaScript 中使用正则表达式
基本概念复习
JavaScript 是什么
-
解析执行:轻量级解释型的,或是 JIT 编译型的程序设计语言
-
语言特点:动态,头等函数 (First-class Function)
-
又称函数是 JavaScript 中的一等公民
-
-
执行环境:在宿主环境(host environment)下运行,浏览器是最常见的 JavaScript 宿主环境
-
但是在很多非浏览器环境中也使用 JavaScript ,例如 node.js
-
-
编程范式:基于原型、多范式的动态脚本语言,并且支持面向对象、命令式和声明式(如:函数式编程)编程风格
JavaScript 与浏览器的关系
JavaScript 的组成
组成部分 | 说明 |
---|---|
Ecmascript | 描述了该语言的语法和基本对象 |
DOM | 描述了处理网页内容的方法和接口 |
BOM | 描述了与浏览器进行交互的方法和接口 |
JavaScript 可以做什么
Any application that can be written in JavaScript, will eventually be written in JavaScript. 凡是能用 JavaScript 写出来的,最终都会用 JavaScript 写出来
JavaScript 发展历史
-
JavaScript 的诞生
-
JavaScript 与 Ecmascript 的关系
-
JavaScript 与 Java 的关系
-
JavaScript 的版本
-
JavaScript 周边大事记
-
语法
-
区分大小写
-
标识符
-
注释
-
严格模式
-
语句
-
-
关键字和保留字
-
变量
-
数据类型
-
typeof 操作符
-
Undefined
-
Null
-
Boolean
-
Number
-
String
-
Object
-
-
操作符
-
流程控制语句
-
函数
JavaScript 中的数据类型
JavaScript 有 5 种简单数据类型:Undefined、Null、Boolean、Number、String
和 1 种复杂数据类型 Object
。
基本类型(值类型)
-
Undefined
-
Null
-
Boolean
-
Number
-
String
复杂类型(引用类型)
-
Object
-
Array
-
Date
-
RegExp
-
Function
-
基本包装类型
-
Boolean
-
Number
-
String
-
-
单体内置对象
-
Global
-
Math
-
类型检测
-
typeof
-
instanceof
-
Object.prototype.toString.call()
值类型和引用类型在内存中的存储方式(画图说明)
-
值类型按值存储
-
引用类型按引用存储
值类型复制和引用类型复制(画图说明)
-
值类型按值复制
-
引用类型按引用复制
值类型和引用类型参数传递(画图说明)
-
值类型按值传递
-
引用类型按引用传递
值类型与引用类型的差别
-
基本类型在内存中占据固定大小的空间,因此被保存在栈内存中
-
从一个变量向另一个变量复制基本类型的值,复制的是值的副本
-
引用类型的值是对象,保存在堆内存
-
包含引用类型值的变量实际上包含的并不是对象本身,而是一个指向该对象的指针
-
从一个变量向另一个变量复制引用类型的值的时候,复制是引用指针,因此两个变量最终都指向同一个对象
小结
-
类型检测方式
-
值类型和引用类型的存储方式
-
值类型复制和引用类型复制
-
方法参数中 值类型数据传递 和 引用类型数据传递
JavaScript 执行过程
JavaScript 运行分为两个阶段:
-
预解析
-
全局预解析(所有变量和函数声明都会提前;同名的函数和变量函数的优先级高)
-
函数内部预解析(所有的变量、函数和形参都会参与预解析)
-
函数
-
形参
-
普通变量
-
-
-
执行
先预解析全局作用域,然后执行全局作用域中的代码,在执行全局代码的过程中遇到函数调用就会先进行函数预解析,然后再执行函数内代码。
JavaScript 面向对象编程
面向对象介绍
什么是对象
Everything is object (万物皆对象)
对象到底是什么,我们可以从两次层次来理解。
(1) 对象是单个事物的抽象。
一本书、一辆汽车、一个人都可以是对象,一个数据库、一张网页、一个与远程服务器的连接也可以是对象。当实物被抽象成对象,实物之间的关系就变成了对象之间的关系,从而就可以模拟现实情况,针对对象进行编程。
(2) 对象是一个容器,封装了属性(property)和方法(method)。
属性是对象的状态,方法是对象的行为(完成某种任务)。比如,我们可以把动物抽象为animal对象,使用“属性”记录具体是那一种动物,使用“方法”表示动物的某种行为(奔跑、捕猎、休息等等)。
在实际开发中,对象是一个抽象的概念,可以将其简单理解为:数据集或功能集。
ECMAScript-262 把对象定义为:无序属性的集合,其属性可以包含基本值、对象或者函数。严格来讲,这就相当于说对象是一组没有特定顺序的值。对象的每个属性或方法都有一个名字,而每个名字都映射到一个值。
<p class="tip"> 提示:每个对象都是基于一个引用类型创建的,这些类型可以是系统内置的原生类型,也可以是开发人员自定义的类型。</p>
什么是面向对象
面向对象不是新的东西,它只是过程式代码的一种高度封装,目的在于提高代码的开发效率和可维护性。
面向对象编程 —— Object Oriented Programming,简称 OOP ,是一种编程开发思想。它将真实世界各种复杂的关系,抽象为一个个对象,然后由对象之间的分工与合作,完成对真实世界的模拟。
在面向对象程序开发思想中,每一个对象都是功能中心,具有明确分工,可以完成接受信息、处理数据、发出信息等任务。因此,面向对象编程具有灵活、代码可复用、高度模块化等特点,容易维护和开发,比起由一系列函数或指令组成的传统的过程式编程(procedural programming),更适合多人合作的大型软件项目。
面向对象与面向过程:
-
面向过程就是亲力亲为,事无巨细,面面俱到,步步紧跟,有条不紊
-
面向对象就是找一个对象,指挥得结果
-
面向对象将执行者转变成指挥者
-
面向对象不是面向过程的替代,而是面向过程的封装
面向对象的特性:
-
封装性
-
继承性
-
[多态性]
扩展阅读:
程序中面向对象的基本体现
在 JavaScript 中,所有数据类型都可以视为对象,当然也可以自定义对象。自定义的对象数据类型就是面向对象中的类( Class )的概念。
我们以一个例子来说明面向过程和面向对象在程序流程上的不同之处。
假设我们要处理学生的成绩表,为了表示一个学生的成绩,面向过程的程序可以用一个对象表示:
var std1 = { name: 'Michael', score: 98 } var std2 = { name: 'Bob', score: 81 }
而处理学生成绩可以通过函数实现,比如打印学生的成绩:
function printScore (student) { console.log('姓名:' + student.name + ' ' + '成绩:' + student.score) }
如果采用面向对象的程序设计思想,我们首选思考的不是程序的执行流程,而是 Student
这种数据类型应该被视为一个对象,这个对象拥有 name
和 score
这两个属性(Property)。如果要打印一个学生的成绩,首先必须创建出这个学生对应的对象,然后,给对象发一个 printScore
消息,让对象自己把自己的数据打印出来。
抽象数据行为模板(Class):
function Student (name, score) { this.name = name this.score = score } Student.prototype.printScore = function () { console.log('姓名:' + this.name + ' ' + '成绩:' + this.score) }
根据模板创建具体实例对象(Instance):
var std1 = new Student('Michael', 98) var std2 = new Student('Bob', 81)
实例对象具有自己的具体行为(给对象发消息):
std1.printScore() // => 姓名:Michael 成绩:98 std2.printScore() // => 姓名:Bob 成绩 81
面向对象的设计思想是从自然界中来的,因为在自然界中,类(Class)和实例(Instance)的概念是很自然的。Class 是一种抽象概念,比如我们定义的 Class——Student ,是指学生这个概念,而实例(Instance)则是一个个具体的 Student ,比如, Michael 和 Bob 是两个具体的 Student 。
所以,面向对象的设计思想是:
-
抽象出 Class
-
根据 Class 创建 Instance
-
指挥 Instance 得结果
面向对象的抽象程度又比函数要高,因为一个 Class 既包含数据,又包含操作数据的方法。
创建对象
简单方式
我们可以直接通过 new Object()
创建:
var person = new Object() person.name = 'Jack' person.age = 18 person.sayName = function () { console.log(this.name) }
每次创建通过 new Object()
比较麻烦,所以可以通过它的简写形式对象字面量来创建:
var person = { name: 'Jack', age: 18, sayName: function () { console.log(this.name) } }
对于上面的写法固然没有问题,但是假如我们要生成两个 person
实例对象呢?
var person1 = { name: 'Jack', age: 18, sayName: function () { console.log(this.name) } } var person2 = { name: 'Mike', age: 16, sayName: fun