Ashun's 技術駅 Ashun's 技術駅
首页
  • 前端文章

    • JavaScript
  • 学习笔记

    • 《JavaScript教程》
    • 《JavaScript高级程序设计》
    • 《ES6 教程》
    • 《Vue》
    • 《React》
    • 《TypeScript 从零实现 axios》
    • 《Git》
    • TypeScript
    • JS设计模式总结
  • HTML
  • CSS
  • Vue
  • 现代web布局
  • React
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 技术资源
  • 第一阶段

    • HTML
  • 第二阶段

    • JavaScript
  • 第三阶段

    • Vue
  • 第四阶段

    • 实战项目
  • 每周测试

    • 每周
  • 其他

    • Vue引入UI框架
    • Web前端面试
    • Vue3-resource
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 福利资源
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Ashun

前端界的小学生
首页
  • 前端文章

    • JavaScript
  • 学习笔记

    • 《JavaScript教程》
    • 《JavaScript高级程序设计》
    • 《ES6 教程》
    • 《Vue》
    • 《React》
    • 《TypeScript 从零实现 axios》
    • 《Git》
    • TypeScript
    • JS设计模式总结
  • HTML
  • CSS
  • Vue
  • 现代web布局
  • React
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 技术资源
  • 第一阶段

    • HTML
  • 第二阶段

    • JavaScript
  • 第三阶段

    • Vue
  • 第四阶段

    • 实战项目
  • 每周测试

    • 每周
  • 其他

    • Vue引入UI框架
    • Web前端面试
    • Vue3-resource
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 福利资源
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 01变量
  • 02常量
  • 03js数据类型
  • 04运算、判断、条件
  • 05数字类型
  • 06字符串
  • 07布尔值
  • 08空值
  • 09未定义
  • 10唯一值
  • 11对象
  • 13数组
  • 14函数
  • 15日期对象
  • 16正则表达式
  • 17异常错误对象
  • 18BOM 浏览器对象模型
  • 19DOM文档对象模型
  • 20json
  • 21Ajax
  • 22jQuery
  • 23函数进阶
  • 24面向对象
    • 一、面向对象的优势和特性
    • 二、类的创建方式
      • 1、工厂模式,生产出来的所有实例化对象都是一样
      • 2、实例化模式,复用性差,没有共性
      • 3、基于原型的混合模式,同时具有共性和特性
    • 三、实例化对象、构造函数、原型
    • 四、原型链
    • 五、对象的方法
    • 六、堆和栈
      • 1)浅克隆和深克隆
      • 浅克隆,只克隆对象的第一层属性
      • 深克隆,克隆对象的所有层级的属性
      • 2)类的继承
  • 《javascript(es5)》
ashun
2022-02-14
目录

24面向对象

# 面向对象

[info] 面向对象(oop)

是一种软件开发方法,一种编程范式。面向对象是相对于面向过程来讲的,面向对象方法,把相关的数据和方法组织为一个整体来看待,从更高的层次来进行系统建模,更贴近事物的自然运行模式。

# 一、面向对象的优势和特性

//优势
1、方便
2、复用性高
3、高内聚低耦合
4、代码冗余低

//特点
1、封装。也就是把客观事物封装成抽象的类。
2、继承。它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。
3、多态。允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。
1
2
3
4
5
6
7
8
9
10

[!NOTE]

%accordion% 历史解说🚀 %accordion%

c   面向过程      过程,难以理解
c++ 面向对象      对象,容易理解,维护性高

ecma    es6 (2015)

JavaScript:
    js  不是面向对象语言,面向原型语言   prototype
    es6 面向对象                        class
1
2
3
4
5
6
7
8

%/accordion%

%accordion% 三种法🚀 %accordion%

// 1、函数
function person(){//函数

}
person()

// 2、构造函数、类
function Person(){//以前:构造函数  //现在:类

}
new Person()

