高阶-对象-构造函数-原型链-this指向
# 1.面向对象编程
# 1.1 面向过程与面向对象的区别
面向过程:编程注重功能过程实现
面向对象:更加注重整体把控
# 1.2 类与对象
类:是一群对象的总称,抽象的概念
人类 女朋友 男人 动物 汽车
对象:一个具体的事物,具象化
张三 红色的毛发的一个老虎 蓝色的一辆红旗H7
注意:除了内置对象之外,所有的对象都是通过类进行创建的
# 1.3 创建对象的方式
//通过实例化创建对象
let user = new Object();
//对象属性和方法
user.name = '张麻子'
user.age = 25
user.eat = function(){
console.log('我正在吃饭...')
}
//通过字面量创建对象 语法糖
let user1 = {
name:'黄四郎',
age:25,
eat:function(){
console.log('我也要吃饭...')
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
问题:如果想要创建多个对象,只能通过复制粘贴的方式进行,如何才能够批量创建对象呢
# 1.4 工厂函数
- 实现了批量创建对象
- 不能够识别不同分类的对象
function createObj(name,age,fn){
return {
name,
age,
fn
}
}
let user = createObj('张麻子',20,function(){
conosle.log('我在吃饭')
})
let user1 = createObj('黄四郎',20,function(){
conosle.log('我在吃饭')
})
let user2 = createObj('老三',20,function(){
conosle.log('我在吃饭')
})
let houzi =createObj('猴子',5,function(){
console.log('我在吃饭');
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
问题:如何在批量创建对象的同时,实现对 对象的分类呢?
# 1.5 构造函数【掌握】
- 构造函数命名规则 大驼峰
- 构造函数没有返回值
- 构造函数的属性和方法 都是挂载到this 上面
- 对象都是通过构造函数 实例化出来的 实例化关键字:new
//人类
function Prosen(name,age){
this.name = name
this.age = age
this.eat = function(){
console.log('我在正吃饭...');
}
}
let user = new Prosen('张麻子',25);
let user1 = new Prosen('黄四郎',30);
//汽车类
function Car(name,color){
this.name = name;
this.color = color;
this.run = function(){
console.log('正在以400km/小时的速度跑');
}
}
let hq = new Car('红旗H7','黑色');
let cc = new Car('长城H6','白色');
//动物类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 1.5.1 new 关键字作用
创建一个空对象
this指向这个空对象
指向this的属性和方法
将创建的对象返回 出 实例对象
问题:如果创建了一万个实例化对象,就创建了一万个独立方法,内置对象就不会出现这种情况,怎么实现?如何避免构造函数的方法过载?
# 2.原型与原型链 【掌握】
# 2.1原型概念
构造函数都有 prototype (显式原型),值是一个对象
实例对象都有
__proto__
(隐式原型),指向构造函数的prototype构造函数的显式原型(prototype)中constructor 属性 指向 构造函数自己
# 2.2 原型链
原型链查找原则:就近原则,一层一层网上找,直到找到 Object 在继续往上查找就没有了,Object就是所有的js对象的祖宗。
# 3.根据原型链概念解决方法过载问题
function Prosen(name,age){
this.name = name
this.age = age
// this.eat = function(){
// console.log('我在正吃饭...');
// }
}
// 原型方法
Prosen.prototype.eat = function(){
cosnole.log('我正在吃饭...')
}
//示例对象
let user = new Prosen('张麻子',25);
let user1 = new Prosen('黄四郎',30);
console.log(user.eat === user1.eat); //true
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 4.自己手写数组的原型方法
实现数组根据元素删除 arr.delete('张三')
//实现数组根据元素删除 arr.delete('张三') Array.prototype.delete = function(item){ console.log(this); let index = this.indexOf(item); if(index >=0){ this.splice(index,1); } } let arr = ['张麻子','黄四郎','张三','李四'] arr.delete('李四') console.log(arr);
1
2
3
4
5
6
7
8
9
10
11
12
13
# 5.this指向【熟悉】
- 在全局中的this 指向 window
- 在一般函数中的this 谁调用指向谁
- 在构造函数中的this 指向构造的实例对象
- 在对象的方法中的this 谁调用指向谁
- 在事件函数中的this 指向事件源
- 在定时器中的this 指向window
- 在箭头函数中的this 指向上一级
//全局this window
console.log(this); //window
console.log(this.location);
//一般函数
var name = '李四'
//普通函数中的this
function sum(a,b){
var name = '张三'
console.log(name);
console.log(this.name);
}
sum(1,2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
//object 中的this指向 谁调用指向谁
var name ='李四';
let obj = {
name:'张三',
age:25,
eat:function(){
console.log(this.name)
}
}
obj.eat() //张三
let fn = obj.eat;
fn() //李四
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
//事件函数中的this 指向事件源
document.querySelector('button').addEventListener('click',function(ev){
console.log(this) //<button>点我吧</button>
})
1
2
3
4
2
3
4
//定时器中的this
window.setTimeout(function(){
console.log(this)
},1000)
//箭头函数:箭头函数自己没有this 拿到上一层级的this
document.querySelector('button').addEventListener('click',function(ev){
console.log(this) //<button>点我吧</button>
let sum =(a,b)=>{
console.log(this);
return a+b;
}
sum(); //<button>点我吧</button>
})
function fn(a,b){
setTimeout(()=>{
console.log(this) //window
},1000)
}
fn(1,2)
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
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
# 6.this的借用
立即执行--调用
- 要借的对象.要借的函数.call(借给谁,参数1,参数2...)
- 要借的对象.要借的函数.apply(借给谁,[参数1,参数2])
永久借用--新的函数
- let fn = 要借的对象.要借的函数.bind(借给谁,参数1,参数2)
let user = {
name:'张三',
show:function(a,b){
console.log('我是:'+this.name);
console.log(a,b);
}
}
let user1 = {
name:'张麻子'
}
// console.log(user.show()); 张三
//立即执行--调用函数
// - 要借的对象.要借的函数.call(借给谁,参数1,参数2...)
// - 要借的对象.要借的函数.apply(借给谁,[参数1,参数2])
user.show.call(user1) //张麻子
user.show.apply(user1,[100,200]) // 我是:张麻子 100 200
//永远借用--赋值出来一个新的函数
// let fn = 要借的对象.要借的函数.bind(借给谁,参数1,参数2)
let fn = user.show.bind(user1,200,3200);
fn() //我是:张麻子 200 3200
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
编辑 (opens new window)
上次更新: 2022/05/28, 19:34:46