02-面向对象编程
1.1-面向对象编程介绍
- 本小节知识点
- 1.理解什么是面向对象编程
面向对象不是一门技术,而是一种解决问题的思维方式
面向对象的本质是对面向过程的一种封装
- 2.理解什么是对象
对象的本质是程序代码与现实世界沟通的一座桥梁。它有两种含义
- 对象:是一种数据类型(存储数据的容器),以键值对的形式存储数据
- 对象:对现实世界实物的一种抽象。
- 1.理解什么是面向对象编程
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script>
/*1.面向对象编程与面向过程编程并不是一门技术,而是一种解决问题的思路和方式
面向对象:注重的是结果
面向过程:注重的是过程
*/
//举例:做饭
//1.1 面向过程:注重的是过程
//买菜
//洗菜
//切菜
//开火热锅
//放油
//把菜放到锅里炒
//放盐,醋,酱油
//把菜装到盘子里
//1.2 面向对象:注重的是结果
//不想自己做,找一个专业的对象来解决
//地沟油一条街的厨师们
/*是不是有了面向对象就不需要面向过程了呢?,不是,面向对象其实是对面向过程的一个封装 */
/*2.理解什么是对象*/
//2.1 对象是对单个实物的抽象 --------万物皆对象
/*
一台车: 特征:品牌 价格 颜色 轮子数量 行为:加速 刹车
一个人: 特征:姓名 身高 年龄 性别 行为:吃饭 睡觉 敲代码
一条狗: 特征:品种 颜色 性别 行为:拉屎 撒尿 打招呼
*/
//2.2 对象是一个存储数据的容器 ------------键值对的形式存储数据
let student = {
name:'张三',
age:18,
eat:function ( ) {
console.log ( "大吉大利,今晚吃鸡" );
}
}
//2.3 如何寻找对象:名词提炼法
//小明在公交车上牵着一条叼着热狗的狗
</script>
</body>
</html>
1.2-面向对象编程举例01
本小节知识点:
- 1.以一个简单示例介绍面向对象编程的好处
- 2.体会面向对象思维方式与面向过程的不同之处
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
div{
height: 50px;
margin-top: 20px;
background-color: greenyellow;
}
p{
height: 50px;
margin-top: 20px;
background-color: hotpink;
}
</style>
</head>
<body>
<div></div>
<div></div>
<div></div>
<p></p>
<p></p>
<p></p>
<script>
//需求:给三个div和p标签设置边框
//一:以前做法: 面向过程
//弊端:(1)获取元素代码过长 (2)两个for循环,代码冗余 (3)不便于维护
//1.获取页面元素
// let divList = document.getElementsByTagName('div');
// let pList = document.getElementsByTagName('p');
// //2.遍历数组每一个元素,设置边框
// for(let i = 0;i<divList.length;i++){
// divList[i].style.border = '10px solid red';
// }
// for(let i = 0;i<pList.length;i++){
// pList[i].style.border = '10px solid red';
// }
//二:使用函数封装
// //好处:代码复用 弊端:函数名是全局变量,会造成全局变量污染
// let divList = tagName('div');
// let pList = tagName('p');
// setStyle(divList,'10px solid red');
// setStyle(pList,'10px solid red');
//
//
// function tagName ( name ) {
// return document.getElementsByTagName(name);
// }
//
// function setStyle ( eles,value ) {
// for(let i = 0;i<eles.length;i++){
// eles[i].style.border = value;
// }
// }
//三:使用对象封装
//好处:(1)便于维护,以后添加修改方法很方便 (2)避免全局变量污染
let obj = {
tagName:function ( name ) {
return document.getElementsByTagName(name);
},
setStyle:function ( eles,value ) {
for(let i = 0;i<eles.length;i++){
eles[i].style.border = value;
};
}
};
let divList = obj.tagName('div');
let pList = obj.tagName('p');
obj.setStyle(divList,'10px solid red');
obj.setStyle(pList,'10px solid red');
</script>
</body>
</html>
1.3-面向对象编程举例02
本小节知识点
- 介绍在以后的开发中,面向对象的应用场景
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
div{
height: 50px;
margin-top: 20px;
background-color: greenyellow;
}
p{
height: 50px;
margin-top: 20px;
background-color: hotpink;
}
</style>
</head>
<body>
<div></div>
<div></div>
<div></div>
<p></p>
<p></p>
<p></p>
<!--这是下个阶段要学习的第三方框架-->
<script src="jquery-1.12.4.js"></script>
<script>
//需求:给三个div和p标签设置边框
$('div,p').css('border','10px solid green');
/*面向对象编程
以后开发中,如果要实现一个需求,先看有没有现成的专业的对象来解决这个需求,如果有就直接拿来用,没有就自己造一个专业的对象
别人造好的对象: 快捷方便,但是不好维护
自己造的对象: 好维护,但是耗费时间和精力
*/
</script>
</body>
</html>
04-内置对象api
- 学习传送门:https://www.runoob.com/jsref/jsref-obj-array.html
- 内置对象api: js作者提前写好的对象,里面有一些预先定义的方法,我们直接使用即可,无需关心原理
- api : 预先定义的函数
- 学习内置对象: 不需要死记硬背,忘记了随时查阅文档。 用多了自然就记住了,熟能生巧
1.1-数组对象api
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
</body>
<script>
//声明数组
let arr = [10,20,30]
/*1.数组的增删改查操作
新增元素到最后面 : arr.push( 元素 )
新增元素到最前面 : arr.unshift()
删除最后一个元素 : arr.pop()
删除第一个元素 : arr.shift()
删除指定位置元素 : arr.splice(起始下标,删除数量)
*/
//2.将数组中的每一个元素都拼接成一个字符串
let str = arr.join()//10,20,30
console.log ( str )
//3.翻转数组
var newArr = arr.reverse()
console.log ( newArr )//[100,20,10]
//4.数组排序
let arr1 = [10,20,70,40,50,60]
//数组排序方法的参数是一个回调函数:告诉数组内置对象你的排序规则
//从小到大排序
arr1.sort(function (a,b)
{
return a - b
});
console.log ( arr1 )//从小到大
</script>
</html>
1.2-字符串对象api
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
</body>
<script>
let str = "今天又是美好的一天!";
//1 判断一个字符串在不在某个字符串里面
let index1 = str.indexOf("今天")//如果存在,则返回参数字符串首字母所在的下标
let index2 = str.indexOf("好")
let index3 = str.indexOf("又一天")//如果不存在,则返回 -1
console.log ( index1, index2, index3 )//0,5,-1
//2 截取字符串 第一个参数:从哪个下标开始截取 第二个参数:截取的长度
let str1 = str.substr(2,4)//又是美
console.log ( str1 )
//3 修改字符串 第一个参数:要修改的字符串 第二个参数:修改后的字符串
let str2 = str.replace("今天","明天")
console.log ( str2 )//明天又是美好的一天!
//4 分隔字符串:将字符串按照指定的符号分隔,得到一个数组
let str3 = "我&爱&你"
//这个函数的返回值一定是一个数组
let arry = str3.split("&")//以&符号分隔字符串 [我,爱,你]
console.log ( arry )// [我,爱,你]
//5 大小写转换 (只有英文才有大小写,中文不存在大小写)
console.log ( "AKlkshflsLKJHDHL".toLowerCase () )//转为小写 aklkshflslkjhdhl
console.log ( "AKlkshflsLKJHDHL".toUpperCase () )//转为大写 AKLKSHFLSLKJHDHL
console.log ( "中文不存在大小写".toLowerCase () )//转为小写
</script>
</html>
05-原型对象
1.1-构造函数new的工作原理
1.1.1-了解工厂函数
- 工厂函数:用于批量创建对象的函数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
</head>
<body>
<script>
/*
1.面向对象 : 是一种注重结果的思维方式
面向对象思维 : 注重结果
面向过程思维 : 注重过程
2.面向对象 与 面向过程的关系
* 面向对象本质 : 对面向过程的一种封装
3.构造函数创建对象(new关键字四个工作流程)
*/
/*学习路线
1.介绍创建多个对象需求
2.介绍函数封装来创建多个对象 (工厂函数)
3.引入最终目标: 构造函数
*/
//1.需求:创建3个人对象 (姓名name,年龄age,性别sex)
//弊端:(1)代码冗余 (2)维护不便
// let person1 = {
// name:'kiki',
// age:18,
// sex:'男'
// }
// let person2 = {
// name:'班长',
// age:38,
// sex:'男'
// }
// let person3 = {
// name:'王悦',
// age:28,
// sex:'男'
// }
//2.使用函数创建对象 : 解决创建多个对象代码冗余
//工厂函数 :
function createPerson (name, age, sex) {
//(1)创建空对象
let p = {}
//(2)对象赋值
p.name = name
p.age = age
p.sex = sex
//(3)返回创建好的对象
return p
}
let p1 = createPerson('kiki', 18, '女')
let p2 = createPerson('班长', 38, '男')
let p3 = createPerson('王悦', 28, '男')
console.log(p1, p2, p3)
</script>
</body>
</html>
1.1.2-重点构造函数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
</head>
<body>
<script>
/*
1.面向对象 : 是一种注重结果的思维方式
面向对象思维 : 注重结果
面向过程思维 : 注重过程
2.面向对象 与 面向过程的关系
* 面向对象本质 : 对面向过程的一种封装
3.构造函数创建对象(new关键字四个工作流程)
构造函数: 使用new关键字调用的函数
(1)创建空对象
(2)this指向这个对象
(3)对象赋值
(4)返回对象
注意:如果修改构造函数中的return的值,返回值为引用类型则会被修改,如果为值类型则不会修改
*/
/*学习路线
1.介绍创建多个对象需求
2.介绍函数封装来创建多个对象 (工厂函数)
3.引入最终目标: 构造函数
*/
//2.使用函数创建对象 : 解决创建多个对象代码冗余
//工厂函数 : 创建对象
function createPerson (name, age, sex) {
//(1)创建空对象
let p = {}
//(2)对象赋值
p.name = name
p.age = age
p.sex = sex
//(3)返回创建好的对象
return p
}
let p1 = createPerson('ikun', 32, '男')
let p2 = createPerson('班长', 38, '男')
let p3 = createPerson('王悦', 28, '男')
console.log(p1, p2, p3)
/*构造函数作用与工厂函数一致,都是创建对象。但是构造函数代码更加简洁
1.构造函数 : 使用new关键字调用一个函数
*/
function Person (name, age, sex) {
//(1)创建空对象 {}
//(2)将this指向这个对象 this = {}
//(3)对象赋值
this.name = name
this.age = age
this.sex = sex
//(4)返回这个对象 return this
}
let person1 = new Person('ikun', 32, '男')
let person2 = new Person('班长', 38, '男')
let person3 = new Person('王悦', 28, '男')
console.log(person1, person2, person3)
/* 声明一个空函数 */
// function fn () {}
// let res1 = fn() //普通函数
// let res2 = new fn() //构造函数
// console.log(res1, res2)
</script>
</body>
</html>
1.2-原型对象
- 本小节知识点:原型对象
- 原型:任何构造函数在被创建的时候,系统都会自动帮我们创建一个与之对应的对象,称之为原型对象
- 同时解决内存浪费与全局变量污染的问题
- 谁可以访问原型对象中的成员(属性和方法)
- 构造函数自身:
构造函数名.prototype
- 构造函数实例化的每一个对象:点语法直接访问
- 构造函数自身:
- 原型:任何构造函数在被创建的时候,系统都会自动帮我们创建一个与之对应的对象,称之为原型对象
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script>
/*
1.学习目标
a. 原型 :每一个函数被创建的时候,系统都会自动创建与之对应的对象,称之为原型对象
b. 作用: 解决 构造函数 (1)内存资源浪费 (2)全局变量污染
c. 怎么用: (1)构造函数.prototype (2)实例化对象直接访问
2.学习路线
(1)复习js构造函数new的工作原理
(2)引出构造函数的弊端 : 浪费内存性能
(3)引出解决方案 : 函数 ->全局变量污染
(4)引出对象 -> 内存资源浪费 + 全局变量污染
(5)引出原型对象
*/
//1.构造函数 : 调用一个函数使用了new关键字
// 构造函数中的方法 弊端 : 浪费内存资源
/*new关键字工作原理
//(1)创建空对象 {}
//(2)this指向这个对象 this = {}
//(3)执行赋值代码
//(4)返回这个对象 return this
注意:如果修改构造函数中的return的值,加入值为引用类型则会被修改,如果为值类型则不会修改
*/
// function Person(name,age){
// //(1)创建空对象 {}
// //(2)this指向这个对象 this = {}
// //(3)执行赋值代码
// //(4)返回这个对象 return this
// this.name = name;
// this.age = age;
// this.sayHi = function(){
// console.log('猴赛雷呀,我爱坤坤哟');
// }
// };
// let p1 = new Person('班长',28);
// console.log(p1);
// p1.sayHi();
// let p2 = new Person('班花',18);
// p2.sayHi();
// //每一个对象的方法都不是同一个
// console.log(p1.sayHi == p2.sayHi);//false
//2. 使用全局函数 : 解决内存资源浪费问题
//弊端 : 全局变量污染的问题
// function fn(){
// console.log('猴赛雷呀,我爱坤坤哟');
// };
// function eat(){
// console.log('中午我要以面向对象的形式吃个饭');
// };
// function Person(name,age){
// //(1)创建空对象 {}
// //(2)this指向这个对象 this = {}
// //(3)执行赋值代码
// //(4)返回这个对象 return this
// this.name = name;
// this.age = age;
// this.sayHi = fn;
// this.eat = eat;
// };
// let p1 = new Person('班长',28);
// console.log(p1);
// p1.sayHi();
// let p2 = new Person('班花',18);
// p2.sayHi();
// console.log(p1.sayHi == p2.sayHi);//true
//3.使用对象 解决 : (1)解决内存资源浪费 (2)全局变量污染
//弊端 : 对象自身还是全局的,造成新的全局变量污染
// let obj = {
// fn:function(){
// console.log('猴赛雷呀,我爱坤坤哟');
// },
// eat:function(){
// console.log('中午我要以面向对象的形式吃个饭');
// }
// }
// function Person(name,age){
// //(1)创建空对象 {}
// //(2)this指向这个对象 this = {}
// //(3)执行赋值代码
// //(4)返回这个对象 return this
// this.name = name;
// this.age = age;
// this.sayHi = obj.fn;
// this.eat = obj.eat;
// };
// let p1 = new Person('班长',28);
// console.log(p1);
// p1.sayHi();
// let p2 = new Person('班花',18);
// p2.sayHi();
// console.log(p1.sayHi == p2.sayHi);//true
/* 4.使用原型 : */
/* 4.1 原型 : 每一个构造函数在声明的时候,系统会自动的创建一个与之对应的对象,
称之为原型对象
*/
function Person(name,age){
this.name = name;
this.age = age;
};
/*4.2 如何获取原型对象
每一个函数都有一个 prototype 属性,指向这个原型对象
*/
console.log(Person.prototype);
/*
4.3 既然原型是一个对象 : 用于存储数据
*/
Person.prototype.sayHi = function(){
console.log('坤坤我爱你');
};
/*
4.4 谁可以访问 原型中的成员(属性+方法)
a. 构造函数自身 : 构造函数名.prototype
b. 这个构造函数所创建(实例化)的每一个对象
*/
// 实例化对象
let p1 = new Person('班长',18);
p1.sayHi();
//实例化对象
let p2 = new Person('班花',20);
p2.sayHi();
console.log(p1.sayHi === p2.sayHi);//true
</script>
</body>
</html>
1.3- ______proto______属性介绍
本小节知识点:proto属性介绍
- 1.属于对象,指向实例化这个对象的构造函数对应的原型
- 2.proto属性不是W3C的标准属性,所以实际开发中一般不会使用它来访问原型
- https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/proto
- 往原型添加属性方法,最好使用构造函数来访问
构造函数名.prototype
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
</head>
<body>
<script>
/*
1.prototype属性: 属于构造函数,指向原型对象
* 作用: 解决构造函数资源浪费+变量污染
2.__proto__属性: 属于实例对象,指向原型对象
* 作用: 可以让实例对象访问原型中的成员
*/
//1.构造函数
function Person (name, age) {
this.name = name
this.age = age
}
//2.原型对象
Person.prototype.eat = function () {
console.log('我中午真的吃了红烧武昌鱼')
}
Person.prototype.country = '中国人'
//3.实例对象
let p1 = new Person('班长', 28)
console.log(p1)
/*
__proto__ : 属于实例对象,指向原型对象
*/
console.log( Person.prototype === p1.__proto__ )//true
//实例对象为什么可以直接访问原型中的成员,其实都是通过__proto__来访问的
/*
1.虽然实例对象可以直接访问原型的原理是 __proto__,但是开发中不推荐使用
2.原因: __proto__不是ECMA标准语法,有一些浏览器不支持。
3.结论: 学习阶段,学习原型可以用__proto__. 实际开发中,建议省略__proto__
*/
p1.eat()//p1.__proto__.eat()
</script>
</body>
</html>
1.4-constructor属性介绍
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
</head>
<body>
<script>
/*
1. prototype : 属于构造函数,指向原型对象
* 作用:解决资源浪费+变量污染
2.__proto__ : 属于实例对象,指向原型对象
* 作用: 可以让实例对象访问原型中的成员
3.constructor: 属于原型对象,指向构造函数
* 作用: 可以让实例对象 知道自己被哪一个构造函数创建的
*/
//1.构造函数
function Person (name, age) {
this.name = name
this.age = age
}
//2.原型对象
Person.prototype.type = '哺乳动物'
Person.prototype.eat = function () {
console.log('吃东西')
}
//3.实例对象
let p1 = new Person('布丁', 3)
p1.eat()
console.log(p1.type)
/*
constructor : 属于原型对象,指向构造函数
作用:可以让实例对象知道自己被那个构造函数创建的
*/
console.log(Person.prototype.constructor)//Person
console.log(Person.prototype.constructor === Person )//true
console.log( p1.constructor )//Person p1.__proto__.constructor
</script>
</body>
</html>
1.5-静态成员与实例成员
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script>
/*
构造函数也可以有自己的属性: 例如prototype
静态成员 : 属于函数对象的成员
实例成员: 属于实例化对象的成员
*/
//构造函数
function Person(name,age){
this.name = name;
this.age = age;
};
Person.aaa = '啊啊啊';
console.log(Person.aaa);//静态成员
//实例化对象
let p1 = new Person('张三',20);
console.log(p1.name);//实例成员
console.log(p1.age);//实例成员
</script>
</body>
</html>
第一天学习总结
- 1.什么是面向对象?
- 面向对象不是一门技术,而是编程的一种思维方式。
- 2.面向对象与面向过程区别
- 面向过程:注重的是过程(实现某一个功能的逻辑,12345步)
- 面向对象:注重的是结果(能一行代码搞定,尽量一行代码搞定)
- 面向对象的本质其实是对面向过程的一个封装(将面向过程的逻辑步骤封装到对象中,然后一行代码搞定)
- 3.如何学习面向对象?
- a.理解对象
- b.了解并学习面向对象的三大特征
1.2-原型对象
- 1.什么是原型?
- 任何构造函数在被创建的时候,系统都会自动帮我们创建一个与之对应的对象,称之为原型对象
- 2.如何访问原型对象
- 构造函数名.prototype
- 3.哪些对象可以访问原型?
- a.构造函数自身
- b.该原型对应的构造函数实例化出来的对象
- 4.proto属性介绍
- 属于对象,指向实例化这个对象的构造函数对应的原型
- proto属性不是W3C的标准属性,所以实际开发中一般不会使用它来访问原型
- 6.constructor属性介绍
- 属于原型对象,指向这个原型对应的构造函数
- 作用:可以得知某个实例对象,到底是由哪一个构造函数生成的
1.3-js基础语法复习(了解即可)
- 1.数据类型
- 基本数据类型:number、string、boolean、undefined、null
- 复杂数据类型:object(包含三种子数据类型)
- 无序存储对象object:
{}
- 有序存储数组array:
[]
- 函数function:
function
- 无序存储对象object:
- 内置对象:属于object类型,是js作者提前写好的对象,里面存储了一些属性和方法,方便开发者直接使用
- Math:数学对象
- Date:日期对象
- Function:函数对象
- RegExp:正则表达式
- Array:数组对象
- String :string对象
- Boolean :boolean对象
- Number :number对象
- 2.值类型与引用类型
- a.值类型(基本数据类型):栈中存储的是数据,赋值拷贝的是数据,修改拷贝后的数据对原数据没有影响
- b.引用类型(复杂数据类型):栈中存储的是地址,数据存在堆中,赋值拷贝的是地址,修改拷贝后的数据对原数据有影响
- 3.in关键字三个作用
- a.for-in循环遍历对象属性
- b.判断对象能够访问某个属性
- 语法:
属性名字符串
in对象名
- 语法:
- c.判断数组是否包含某个下标
- 语法:
下标
in数组名
- 判断数组是否包含某元素,可以使用:
数组名
.indexOf(元素
)
- 语法:
- 4.delete关键字两个作用
- a.删除对象的属性 :
delete
对象名.属性名
- b.删除没有使用let声明的变量
- a.删除对象的属性 :
- 5.与=的区别
- a.===:全等运算符
- 严格匹配,值与数据类型必须要同时相等
- b.==:相等运算符
- 不严格匹配,当左右两边数据类型不一致的时候允许数据类型转换,分为五种情况(x == y)
- (1)当x与y都为null或者undefined, 返回true
- (2)当x或y为NaN,返回false
- (3)当x或y都为:string,number,boolean。且数据类型不一致的时候,此时会隐式转换成number后比较
- (4)如果x或y存在对象类型,则会转为原始值后比较
- (5)x与y都为对象类型,则比较它们的引用地址。如果同一个地址则为true,不同地址则为false
- 不严格匹配,当左右两边数据类型不一致的时候允许数据类型转换,分为五种情况(x == y)
- a.===:全等运算符
今天学习重点梳理(面试题)
-
1.new关键字四个工作流程(必须记住)
- 1.创建一个空对象
- 2.this指向这个对象
- 3.对象赋值
- 4.返回这个对象
-
2.构造函数、原型对象、实例对象三者关系(说的出来)
- 构造函数有一个属性prototype,指向自己的原型对象
- 实例对象有一个属性__proto__指向自己的原型对象
- 原型对象有一个属性constructor,指向自己的构造函数