// 3、类、构造函数(es6)
class Person{//类
    constructor(){//构造函数

    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

简单定义一个函数

// function person() {//函数
//     this.name = "小明"// 给window加
// }

function person() {//以前:构造函数    //现在:类
    this.name = "小明"
}
var p = new person()//对象
console.log(p); //person {name: "小明"}
1
2
3
4
5
6
7
8
9

%/accordion%

# 二、类的创建方式

# 1、工厂模式,生产出来的所有实例化对象都是一样

function Car(){
  this.name = "奔驰"
  this.color = "black"
}

let a = new Car()
let b = new Car()
console.log(a)
console.log(b)
1
2
3
4
5
6
7
8
9

%accordion% 克隆工厂模式🚀 %accordion%

function person() {//构造函数/类
    this.name = "小明"
}
var p1 = new person()//对象
console.log(p1); //person {name: "小明"}

var p2 = new person()//对象
console.log(p2); //person {name: "小明"}
1
2
3
4
5
6
7
8

%/accordion%

# 2、实例化模式,复用性差,没有共性

function Car(name,color){//实例化模式,复用性差
  this.name = name
  this.color = color
}

let a = new Car("奔驰","黑色")
let b = new Car("宝马","蓝色")
console.log(a)
console.log(b)
1
2
3
4
5
6
7
8
9

%accordion% 实例化模式🚀 %accordion%

function person(name) {//构造函数/类
    this.name = name
}
var p1 = new person("小明")//对象
console.log(p1); //person {name: "小明"}
var p2 = new person("小红")//对象
console.log(p2); //person {name: "小红"}
1
2
3
4
5
6
7

%/accordion%

# 3、基于原型的混合模式,同时具有共性和特性

function Car(name){
  this.name = name
}

Car.prototype.color = "黑色"

let a = new Car("奔驰")
let b = new Car("宝马")
console.log(a)
console.log(b)
1
2
3
4
5
6
7
8
9
10

%accordion% 混合模式,同时具有共性和特性🚀 %accordion%

function person(name, age, sex) {//构造函数/类
    this.name = name
    this.age = age
    this.sex = sex
}

person.prototype.country = "中国"//共性(原型去添加)

var p1 = new person("小明", 18, "男")//特性
console.log(p1); //person {name: "小明", age: 18, sex: "男"}

var p2 = new person("小红", 23, "女")//特性
console.log(p2); //person {name: "小红", age: 18, sex: "男"}
1
2
3
4
5
6
7
8
9
10
11
12
13

这种仅参考

function person(name, age, sex, country) {//构造函数/类
    this.name = name
    this.age = age
    this.sex = sex
    this.country = country
}
var p1 = new person("小明", 18, "男", "中国")//对象
console.log(p1); //person {name: "小明", age: 18, sex: "男", country: "中国"}

var p2 = new person("小红", 23, "女", "中国")//对象
console.log(p2); //person {name: "小红", age: 18, sex: "男", country: "中国"}
1
2
3
4
5
6
7
8
9
10
11

%/accordion%

# 三、实例化对象、构造函数、原型

[warning] For warning

所有引用类型都有一个__proto__(隐式原型)属性,属性值是一个普通的对象。

所有函数都有一个__prototype__(原型)属性,属性值是一个普通的对象。

所有引用类型的__proto__属性指向它构造函数的__prototype__。



function Car(){//构造函数
  this.name = "奔驰"
  this.color = "black"
}

let a = new Car()
console.log(a)//实例化对象
console.log(a.__proto__)//实例化对象a的原型
console.log(Car.prototype)//实例化对象a的原型
console.log(a.__proto__ === Car.prototype)//true
1
2
3
4
5
6
7
8
9
10
11
12

# 四、原型链

[!NOTE]

当访问一个对象的某个属性时,会先在这个对象本身属性上查找,如果没有找到,则会去它的__proto__隐式原型上查找,即它的构造函数的__prototype__,如果还没有找到就会再在构造函数的__prototype__的__proto__中查找,这样一层一层向上查找就会形成一个链式结构,我们称为原型链。

function Car(){//构造函数
  this.name = "奔驰"
  this.color = "black"
}

let a = new Car()
console.log(a.__proto__)//实例化对象a的原型。即Car.prototype
console.log(a.__proto__.__proto__)//对象Object的原型。即Object.prototype
console.log(a.__proto__.__proto__.__proto__)//null
1
2
3
4
5
6
7
8
9

{% reveal text="图片块" %}

Untitled

{% endreveal %}

类\\构造函数
	1、prototype -> 访问原型
	2、__proto__ -> 指针,访问构造这个类的原型
	
原型
	1、prototype -> 访问原型
	2、__proto__ -> 指针,访问构造这个原型的原型
	3、constructor -> 访问类\\构造函数

实例化对象
	1、__proto__ -> 指针,访问构造这个实例化对象的原型
	2、constructor -> 访问类\\构造函数
1
2
3
4
5
6
7
8
9
10
11
12

[!cogs]

%accordion% 练习 %accordion%

function Person(name) {//类、构造函数
    this.name = name//实例属性
}

var p = new Person("小明")

// console.log(Person.prototype);
// console.log(Person.__proto__.constructor);//指针,指向构造这个类的原型
// console.log(Person.__proto__.__proto__);
// console.log(person.__proto__.__proto__.__proto__);//null

Person.__proto__.__proto__.constructor.prototype.eyes = 3

Person.prototype.eyes = 3
console.log(p.eyes);//3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

%/accordion%

# 五、对象的方法

//返回指定对象的原型,用来代替__proto__
Object.getPrototypeOf(obj)

//在对象自身查找属性而不到原型上查找
hasOwnProperty()

//判断一个对象是否是某个实例的原型对象
isPrototypeOf

//判断一个对象是否是一个类的实例
instanceof

//根据__proto__来创建一个新对象
Object.create()

//用于将所有可枚举属性的值从一个或多个源对象复制到目标对象
Object.assign()

//案例
function Car(name){
  this.name = name
}

Car.prototype.color = "黑色"//原型属性(共性)

let a = new Car("奔驰")

console.log(a.hasOwnProperty("name"))//true

console.log(a.__proto__.isPrototypeOf(a))//true

console.log(a instanceof Car)//true

let b = Object.create(a.__proto__)//创建一个基于原型的新对象
console.log(b)

let obj = {name:"小明"}
let obj2 = {name:"小红"}
console.log(Object.assign(obj,obj2))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

# 六、堆和栈

//堆  存储引用类型数据object(函数,数组等都是)
//栈  存储普通类型数据number,string,boolean,undefined,null
//栈是直接赋值数据,堆是赋值引用地址

//栈类型数据
var a = "123"
var b = a
b = "456"
console.log(a)//123
console.log(b)//456

//堆类型数据
var a = {"name":"小明"}
var b = a
b.name = "小红"
console.log(a)//{name: "小红"}
console.log(b)//{name: "小红"}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

%accordion% 堆和栈的区别 %accordion%

堆和栈
栈是直接赋值数据:速度快 
堆是赋值引用地址:速度慢 

堆: 粘贴         文件a(10mb)   文件b(10,mb)
栈: 粘贴快捷方式  文件a(10mb)  文件b(5kb)
1
2
3
4
5
6

直接赋值 【栈】

var a = 1
var b = a
b = 2
console.log(a); //1
console.log(b); //2
1
2
3
4
5

赋值的是引用地址,CPU地址 对象 【堆】

var a = { name: "小明" }
var b = a;
b.name = "小红"
console.log(a); //小红
console.log(b); //小红
1
2
3
4
5

%/accordion%

# 1)浅克隆和深克隆

# 浅克隆,只克隆对象的第一层属性

var obj = {name:"小明"}
var obj2 = Object.assign({},obj)
obj2.name = "小红"
console.log(obj) //{name: "小明"}
console.log(obj2) //{name: "小红"}
1
2
3
4
5

%accordion% 浅克隆——更改值另一个不受影响 %accordion%

var a = {
    name: "小明1",
    obj: {
        name: "小明2"
    }
}
var b = Object.assign({}, a)
b.obj.name = "小红"
console.log(a);
console.log(b);
1
2
3
4
5
6
7
8
9
10

image-20220101150526808

%/accordion%

# 深克隆,克隆对象的所有层级的属性

[warning] 深克隆有三种方法

1、自定义深克隆——麻烦

2、JSON.parse(JSON.stringify())——缺陷

3、jq方法 $.extend(true,{},obj)——引用函数库

[!cogs]

%accordion% 简单深克隆 %accordion%

var a = {
    name: "小明1",
    obj: {
        name: "小明2"
    }
}
var x = Object.assign({}, a)
var y = Object.assign({}, a.obj)
x.obj = y
x.obj.name = "小红2"
console.log(x);
console.log(a);
1
2
3
4
5
6
7
8
9
10
11
12

image-20220101152105013

%/accordion%

%accordion% 1、自定义深克隆 %accordion%

function deepClone(obj){
  var x = {}
  for(key in obj){
    if(typeof obj[key] === "object"){
      x[key] = deepClone(obj[key])
    }else{
      x = Object.assign(x,obj)
    }
  }
  return x
}

var b = deepClone(a)
b.obj.name = "小红2"
console.log(a)//{name: "小明1",obj: {name: '小明2'}}
console.log(b)//{name: "小明1",obj: {name: '小红2'}}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

image-20220101153459879

%/accordion%

%accordion% 2、JSON.parse(JSON.stringify()) %accordion%

工作中用得最多了

缺陷里面有——构造涵数、正则表达式 都会有问题

var a = {
    name: "小明1",
    obj: {
        name: "小明2"
    }
}
var b = JSON.parse(JSON.stringify(a))
b.obj.name = "小红"
console.log(a);
console.log(b);
1
2
3
4
5
6
7
8
9
10

image-20220101160305524

%/accordion%

%accordion% 3、jq方法 $.extend(true,{},obj) 引用函数库 %accordion%

# jquery (opens new window)

<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>

var a = {
    name: "小明1",
    obj: {
        name: "小明2"
    },
    reg: /hello/
}
var b = $.extend(true, {}, a)
b.obj.name = "小红2"
console.log(a);
console.log(b);
1
2
3
4
5
6
7
8
9
10
11
12
13

image-20220101155943685

%/accordion%

# 2)类的继承

es5

//es5
function Person(){
  this.name = "小明"
}
Person.prototype.age = 18

var p = new Person()

function Student(){
  Person.call(this)
}

Student.prototype = Person.prototype

var s = new Student()

console.log(s.age)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

es6 ——方便

class Person{
  constructor(name){
    this.name = name
  }
}

var p = new Person("小明")

class Student extends Person{
  constructor(name){
    super(name)
  }
}

var s = new Student("小红")
console.log(s)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
编辑 (opens new window)
上次更新: 2022/04/24, 13:33:34
23函数进阶

← 23函数进阶

最近更新
01
课件-react路由-V6
01-22
02
课件-国际化
01-22
03
课件-redux-toolkit
01-22
更多文章>
Theme by Vdoing | Copyright © 2019-2024 Evan Xu | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式