1. 面向对象编程
1.理解什么是面向对象编程
面向对象不是一门技术,而是一种解决问题的思维方式
面向对象的本质是对面向过程的一种封装
2.理解什么是对象
对象的本质是程序代码与现实世界沟通的一座桥梁。它有两种含义
- 对象:是一种数据类型(存储数据的容器),以键值对的形式存储数据
- 对象:对现实世界实物的一种抽象。
<!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>
2. 内置对象:
- 内置对象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,6,-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>
3. 工厂函数(了解)
<script>
// 解决代码冗余方案: 封装函数
// 什么是工厂函数 : 创建多个对象的函数
function creatPerson(name, age, sex) {
// 1.声明对象
let p = {
// 2.属性名:属性值
namer: name,
ager: age
}
//2.对象.属性名 = 属性值
p.sex = sex
// 3. 返回值
return p
}
let zxy = creatPerson('张学友', 18, '男')
let ldh = creatPerson('刘德华', 20, "男")
console.log(zxy);
console.log(ldh);
</script>
4. 构造函数(重点)
- 构造函数:作用于工厂函数一致,但是代码更少
- 构造函数:使用new来调用的函数
new 工作原理
- 1.创建一个空对象{}
- 2.this指向这个对象 this.属性名 = {}
- 3.对象赋值
- 4.返回这个对象
new 细节:
- (1)构造函数首字母大写:为了提醒别人不要忘记new关键字
- (2)构造函数里主动写了return:
如果是值类型:无效 继续返回new创建的对象
引用类型:有效 会覆盖new创建的对象
function Person(name, age) {
// 1.创建一个空对象{}
// 2.this指向这个对象 this.属性名 = {}
// 3.对象赋值
this.name = name
this.age = age
//4.返回这个对象
}
let zs = new Person('张三', 18)
let l4 = new Person('李四', 19)
console.log(zs, l4);
5.原型对象
1.什么是原型对象:
- 任何构造函数在被创建的时候,系统都会自动帮我们创建一个与之对应的对象,称之为原型对象
2.原型对象作用:
- 解决内存浪费+ 变量污染
3.谁可以访问原型对象中的成员(属性和方法)
- 构造函数自身:
构造函数名.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
*/
// 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>
6.构造函数 原型对象 实例对象的关系
- 1.prototype:属于构造函数,指向原型对象
作用:解决内存浪费+变量污染 - 2.proto:属于实例对象,指向原型对象
作用:实例对象访问原型对象的成员 - 3.constructor:属于原型对象,指向构造函数
作用让实例对象知道自己是谁创建的
//1.构造函数
function Person(name, age) {
this.name = name
this.age = age
}
//2.原型对象
Person.prototype.eat = function () {
console.log('鸡腿');
}
//3.实例对象
let p = new Person('张三', 19)
console.log(p);
console.log(p.eat);
1.构造函数:每一个构造函数都有一个属性prototype,指向原型对象
2.原型对象:每一个原型对象都有一个属性constructor,指向构造函数
3.实例对象:每一个实例对象都有一个属性_proto_,指向原型对象
先有构造函数 再有原型对象 再有实例对象