1、含义:编程思想或者是一种开发方式
2、我们之前的开发方式:面向过程开发
=>面向过程:就是一步一步的实现,每一个步骤联系很密切,需要我们亲力亲为
3、面向对象:就是找一个对象,帮我实现一个轮播图
4、实例:吃面
=>面向过程:和面 擀面 切面 煮面 拌面 吃面
=>面向对象:找到一家面馆 点面 吃面
5、面向对象和面向过程的关系
=>面向对象是对面向过程的高度封装
6、如何出现这样的一个对象
=>只要我们有了这样的一个对象就可以了
=>能出现一个创建对象的‘机器’也可以
=>创建出现的对象要相似但是不一样
=>能批量创建
=>字面量的方式:可以创建对象,可以做到相似但是不一样,但是做不到批量创建
let obj = {}
=>内置构造函数:可以创建对象,可以做到相似但是不一样,但是做不到批量创建
let obj = new Object()
=>工厂函数的方式:可以实现批量创建对象
- function createObj(name, age, gender) {
- // 手动创建一个对象
- var obj = new Object()
- // 手动的向对象中添加成员
- obj.name = name
- obj.age = age
- obj.gender = gender
- // 手动返回一个对象
- return obj
- }
- // 2. 使用这个工厂函数创建对象
- var o1 = createObj('明明', 20, '男')
- var o2 = createObj('红红', 18, '女')
- console.log(o1, o2);
=>使用自定义构造函数创建对象:自定义就是自己起名字
->构造函数:就是和new关键字连用的函数,这样的函数称之为构造函数
->内置构造函数:对象、数组、时间、正则、字符串,内置构造都是JS中自带的
->创建步骤:
- // 1. 先创造一个构造函数
- function Person(name, gender) {
- this.age = 18
- this.name = name
- this.gender = gender
- }
-
- // 2. 使用构造函数创建对象
- var p1 = new Person('Jack', 'man')
- var p2 = new Person('Rose', 'woman')
=>new 关键字都做了什么
=>一定要和new关键字连用
=>首字母要大写,为了区分普通函数还是构造函数的
=>构造函数体内不要写return
->如果写了return返回的是基本数据类型,写了白写
->如果写了return返回的是复杂数据类型,构造函数失效
// 1. 先创造一个构造函数
function Person(name, gender) {
this.age = 18
this.name = name
this.gender = gender
}// 2. 使用构造函数创建对象
var p1 = new Person('Jack', 'man')
var p2 = new Person('Rose', 'woman')
=>this指向自动创建出来的那个空对象
=>会自动返回这个对象
=>自动返回的这个对象给了谁?
->给了前面的那个变量,那个变量就是一个对象,也就说明,这个对象就是this
=>实例的含义:就是前面的那个变量就是实例
=>实例化的含义:创建实例的过程就叫做实例化
- function Person() {
- console.log(this)
- }
- var o1 = new Person() // 本次调用的时候,this => o1
- var o2 = new Person() // 本次调用的时候,this => o2
1、属性和方法的概念
=>属性:我们把构造函数中,值不是函数的叫做属性
=>方法:我们把构造函数中,值是函数的叫做方法
2、把方法定义在函数构造体内真的合理吗?(下面有解决办法)
=>不合理。因为每实例化一个对象,就会开辟一个新的空间,但是同样的代码需要执行多次,就会造成内存的浪费
1、原型对象:是构造函数(函数)的一个属性,这个属性是对象数据类型,叫做prototype
注意:(1)每一个函数天生自带一个成员,叫做 prototype,是一个对象空间,也就是说prototype本身就是一个对象
(2) 在函数的 prototype 里面存储的内容,不是给函数使用的,是给函数的每一个实例化对象使用的
2、对象原型(原型):是对象身上的一个属性,这个属性是一个非标准属性,不能用来进行赋值的,作用就是提供一个指向,指向所属构造函数的原型对象,叫做 __proto__
- function Person() {}
-
- var p1 = new Person()
-
- console.log(p1.__proto__ === Person.prototype) // true
3、对象的访问:
=>当实例想要访问一个成员(属性 方法)的时候,首先在自己身上就查找,如果有拿来用,停止查找
=>如果没有就去所属构造函数的原型对象上查找,如果有就拿来使用,停止查找
=>如果没有就沿着_proto_去到所属构造函数的原型对象上查找
=>依次类推,直到找到顶级原型,如果有就拿来使用
=>如果没有就返回undefined
4、解决不合理的地方
=>我们把属性定义在构造函数体内
=>方法我们写在原型对象上,减少内存的消耗
- function Person() {}
-
- Person.prototype.sayHi = function () {
- console.log('hello')
- }
-
- var p1 = new Person()
- var p2 = new Person()
-
- console.log(p1.sayHi === p2.sayHi)
1、构造函数体内的 this
=>因为和 new 关键字连用
=>this 指向 当前实例
2、原型上的方法体内的 this
=>因为原型上的方法是被当前实例调用的
=>this 指向 当前实例
面向过程的优缺点
=>优点:性能比面向对象高,步骤联系密切
=>缺点:不好维护,不宜多次使用和扩展
面向对象的优缺点
=>优点:易维护、可复用、可扩展灵活性高
=>缺点:性能没有面向过程高
面向对象的三大特性
=>封装性
=>继承性
=>多态性
1、含义:在 ES6 的语法标准中, 管构造函数不叫做构造函数了, 叫做 类
2、语法:
-
- class 类名 {
-
- constructor () {
- // 书写属性
- }
- 书写原型上的方法
- 方法名 () {}
- }
- // ES6 类的语法
- class Person {
- // 等价于 ES5 的构造函数体
- constructor(name) {
- this.name = name
- }
-
- // 直接书写原型上的方法
- sayHi() { console.log('你好 世界') }
-
- play() { console.log('play game') }
- }
-
- const p = new Person('Jack')
- console.log(p)
- p.sayHi()
- p.play()
- // 此时 Person 已经不是函数了, 是一个 类
- // 不能当做函数来调用
- Person('Rose')
1、在JS中,一切数据类型都可以看做是对象的数据类型
2、对象是一个纯粹的对象数据类型
3、函数/数组都有有两层空间,函数/数组空间和对象空间