js入门(9)面向对象
面向对象
认识对象
认识对象
- 对象是"键值对"的集合,表示属性的值的映射关系
![]()
对象的语法

属性是否加""
- 如果不符合js的命名规则就要加,否则不加
属性的访问
- xxx.属性名;
- 如果属性名是不符合命名规则,必须用方括号的写法来访问
xxx['shuxin-ming']; - 如果属性名以变量形式存储,则必须使用方括号形式
![]()
![]()
属性的更改

属性的创建

属性的删除

对象的方法
- 如果某个属性值是函数,则被称为对象的方法
![]()
方法的调用

方法和函数的区别

对象的遍历
- 和遍历数组类似,对象也可以被遍历,遍历对象需要使用for...in...循环
- 使用for...in...循环可以遍历对象的每个键
![]()
对象的深浅克隆

对象是引用类型值

对象的浅克隆


- 对象中的c还是同一个数组
对象的深克隆
<html lang="en">
<head>
<meta charset="UTF-8">
<title>面向对象 深克隆</title>
</head>
<body>
<script>
var obg1={
a:1,
b:2,
c:[1,2,{
q:1,
w:2,
c:[3,4,5]
}]
}
function deepclone(e) {
//判断是什么
if (Array.isArray(e)){
//创建一个结果数组,传入数值
var result=[];
for (var i=0;i<e.length;i++){
result.push(deepclone(e[i]));
}
}else if(typeof e=='object'){
//创建一个结果空对象
var result={};
for (var k in e){
result[k]=deepclone(e[k]);
}
}else {
var result=e;
}
return result;
}
var obg2=deepclone(obg1);
console.log(obg2);
</script>
</body>
</html>
认识上下文
- 函数中可以使用this关键字,它表示函数的上下文
+与中文中的这类似,具体指代什么,需要通过上下文来判断
![]()
![]()
函数的上下文是由调用方式决定的

上下文规则1
- 对象.方法(),函数上下文是这个打点的对象
![]()
![]()
![]()
![]()
上下文规则2
- 圆括号直接调用函数,则函数的上下文是window对象
![]()
![]()
上下文规则3
- 数组[下标](),上下文是这个数组(类数组对象)
![]()
类数组对象


上下文规则4
iife中的函数,上下文是window对象
(function(){
})();

上下文规则5
- 使用定时器延时器,上下文是window对象
![]()
![]()
上下文规则6
- 事件处理的上下文是绑定事件的DOM元素
xxx.onclick=function(){}; - 小案例 点击哪个盒子,哪个就变红,要求使用同一个事件处理函数
![]()
- 小案例 点击哪个盒子,哪个盒子2秒后变红
![]()
call和apply
- 可以指定函数的上下文
![]()
![]()
![]()
- 区别
![]()
![]()
答案:77
![]()
构造函数
用new函数的四步走
用new操作符调用函数
- new 函数()
- js规定,使用new操作符调用函数会有4步:
- 函数体会自动创建出一个空白对象
- 函数的上下文this会指向这个对象
- 函数体内的语句会执行
- 函数会自动返回上下文对象,即使函数没有return语句
![]()
构造函数

- this指的是之后会创建的空白对象,并不是函数本身
![]()
类和实例

- 这个people是可以看作类,js中其实是没有类的
原型和原型链
protorype和原型链查找
- 任何函数都有prototype属性,prototy是英语"原型"的意思
- prototype属性值是个对象,它默认拥有constructor属性指回函数
![]()
- 对于普通函数prototype属性没有任何用处,但对于构造函数prototype属性非常有用
- 构造函数的prototype属性是实例的原型
![]()
原型链查找
- js规定:实例可以打点访问它的原型的属性和方法,这被称为 原型链查找
![]()
![]()
![]()
- 实例可以打点调用原型链身上的属性,如果本身就有就不用从原型链上面查找
hasOwnProperty

in

在prototype上添加方法
- 将方法写在对象身上,会造成空间浪费
![]()
- 解决方法:将方法写到prototype上面
![]()
- 通过打点来写
![]()
原型链的终点

关于数组的原型链

继承



- 继承描述了两个类之间的is a kind of 关系,比如学生是一种人
- people是父类,student是子类
- 子类丰富了父类,让类更具体,更详细
js中如何实现继承
- 继承的关键在于,子类必须拥有父类的全部属性和方法,同时子类还应该能定义自己特有的属性和方法
- 使用js原型链来实现继承,是普遍的做法
![]()
<script>
//父类
function People(name,age,sex) {
this.name=name;
this.age=age;
this.sex=sex;
}
People.prototype.sleep=function () {
console.log(this.name +"开始睡觉zzzz")
}
//子类
function Student(name,age,sex,school,studentNamber) {
this.name=name;
this.age=age;
this.sex=sex;
this.school=school;
this.studentNamber=studentNamber;
}
//关键语句,实现继承
Student.prototype=new People();
Student.prototype.study=function () {
console.log(this.name+"正在学习!")
}
//重写,复写,父类的方法
Student.prototype.sleep=function () {
console.log(this.name+"准备开始睡觉了,睡觉真爽");
}
//实例化
var hmm=new Student("韩梅梅",12,"女","q",23);
hmm.study();
hmm.sleep();
</script>
上升到面向对象
- 面向对象:定义不同的类,让类的实例工作
- 优点:代码更清晰,结构更严密,代码更健壮利于维护
- 应用场合:封装和复用性的场合
上升到面向对象小案例1
- 红绿灯案例
![]()
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>面向对象红绿灯案例</title>
<style>
img{
width: 50px;
}
</style>
</head>
<body>
<div id="box"></div>
<script>
//定义红绿灯类
function Honglvdeng() {
this.color=1;
//初始化颜色
this.init();
//调用自己的初始化方法;
this.bindEvent();
//绑定监听
}
//初始化方法
Honglvdeng.prototype.init=function () {
//创建自己的dom,src属性,绑定到盒子上面
this.dom=document.createElement('img');
this.dom.src = 'images/'+ this.color +'.jpg';
box.appendChild(this.dom);
//这个box如何得到,写在实例之前即可
}
//绑定监听
Honglvdeng.prototype.bindEvent=function () {
//备份上下文,这里的this指的是js实例
var self=this;
//当dom被点击时,调用自己的changecolor方法
this.dom.onclick=function () {
self.changecolor();
}
}
//改变颜色方法
Honglvdeng.prototype.changecolor=function () {
this.color++;
if (this.color==4){
this.color=1;
}
//同时还要改变src的属性值
this.dom.src = 'images/'+ this.color +'.jpg';
}
//得到盒子
var box=document.getElementById('box');
//实例化100个
var hld=100;
while (hld--){
new Honglvdeng();
}
</script>
</body>
</html>
上升到面向对象小案例2
- 炫彩小球
![]()
![]()







































浙公网安备 33010602011771号