01 js高级-数组的方法-面向对象
箭头函数
公式: const func2 = () => { }
相对以前的function() {} 会更加方便 简易
箭头函数-代码示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no"
/>
<title>02-箭头函数.html</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
</style>
</head>
<body>
<button>点击我</button>
<script>
// 以前写函数
function func1(num1) {
return num1 + 100;
}
// 箭头函数的时候
// const func2 = (num1) => num1 + 100;
// 定义一个箭头函数 没有形参 没有返回值
const func2 = () => {
console.log('执行业务1');
console.log('执行业务2');
};
// 没有形参、没有返回值、业务只有一行代码 大括号都可以省略
const func3 = () => console.log('执行业务1');
// 只有一个形参、没有返回值、业务只有一行代码
// const func4 = num => console.log(num + 1);
// const func4 = (num) => console.log(num + 1);
// 两个或者多个参数(括号不能省略)、没有返回值、业务只有一行代码
// const func5 = (a, b) => console.log(a + b);
// 没有形参,有返回值 业务两行代码
const func6 = () => {
let a = 100;
return a + 100;
};
// 没有形参、有返回值,业务一行代码
// const func7 = () => {
// return 100 + 200;
// };
// 没有形参、有返回值,业务一行代码 等价上述写法
const func7 = () => 100 + 200; // 相等于 return 100+200
console.log(func7());
const button = document.querySelector('button');
button.addEventListener('click', () => {
console.log(123321);
});
</script>
</body>
</html>
箭头函数-返回对象
如果你一定要在箭头函数中想要通过省略 return 的方式来返回对象,请你加上一个小括号
const func7 = (num) => ( {a:123} );
如果不加小括号 那么就会返回 unfinished
const func8=(num)=>{a:123}; unfinished
代码示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no"
/>
<title>05-箭头函数-返回对象.html</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
</style>
</head>
<body>
<script>
const arr = ['a', 'b', 'c'];
// 返回 [ {name:"a",name:"b",name:"c"} ]
// 如果你一定要在箭头函数中想要通过省略 return的方式来 返回对象,请你加上一个小括号
const func7=(num)=>({a:123});// => 右边加了小括号 表示想要返回 小括号里面的数据 return {a:123};
const func8=(num)=>{a:123};// => undefined
console.log(func7()); {a:123}
console.log(func8());// undefined
</script>
</body>
</html>
数组方法-forEach()
遍历数组
forEach() 数组每一个元素都执行一次回调函数,类似以前的for 循环 forEach高阶函数(可以接收一个形参 - 函数)
公式:
const arr = ['a','b','c']
arr.forEach(value => console.log(值是${value})) 打印结果: 值是'a' 值是'b' 值是'c'
注意
for循环可以通过break来打断, forEach不能通过break来打断
代码 示例
// forEach() 数组每个元素都执行一次回调函数。 = 类似以前的for forEach 高阶函数(可以接收一个形参-函数)
// for循环可以通过 break来打断、 forEach不能通过break打断
const arr = ["a", "b", "c"];
// 分别打印他们
arr.forEach(function (value, index) {
console.log(`值 是 ${value} 下标是 ${index}`);
});
arr.forEach((value, index) =>
console.log(`值 是 ${value} 下标是 ${index}`)
);
arr.forEach((value) => console.log(`值 是 ${value}`));
数组方法-map()
map()根据原来得数组 来返回新的数组
也会循环数组 在循环的回调函数中可以返回新的数组 组装成新的数组
// map 根据原来的数组 来返回新的数组
// 也会循环数组 在循环的回调函数中可以返回新的数据 组装成新的数组
// const arr = ['a', 'b', 'c'];
// 可以返回 ["我的字母是a","我的字母是b","我的字母是c"]
// const newArr = arr.map((value) => '我的字母是' + value); // [1,1,1]
// console.log(newArr);
// const list=[10,11,12];
// const newList=list.map(value=>value+1);// [11,12,13]
// console.log(newList);
// const objectArr=[{name:"悟空"},{name:"八戒"}];
// const newObjectArr=objectArr.map(value=>{
// // 1
// value.color="red";
// // 2
// return value
// })// [{name:"悟空",color:"red"},{name:"八戒",color:"red"}]
// console.log(newObjectArr);
const texts = ["刘德华", "郭德纲", "林志颖"];
// // 返回 [<div>刘德华</div>,<div>郭德纲</div>,<div>林志颖</div>]
const newTexts = texts.map((value) => `<div>${value}</div>`);
// console.log(newTexts);
// // [<div>刘德华</div>,<div>郭德纲</div>,<div>林志颖</div>]
// // 把它转成字符串
const html = newTexts.join(""); // <div>刘德华</div><div>郭德纲</div><div>林志颖</div>
// console.log(html);
document.body.innerHTML = html;
// 后面再说
// const renderHTML=value=>`<div>${value}</div>`
// document.body.innerHTML=["刘德华","郭德纲","林志颖"].map(renderHTML).join("");
捐赠管理-map()方法渲染-案例示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no"
/>
<title>01-捐赠管理.html</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
h3 {
margin: 50px;
text-align: center;
}
table {
width: 800px;
margin: 0 auto;
border-collapse: collapse;
text-align: center;
}
thead {
background-color: #337ab7;
color: #fff;
}
td,
th {
padding: 10px 50px;
/* 设置文字不换行 */
white-space: nowrap;
}
</style>
</head>
<body>
<h3>捐赠管理</h3>
<table border="1">
<thead>
<tr>
<th>序号</th>
<th>捐赠人</th>
<th>收捐单位</th>
<th>金额</th>
<th>收捐日期</th>
<th>操作</th>
</tr>
</thead>
<tbody></tbody>
</table>
<script>
// 获取tbody
const tbody = document.querySelector("tbody");
// 定义数据
const arr = [
// id:数据编号 person:捐赠人姓名 unit:捐赠单位名称 money:捐赠金额 date:捐赠日期
{
id: 1,
person: "刘德化",
unit: "壹基金",
money: 1000,
date: "2021-10-5",
},
{
id: 2,
person: "周杰伦",
unit: "自然之友",
money: 1000,
date: "2021-01-15",
},
{
id: 3,
person: "李连杰",
unit: "嫣然基金",
money: 1000,
date: "2021-06-7",
},
];
// 根据数组来渲染页面
function render() {
// 只能使用 map方法 和 数组转方式方法 join 来实现 拼接html的功能
// 把 arr 转成(map、join 来实现功能) 变量 html 让下面的代码 (tbody.innerHTML = html;) 执行成功
let newArr = arr.map(
(value) => `
<tr>
<td>${value.id}</td>
<td>${value.person}</td>
<td>${value.unit}</td>
<td>${value.money}</td>
<td>${value.date}</td>
<td>
<a href="#" class="del">删</a>
<a href="#" class="update">改</a>
</td>
</tr>
`
);
let html = newArr.join("");
tbody.innerHTML = html;
}
// 根据数组数组渲染页面
render();
</script>
</body>
</html>
代办事项-filter方法过滤-案例示例
// // 给每一个商品绑定点击事件
for (let index = 0; index < checkboxList.length; index++) {
checkboxList[index].addEventListener('click', function () {
// 判断是否达到了全选 条件
// 判断每一个小小的复选框的选中状态 如果都是true,那么就全选
let checked = checkboxList.every((value) => {
if (value.checked === true) {
return true;
} else {
return false;
}
});
// 设置全选按钮即可
checkAll.checked = checked;
});
}
</script>
</html>
<!--
两个知识
1 伪数组转真正的数组 let newArr=[...伪数组] ;
2 every 要求数组的每一个元素都符号要求, every才返回true
使用场景, 商品全选 => 每一个小商品都选中, 全选才勾选!!
4 如果 数组 有every方法, list.every 看是不是undefined
不是的话 表示数组有 every方法 list.every() 调用
是 表示数组没有 every方法,不用list.every()
-->
数组方法 - every()
进行判断 全部符合就会返回true 只要有一个不符合就返回false
every();
function every() {
// 会返回 true或者false
// 如果数组中每一个元素都复合条件,every返回true
// const arr = [1, 6, 3, 4];
// // 判断数组中每一个元素,是不是都小于 5 如果是 返回true
// // every当中的函数,要求每一个都return 了true 最后 every的返回值才是true
// const result = arr.every((value) => {
// if (value < 5) {
// return true;
// } else {
// return false;
// }
// });
// const result = arr.every((value) => value < 5);
// console.log(result);
// 有一个数组,存放每一个人 关于肺炎的检查结果
const arr = [true, true, true, true, true]; // true就表示安全,false 中招
// 我想要判断一下 这个人群安不安全 (只要有一个为false,不安全) 要求每一个都为true才安全
// const result = arr.every((value) => {
// if (value === true) {
// return true;
// } else {
// return false;
// }
// });
// console.log(result);
// every:
//会返回true 或者 false
//要求数组中每一个元素都符合条件,every 得到true
//如果空数组调用了every 得到结果 也是true
}
数组方法 -filter
过滤或者筛选
const arr = [1, 2, 3, 4, 5, 6, 7];
const newArr = arr.filter((value) => value % 2 !== 0);
过滤, 过滤出满足条件的数据 =>新的数组
// 过滤, 过滤出满足条件的数据 =>新的数组
const arr = [1, 2, 3, 4, 5, 6, 7];
// 返回 奇数
// const newArr = arr.filter((value) => {
// // 如果你return 了 true 表示当前的value你想要
// if (value % 2 !== 0) {
// // value 1 2 3 4 5 6
// // value%2!==0 value=[1,3,5,7]
// // 奇数
// return true;
// } else {
// return false;
// }
// }); 简化
const newArr = arr.filter((value) => value % 2 !== 0);
console.log(newArr);
}
数组方法-some()
检测数组,其中只要有一个元素符合条件,some返回true ( every要求每一个都符合 )
公式:
const arr = [1, 3, 4, 6, 7];
const result = arr.some((value) => value > 6); //true
// 检测数组,其中只要有一个元素符合条件,some返回true (every要求每一个都符合)
const arr = [1, 3, 4, 6, 7];
// 这个数组里面有没有元素大于6的
const result = arr.some((value) => value > 6);
console.log(result); //true
/*
every 和 some 一起记
every 要求全部都符合
some 最少有一个符合即可
*/
数组方法- 其他方法以及属性
伪数组转真数组方法
数组 = [ ...伪数组 ]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no"
/>
<title>09-伪数组转真正的数组.html</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
</style>
</head>
<body>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
<script>
const lis = document.querySelectorAll('li'); // 伪数组
// const liList=domToArr(lis);
// console.log(liList.every);
// 现在先简单用一个
// const liList=[...伪数组]
const liList=[...lis];// 最简单的转伪数组的方式 先这么用
</script>
</body>
</html>
面向对象 -概念-思维
一种编程行业通用的写项目级的代码的思维,引导我们如何编写 高质量的代码,万物皆对象-看待事物的角度,( 属性: 数据, 行为: 动作 (方法))代码特点是封装和继承
概念:一般写大型项目才使用
思维:看成两部分
1属性:(颜色,名字身高等)
2行为:(修改颜色,设置文字大小,等)
// 分析代码 功能 或者任何事情 面向对象的思维
// 属性
// 行为
// 孙悟空
// 属性: 名字孙悟空、颜色、黄色、身高150、毛发多、
// 行为:会走路、会技能72变、
// 思维 去分析 轮播图
// 属性 有图片、有小圆点(索引器)、有上下箭头 、居中显示
// 有小圆点(小,选中,蓝色,未选中,黑色,中间存在间隔)
// 行为
// 自动轮播、点击上下页切换显示、点击指示器跳转显示、显示渐变效果显示
// 结合写代码的经验 从上面整理出有效的属性和行为 ->构造代码的结构
// 对象 就是指对象类型 Object
面向对象-字面量
- 简单粗暴
- 不适合创建多个同样类型的对象的场景
- 只能在小案例使用,不好修改样式
面向对象-构造函数
专业术语
会把 createPerson 叫做 构造函数
会把 createPerson 创建出来的对象 叫做 实例
this.属性值 和 new 创建对象 配套使用
公式:
1 声明一个函数
function createStudent(name,age){
// 2 给this赋值
this.name=name
this.age=age
}
// 3 通过new的方式来创建对象 就叫实例
const obj1=new createStudent('悟空',18)
console.log(obj1);
后续添加属性就this. 属性值 形参也要有几个 写几个
// 后续添加属性 就 this. 属性值 形参也要有几个 写几个
function createStudent(name, age, sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
const obj1 = new createStudent("悟空", 18, "男");
console.log(obj1);
构造函数的工作原理:
- 开辟空间
- 将新的创建的对象对象构造函数中的this
- 为对象赋值
- 将创建好的对象的地址返回
13-构结函数的弊端
外部声明函数 方法 在大型项目中 会污染了全局变量
缺点: 代码不够优雅 污染了全局变量 以后不能写 say方法,很容易就覆盖()
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no"
/>
<title>16-构造函数-性能问题.html</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
</style>
</head>
<body>
<script>
// 构造函数的 方法 都会通过类似的这种方式 来实现 多个实例的方法共享
function say() {
console.log('你好');
}
function CreatePerson(name) {
this.nickname = name;
this.say = say;
}
// function say() {
// console.log("学生你好");
// }
// function createStudent(params) {
// }
const obj1 = new CreatePerson('悟空');
const obj2 = new CreatePerson('八戒');
console.log(obj1);
console.log(obj2);
console.log(obj1.say === obj2.say); // true 这个代码是合理的 优化过
console.log(obj1.say === obj2.say); // false 不够好 性能不够好 两个say占据了两个内存
// 函数函数 方法提取出去 这套代码
// 优点: 方便代码维护、也解决了性能 obj1.say === obj2.say
// 缺点: 代码不够优雅 污染了全局变量 以后不能写 say方法,很容易就覆盖()
</script>
</body>
</html>
原型对象-勾结函数(好用,没弊端)
在原有的结构函数上使用原型对象
-
原型的单词是
prototype, 原型的这个名字是行业内共同认可的名字。 -
原型本质是一个对象,理解为
JavaScript自动帮我们添加的 -
原型是
JavaScript自动帮我们在定义构造函数的时候添加的 -
所有构造函数的实例,共享一个原型
-
原型上一般是挂载函数
主要:
构造函数内只放属性 name 、age、color、height
对应原型上 都是放 方法 = 函数
// 原型对象 是任何构造函数对存在的一个对象 prototype // 作用: 构造函数看是人, 原型对象 就是人的DNA // 如果我们修改了DNA,那么通过构造函数创建实例都会一起发生修改 // 如果我们在DNA上新增了一些东西,对应实例一样会被新增 function CreatePerson(name) { this.name = name; } // 原型对象 // console.log(CreatePerson.prototype); // 在DNA上新增 东西 CreatePerson.prototype.say = function () { console.log("你好"); }; const obj1 = new CreatePerson("悟空"); const obj2 = new CreatePerson("八戒"); // obj1.say(); // obj2.say(); function CreateStudent() {} CreateStudent.prototype.say = function () { console.log("学生你好"); }; // console.log(obj1.say === obj2.say);// 没有性能问题 // 有污染全局变量的问题吗 没有 // CreatePerson.prototype.say // CreateStudent.prototype.say // 小结 原型对象-构造函数 一般情况 // 构造函数内只放属性 name 、age、color、height // 对应原型上 都是放 方法 = 函数面向对象-案例
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no" /> <title>20-面向对象-初体验.html</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; } .scale{ border-radius: 50%; animation:ani-scale 3s linear infinite alternate ; } @keyframes ani-scale { 0%{ transform: scale(0.1); } 100%{ transform: scale(2); } } </style> </head> <body> <button class="btn1">控制图片1</button> <script> /* 需求: 通过 new MyImg("图片地址") 页面上就会多一个图片标签 1 页面上多一个图片的本质代码 1 const img = document.createElement("img"); 2 img.src="图片地址" 3 document.body.appendChild(img); 2 new的方式来创建图片 new MyImg 做了什么事情 => 调用了一个构造函数 MyImg 通过 点击了按钮,控制对应的图片 放大缩小效果 1 css来实现放大缩小 2 按钮 绑定点击事件 */ // const img1 = new MyImg('./images/1.png'); // 页面上多一个图片标签 function MyImg(src) { const img = document.createElement('img'); img.src = src; document.body.appendChild(img); this.dom=img;// 把图片dom元素 添加到 this对象的一个属性 dom属性上了 } MyImg.prototype.scale=function(){ // 图片放大缩小的本质是不是给图片的dom元素 添加一个class // 获取一下 上一个函数中的一个变量 img // 原型上 想要获取另外一个函数中的变量 // console.log(this.dom); this.dom.classList.add("scale"); } const imgModel = new MyImg('./images/s_02.jpg');// 创建了一个对象 const btn1=document.querySelector(".btn1"); btn1.addEventListener("click",function () { imgModel.scale();// 要调用这个对象的放大缩小的方法 }) /* 需求: 1 通过行代码 const divModel = new Div("这个是普通的地址"); 页面中出现对应的一个div标签 2 给按钮绑定点击事件 触发了 divModel.changeColor("red"); 这个div的背景颜色变成红色 divModel.changeColor("yellow"); 这个div的背景颜色变成黄色 分析: 1 Div 是一个构造函数 2 Div 构造函数 在原型上有一个方法 changeColor 3 const divModel = new Div("这个是普通的地址"); 这行代码实际的作用 页面中出现一个div 1 const div=document.createElement("div"); 2 div.innerText="文本内容" 3 document.body.appendChild(div) 4 divModel.changeColor("yellow"); 这个div的背景颜色变成黄色 ???.style.backgroundColor="yellow" */ function Div(text) { const div = document.createElement('div'); div.innerText = text; document.body.appendChild(div); this.dom = div; } Div.prototype.changeColor = function (color) { // this.dom = div; this.dom.style.backgroundColor = color; }; Div.prototype.setFont = function (px) { // this.dom = div; this.dom.style.fontSize = px; }; const button=document.querySelector("button"); const divModel1 = new Div('这个是普通的div1'); button.addEventListener("click",function () { divModel1.changeColor("red"); // 新功能 divModel1.setFont("100px");// 希望div中的文字 大小变为100px }) </script> </body> </html>面向对象-指定标签添加图片
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no" /> <title>03-面向对象的案例.html</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; } </style> </head> <body> <ul> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> </ul> <script> /* 需求 1 const imgModel =new MyImg("图片地址") (不要直接插入到body标签上) 2 imgModel.append("父元素的选择器"); 希望可以在父元素里面插入一个img 3 根据给到的需求 1 先拆分出 代码的结构 要定义构造函数吗 原型上要写什么方法 2 根据给到的代码具体需求 结合 底层js+webAPI的知识 来实现 封装的功能 3 在以前更多的是学习如何直接写代码问题 ,现在也是在写代码 - 直接解决问题,通过封装代码(提高的能力)->解决问题 */ function MyImg(src) { const img = document.createElement("img"); img.src = src; this.dom = img; } MyImg.prototype.append = function (parentSelector) { // 通过 this.dom 获取到 构造函数中创建好的图片img对象 // 希望可以在父元素里面插入一个img 底层的webAPI代码是什么 // document.body 父元素 // 父元素.appendChild(子元素); // img 创建的元素 document.querySelector(parentSelector).appendChild(this.dom); }; // 获取指定的li标签 // const li=document.querySelector("li:nth-child(3)"); // 先创建一个图片标签 const imgModel = new MyImg("./images/s_10.jpg"); // 指定位置来插入元素 imgModel.append("li:nth-child(3)"); // 图片插入到指定的父元素中 </script> </body> </html>
02-JS-高级-原型继承(call)-函数默认值-拓展-剩余运算符
call 就是借用别人的 属性 方法
1 - call -调用属性
如父亲的属性 儿子想要调用
父元素.call(this,形参1,形参2等等) this是指自己 谁调用this this就是指谁
this. 属性 this. 只能在属性上使用 方法不能使用 方法要使用对象名称
//父亲
function Person(name, age, height) {
this.name = name;
this.age = age;
this.height = height;
}
//儿子
function Student(name, age, height, color) {
// 这一行代码解决了继承的问题!!
// call 借用别人的方法
// 谁有方法
// 谁想要借用person方法 this = 实例 = 下面代码的s1
//this 指的是自己(Student) 谁调用this 谁就是this
Person.call(this, name, age, height); //儿子想要使用父亲的某些代码, 父亲方法.call(this,形参1,形参2)
// this.name = name;
// this.age = age;
// this.height = height;
this.color = color;
}
const p1 = new Person("小明", 18, 180);
const s1 = new Student("小红", 28, 170, "red");
console.log(p1);
console.log(s1);
call-调用方法
如调用方法 超人会飞 普通人调用
父元素 .方法 .call (要调用的对象名称)
const obj={
name:"超人",
skill(){
console.log(this.name +" 会飞");
}
}
// 超人有技能 会飞
const obj2={
name:"普通人"
};
// 让普通人 借 一下超人的技能 skill 固定的规则
obj.skill.call(obj2);
方法内可以给对象添加属性
本质可以给对象添加新的属性
const car = {
name: '装甲车',
add: function (username, age) {
// 本质 可以给car添加新的属性
this.username = username;
this.age = age;
},
};
car.add('发动机', 100);
console.log(car); // {name='装甲车',username='发动机',age=100}
可以实现了一个空对象obj通过call的使用来实现了 借别人的方法add来给obj添加新的属性
const car = {
name: '装甲车',
add: function (username, age) {
// 本质 可以给car添加新的属性
this.username = username;
this.age = age;
},
};
// car.add('发动机', 100);
// console.log(car);
const obj = {};
// car.add.call(obj); // obj 想要借用 添加属性的方法
car.add.call(obj, '发动机', 200); // call 传入参数 add.call(谁要借用,被借用的方法的形参1,被借用的方法形参2)
console.log(obj);
继承-call-prototype
想要实现继承的功能 分两个部分
1 属性的继承
父元素.call(this,其他参数)
person.call(this,name,age)
2 方法的继承
儿子的原型.方法 = 父亲的原型.方法
studen.prototype.say = person.prototype.say
// 对象 两个大的特点
// 属性 - 属性的继承
// 行为-方法
// 让儿子也具有父亲的行为 => 把父亲的DNA 给到儿子即可
// 给儿子添加行为 儿子的原型上添加
// 父亲的行为 存放在父亲原型上
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.say = function () {
console.log(this.name, this.age); // 我是谁 我的年龄是
};
Person.prototype.show = function () {
console.log(this.name + " 打螺丝");
};
function Student(name, age, color) {
// name age person里面已经有定义
// 借用一下
Person.call(this, name, age);
// color person里面没有的 需要自己来定义
this.color = color;
}
const s1 = new Student("小学生", 18, "yellow");
// 把父亲的行为 也设置到儿子
Student.prototype.say = Person.prototype.say;
Student.prototype.show = Person.prototype.show;
s1.say();
s1.show();
// console.log(s1);
/*
总结
想要实现继承的功能 分两个部分
1 属性的继承
Person.call(this,其他参数)
2 方法的继承
儿子的原型.say = 父亲的原型.say
*/
案例
/*
封装 代码 实现以下的功能
1 父亲 Element
1 属性 dom this.dom
2 行为 实例.append(父元素标签的选择器)
2 儿子1 ElementDouble div
1 继承父亲 Element
属性 dom
行为 append
3 儿子2 ElementSingle img
属性 dom
行为 append
4 当执行以下代码时 出现对应效果
1 const divModel = new ElementDouble("div","div内的文字")
2 divModel.append("body") ; body标签可以出现 一个 div
1 const imgModel = new ElementSingle("img","图片地址")
2 imgModel.append("body"); body标签可以出现 一个图片
*/
//父亲
function Element(tagName) {
const dom = document.createElement(tagName);
this.dom = dom;
}
Element.prototype.append = function (parentSelector) {
document.querySelector(parentSelector).appendChild(this.dom);
};
// 儿子1
function ElementDouble(tagName, content) {
Element.call(this, tagName);
this.dom.innerText = content;
}
ElementDouble.prototype.append = Element.prototype.append;
// 儿子2
function ElementSingle(tagName, src) {
Element.call(this, tagName); //继承父亲的属性
this.dom.src = src;
}
// 继承父亲的行为
ElementSingle.prototype.append = Element.prototype.append;
const divModel = new ElementDouble("div", "这是div里面的内容");
divModel.append("body");
const imgModel = new ElementSingle("img", "./images/s_10.jpg");
imgModel.append("div");
函数参数默认值 es6
注意:
默认值就是 (调用者)你没有, 就使用我, 你有,使用你的
如果你给我传递了形参 我就输出你的形参
function show(msg = '你好',str="你我都好") {
console.log(msg,str);
}
show(); // 没有传递参数 输出你好 你我都好
show('大家好'); // 输出 大家好 你我都好
show('大家好',"世界美好"); // 输出 大家好 世界美好
对象-简写
简写 如果变量的名字和属性的名字 一致的话, 对象可以简写
const name = 123 对象 = { name } 对象.name 就能获取它的值
// 简写 如果变量的名字和属性的名字 一致的话,对象可以简写
// const obj = {
// // 属性名 和 属性值
// username: 123,
// };
const username = 123;
const color = 'red';
const say = function () {};
function show() {}
// 很常用
const obj = {
username, // username:username
color, // color : color
say,
show,
height: 100,
};
obj.height = 200;
console.log(obj);
// 对象中方法的简写
const person={
show:function(){
console.log("show");
},// 常规写法
say(){
console.log("say");
} // es6 关于 方法简写
}
person.show();
person.say();
对象-数组-解构
对象-解构:
const { username,height } = { username:'悟空',height:200 }
打印 username,height 就是 username: '悟空 ', height:200
数组-解构:
const arr = [1 ] > const [ a, b ] = arr 打印 a=1 b=undefined
const [ a, b ] = [ 100, 200 ] > 打印 a = 100 , b = 200
解构+默认值:
如果右边对象中没有height 属性那么 height变量 = 1000
const { username,height = 1000 } = { username:'悟空',height:200 }
c 在右边找不到对应的数据 c 就使用默认值 300
const [a,b,c=300]=[100,200];
代码示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div data-index="100" data-num="200">div</div>
<script>
// dataset本身就是一个对象,所以可以用解构来获取他的值
const { index,num } = document.querySelector('div').dataset;
console.log(index);//100
console.log(num);//200
//数组解构
// const arr = [1, 2, 3, 4];
// const [a, b, c, d] = arr;
// console.log(a, b, c, d);
// //对象解构
// const obj={
// username:'悟空',
// height:188
// }
// const {username,height}=obj
// console.log(username,height);
// 数组解构 + 默认值
const arr = [1];
// const [a,b]=arr// a=1 b=undefined
// b = 2 默认值 (你没有,就使用我,你有,使用你的)
const [a, b = 2] = arr;
console.log(a, b); //a=1 b=2
//对象 解构 + 默认值
const obj = {
username: 100,
};
const { username, height = 200 } = obj;
console.log(username, height);
/*
小结
1 解构 对象 和 数组上
对象
const { username,height } = {username:"悟空",height:200}
数组
const [a,b]=[100,200];
2 解构 + 默认值
如果 右边的对象中没有height 属性 那么 height变量 = 1000
const { username,height=1000 } = {username:"悟空",height:200}
c 在右边找不到对应的数据 c 就使用默认值 300
const [a,b,c=300]=[100,200];
*/
</script>
</body>
</html>
扩展-剩余-延展运算符 ...
合并数组-伪数组转真数组
扩展运算符可以应用于 合并数组
扩展运算符可以应用于 合并数组
arr1=[1,2,3] arr2=[3,4,5]
arr1.push( ... arr2 ) 结果是: arr1[1,2,3,4,5]
可以将 伪数组 转 真数组
数组 = [ ... 伪数组 ]
// const lis = document.querySelectorAll('li');// lis 伪数组 没有map方法
// const newList = [...lis]; // 如何理解 ? 转成真正的数组
剩余-数组-对象
剩余-数组-对象
获取剩下数组
注意: 和解构不同的是 加入 ... 那么他获取的值就是数组
在数组中 放进 ... 就可以后面的内容 存进一个新数组中 就算后面是没内容 那也返回空数组
数组中 const [a,b,...c]=[1,2,3,4,5,6,7]; // c =[3,4,5,6,7]
// 获取剩下 数组
// const [a,b,...c]=[1,2,3,4,5,6,7];
// console.log(a,b); // 1 , 2
// console.log(c);// [3,4,5,6,7]
// const [a,b,...c]=[1,2,3];
// const [a, b, ...c] = [1, 2];
// console.log(c); // [3]
// console.log(c); // []
获取剩下对象
在对象中 放进 ... 就可以后面的内容 存进一个新对象中 就算后面是没内容 那也返回空对象
对象中 const { a,...d } = { a: 1, b: 2, c: 3 }; // d = {b:2,c:3 }
// 获取剩下 对象
// const { a, ...c } = { a: 1, b: 2, c: 3 };
// const { a,b,c ,...d } = { a: 1, b: 2, c: 3 };
// console.log(c);// ? {b:2,c:3}
// console.log(d); // ? {}
获取剩下 用在函数的形参上的和
也能计算数据和的功能
function calc(...args) {
// args 数组 装载这所有传给calc的参数
// console.log(args);
// 声明一个变量
let sum = 0;
args.forEach((value) => (sum += value));
console.log(sum);
}
calc(1, 2); // ? [1,2]
calc(1, 2, 3); // [1,2,3]
calc(1, 2, 3, 4); // [1,2,3,4]
计算最大值得写法
function getMax(...args) {
// args= 数组 接收 所有传递给 getMax方法的 参数
// console.log(args);
// 计算最大值 的
let max = args[0];
args.forEach((value) => {
if (value > max) {
max = value;
}
});
console.log(max);
}
展开-延展-数组-对象
展开运算符 对数组操作
在前面新增一个元素 后增同理
const arr = ["a", "b", "c"]; const newArr=[ ...arr ,' d'] 打印: [ "a", "b", "c",'d' ]
// 展开运算符 对数组操作
const arr = ["a", "b", "c"];
// 在数组的后面 新增一个 元素 'd'
// const newArr=[...arr,'d'];
// 在数组前面 新增一个属性 w
// console.log(newArr);
// const newArr = ['w', ...arr];
// console.log(newArr);
// arr.push
// arr.unshift
// 中间 无法使用 ...
// splice 来实现
展开运算符 对对象操作
注意:
需要给新对象 重新声明 对象 因为引用类型都是指向同一地址,一旦修改数据,另一个也会改变
// 展开 ... 用法
const obj = {
username: '悟空',
height: 200,
};
// // 新创建一个对象 这个对象 具有 所有 obj的属性
// // 同时 还有多一个属性,color
// 建议这做 互补影响
const newObj = { ...obj, color: 'yellow' }; // 给newObj 开辟新的内存空间
// const newObj={ username:"悟空",height:20}; // 给newObj 开辟新的内存空间
newObj.username = '八戒';
newObj.weight = 100;
console.log(obj);
console.log(newObj);
数组去重案例 - some方法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no"
/>
<title>21-数组去重.html</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
</style>
</head>
<body>
<input type="text" />
<ul></ul>
<script>
/*
1 输入框绑定键盘按下事件
1 判断按下的是不是 回车键
2 是的话 获取输入框的值
3 判断当前要显示的数据 是否已经存在于数组中 filter 可以 some可以
如果是已经存在 就不要继续添加
如果是不存在 就继续添加
4 把它添加到数组中
5 写一个方法 把数组的数据 拼接成li标签,插入到 ul中
*/
const input = document.querySelector('input');
const ul = document.querySelector('ul');
const arr = ['a', 'b'];
render();
input.addEventListener('keydown', function (event) {
//判断按下的是不是回车
if (event.key === 'Enter') {
// console.log(this.value);
// some 如果数组中有一项 是返回了true 整个some方法就返回了true
// 调用some方法的时候,在它的回调函数中 拿数组中的元素 和 当前要添加的元素 做比较 如果相等 就返回true 表示找到了重复
const isHas = arr.some((value) => value === this.value); // 在我的数组中找到了和你待添加的元素 一样的值 返回true
if (isHas) {
// 有重复了 不要再添加
console.log('有重复了 不要再添加');
} else {
// 没有重复 你可以添加
// 把它添加到数组中
arr.push(this.value);
// 数组发生了改变 重新调用render方法 来实现页面的渲染
render();
}
}
});
function render() {
const html = arr.map((value) => `<li>${value}</li>`).join('');
ul.innerHTML = html;
}
</script>
</body>
</html>
数组去重-filter方法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no"
/>
<title>21-数组去重.html</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
</style>
</head>
<body>
<input type="text" />
<ul></ul>
<script>
const input = document.querySelector('input');
const ul = document.querySelector('ul');
let arr = ['a', 'b'];
render();
input.addEventListener('keydown', function (event) {
if (event.key === 'Enter') {
// filter 来解决
// filter 过滤
// 先过滤出 和当前的输入框的值 不相等的 数据
// 然后再添加
// 当前输入框的值 "d"
// 我数组 ['a','c','d']
// 数组过滤 不包含 "d" => ['a','c']
// ['a','c'] 再次添加 'd' 进去 就可以了
// 过滤出不包含 当前输入框的值的数组
const newArr = arr.filter((value) => value !== this.value);
// debugger
// 让我们的旧的数组 等于你过滤后的数组
arr = newArr;
arr.push(this.value);
render();
}
});
function render() {
const html = arr.map((value) => `<li>${value}</li>`).join('');
ul.innerHTML = html;
}
</script>
</body>
</html>
03-JS-高级-Set数组去重
set数组去重
-
set对象 是es6 才推出
-
注意的功能 去重处理
-
set.add(1); 如果原数组已经有了,那么就不会添加进去
-
set是一个对象,不是一个数组
-
实现 使用set转成数组的时候,需要考虑 ( set对象转-数组 数组-转成对象 )
-
数组-转成对象 new Set( beforeArr )
-
set对象转-数组 const arr = [ ...set ]
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no" /> <title>01-set数组去重.html</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; } </style> </head> <body> <script> /* 1 set对象 是es6 才推出 2 主要的功能 去重处理 set.add(1); 3 set是一个对象,不是一个数组!! 4 实现 使用set转成数组的时候,需要考虑 (set对象转-数组 数组 - 转成对象) 数组 - 转成对象 new Set(beforeArr) set对象转-数组 const arr=[...set]; */ // 0 有时候 先设置一个初始数组 里面已经存在一些数据 // 在创建set的对象的时候,把数组传给它 const beforeArr=['a','b',3,4]; // 1 set对象 需要被new 出来 const set = new Set(beforeArr);// 数组转成set对象 // 2 给set添加数据的时候 使用 add方法 set.add(1); set.add(2); set.add(2);// 发现有重复数据了,自己内部过滤 set.add(2);// 发现有重复数据了,自己内部过滤 set.add(2);// 发现有重复数据了,自己内部过滤 set.add(2);// 发现有重复数据了,自己内部过滤 // 3 打印set 看一下 console.log(set); // 4 set 转成 数组(map、forEach。。。) const arr=[...set]; console.log(arr); </script> </body> </html>
call apply bind: 修改this指向和传递参数
1, 修改this指向- call : obj.skill.call(调用者) 传递参数- call: obj.skill.call(person,参数1,参数 2)
const obj = {
name: '老王',
skill() {
console.log(this.name + ' 翻墙');
},
};
const person = {
name: '大郎',
};
// call 方式来修改this的指向
obj.skill.call(person);// 大郎 借用老王的方法
const obj = {
name: '老王',
skill(a, b) {
console.log(this.name + ' ' + a + ' ' + b);
},
};
const person = {
name: '大郎',
};
obj.skill.call(person,1,2);// 传参
计算最大与最小值 这种事es6 主流的常用方法call方法
const arr=[1,2,3,4];
console.log(Math.min(...arr)); //最小值
console.log(Math.max(...arr)); //最大值
2, 修改this指向- apply: obj.skill.apply(person) 传递参数- apply: obj.skill.apply(person,[ 参数1,参数2 ])
const obj = {
name: '老王',
skill() {
console.log(this.name + ' 翻墙');
},
};
const person = {
name: '大郎',
};
// apply 方式来修改this的指向
obj.skill.apply(person); // 大郎 借用老王的方法
const obj = {
name: '老王',
skill(a, b) {
console.log(this.name + ' ' + a + ' ' + b);
},
};
const person = {
name: '大郎',
};
obj.skill.apply(person, [1, 2]); // 数组
3, 修改this指向-const func = obj.skill.bind(person); func();
const obj = {
name: '老王',
skill() {
console.log(this.name + ' 翻墙');
},
};
const person = {
name: '大郎',
};
const func = obj.skill.bind(person);
func(); //大郎 调用老王的方法
3.1 传递参数 const func = obj.skill.bind(person); func(参数1,参数2)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no"
/>
<title>04-bind-call-apply修改this指向.html</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
</style>
</head>
<body>
<script>
/*
1 传递参数的时候不同写法上 (下一节课再来讲解)
*/
const obj = {
name: '老王',
skill(a, b) {
console.log(this.name + ' ' + a + ' ' + b);
},
};
const person = {
name: '大郎',
};
// obj.skill.call(person,1,2);// 传参
// obj.skill.apply(person, [1, 2]); // 数组
// apply 方法计算
// 在早些时候 我们是这样来计算 数组最大值和最小值
// 借用 Math.max方法 目的不是修改this指向
// 而是 计算数组最大值
// const arr=[1,2,3,4];
// const max = Math.max.apply(null,arr); //最大值
// const min = Math.min.apply(null,arr); //最小值
// 这种 是 es6 主流的 常用方法 call方法
// const arr=[1,2,3,4];
// console.log(Math.max(...arr));
// console.log(Math.min(...arr));
const func=obj.skill.bind(person);
func(1,2);
/*
1 bind call apply 都可以实现修改this指向
2 代码写法上有区别
1 obj.skill.call(person);
2 obj.skill.apply(person);
3 const func = obj.skill.bind(person);
func();
3 传递参数
1 obj.skill.call(person,参数1,参数2)
2 obj.skill.apply(person,[参数1,参数2])
3 const func = obj.skill.bind(person);
func(参数1,参数2)
*/
</script>
</body>
</html>
箭头函数-this的指向
大部分情况,对于普通函数,this等于这个函数的调用者 ( 例外 - bind, call, apply )
大部分情况,对于箭头函数,this等于window
箭头函数和this 一起用得话,要慎用!!! 例外 ( 面向对象用法 )
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no"
/>
<title>06-箭头函数-this指向.html</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
</style>
</head>
<body>
<button>点击我 我就改变颜色</button>
<script>
// 在js中,顶级的对象 就是window
// 定义一个函数 形式是箭头函数的
// const func = () => {
// console.log(this);
// };
// func(); //window
// const obj = {
// name: '悟空',
// say: () => {
// console.log(this);
// },
// };
// obj.say(); // window
// const obj1 = {
// name: '悟空1',
// obj2: {
// name: '悟空2',
// say: () => {
// console.log(this);
// },
// },
// };
// obj1.obj2.say();//window
const button = document.querySelector('button');
button.addEventListener('click', function () {
console.log(this); // this = button
});
button.addEventListener('click', ()=> {
console.log(this);// this = window
});
/*
大部分情况,对于普通函数,this 等于这个函数的调用者
(例外 - bind、call、apply)
大部分情况,对于箭头函数,this 等于window
箭头函数和this 一起用的话,要慎用!!
例外(面向对象用法,)
*/
</script>
</body>
</html>
es6 的面向对象 - class
语法:
class Person {
可以在这直接声明属性如:
username='小米'
和在下面 this.username='小米' 是等价的
// constructor 会在 new Person的时候触发
constructor(name) {
// console.log("开始创建对象啦");
this.name = name;
}
// 直接写行为 而且可以写多个方法
say() {
console.log('say方法被调用啦 ' + this.name);
}
fly() {
console.log('会飞');
}
sing() {
console.log('唱歌');
}
}
// es6 面向对象 引出新的语法 类 class
class Person {
// 方法 constructor 在es6 构造函数
// constructor 会在 new Person的时候触发
constructor(name) {
// console.log("开始创建对象啦");
this.name = name;
}
// 直接写行为
say() {
console.log("say方法被调用啦 " + this.name);
}
fly() {
console.log("会飞");
}
sing() {
console.log("唱歌");
}
}
// 一样new一个对象
const p1 = new Person("悟空1");
const p2 = new Person("悟空2");
// console.log(p1);
p1.say();
console.log(p1.say === p2.say); //true 共用一个方法 节省性能
es6的继承-calss
语法: 子类 extend 父类 这是固定写法 这只是继承父类的方法
容易出错的 写了 extends 和 constructor 没写 super() Must call super constructor in derived class before accessing 'this' or returning from derived constructor 1 如果你写了 extends 而且还写了 constructor 那你必须要在 constructor 调用了方法 super(); 2 如果你只写了 extends 但是你没有写constructor 不需要管super
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0,maximum-scale=1,minimum-scale=1,user-scalable=no"
/>
<title>10-es6-继承.html</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
</style>
</head>
<body>
<script>
//父亲
class Person {
constructor(name) {
this.name = name;
}
say() {
console.log("say方法我调用啦 " + this.name);
}
fly() {
console.log("父亲的起飞");
}
}
//学生
// 表示学生要继承父亲
// extends 直接就实现了继承父亲的方法
class Student extends Person {
//
constructor(name, color) {
super(name); // 父亲的构造函数 =es5 Person.call(this,name);
this.color = color;
}
// fly(){
// console.log("儿子 起飞");
// }
// fly = null; // 用儿子的新的null 去覆盖父亲的fly没有父亲的fly
}
const s1 = new Student("学生", "red");
s1.say();
s1.fly();
/*
容易出错的 写了 extends 和 constructor 没写 super()
Must call super constructor in derived class before accessing 'this' or returning from derived constructor
1 如果你写了 extends 而且还写了 constructor 那你必须要在 constructor 调用了方法 super();
2 如果你只写了 extends 但是你没有写constructor 不需要管super
extends 是继承方法 super() 是继承属性 一般配合使用
继承要继承父亲的属性和父亲的行为
1 只实现了继承父亲的行为 还没有实现继承父亲的属性 (super 表示可以继承父亲的属性)
*/
</script>
</body>
</html>
es6继承
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<script>
//父类 选择器selecto
class Element {
constructor(selecto) {
let dom = document.createElement(selecto);
this.dom = dom;
}
append(personSelecto) {
//方法插入
document.querySelector(personSelecto).appendChild(this.dom);
}
}
// 子 继承
class DivElement extends Element {
constructor(selecto, text) {
super(selecto);
this.dom.innerText = text;
}
}
class ImgElement extends Element {
constructor(selecto, src) {
super(selecto);
this.dom.src = src;
}
}
const divModel = new DivElement("div", "这是div里的文字");
const imgModel = new ImgElement("img", "./images/s_10.jpg");
divModel.append("body");
imgModel.append("body");
</script>
</body>
</html>
三种定义方法的写法-最优
class Preson {
//性能最好
say1() {
console.log("say1");
}
say2 = function () {
console.log("say2");
};
say3 = () => {
console.log("say3");
};
}
const p1 = new Preson();
const p2 = new Preson();
console.log(p1.say1 === p2.say1); // true p1 和 p2 say1方法是同一个-节省内存
console.log(p1.say2 === p2.say2); // false p1 和 p2 say2方法不是同一个-性能不好
console.log(p1.say3 === p2.say3); // false p1 和 p2 say3方法不是同一个-性能不好
es5-原型链
原型链:
一个对象 它可以通过 prototype 来 找到被它继承父亲的方法
如果一个对象从底层触发 可以通过 prototype 一层一层往上找到 继承的关系 = 原型链
作用:
1 如果我需要给 某个数据 (字符串、数组、对象) 统一添加一个方法 ,可以直接在原型上添加
2 初学者 不要乱在原型上定义方法 - 影响巨大
// 1 创建数组的方式 有两种
// const arr = ['a', 'b', 'c']; // 字面量 常用-直接和简单的写法
// 2 数组 也是可以被new
// const arr = new Array('a', 'b', 'c');
// console.log(arr);
function Person() {}
const p1 = new Person();
// 在 Person的原型上添加一个方法
Person.prototype.show = function () {
console.log('自己添加的方法');
};
// p1.show();
// 给js内置的Array数据 原型也添加一个方法试试
Array.prototype.show = function () {
console.log('自定义的数组方法');
};
const arr = new Array('a', 'b', 'c');
// const arr = ['a', 'b', 'c'];
// arr.show();
// 利用原型对象的方式,在任意的构造函数上添加想要的行为
// 任意的构造函数 包括 自己定义的构造函数
// 也包括 js中 -内置就有的构造函数 Array
// arr.forEach
// arr.push()
// arr.map()
// arr.filter
// 对象的创建也分两种清空
// const ojb={};// 字面量 常用 直接 简单
const obj = new Object(); // 利用构造函数的方式来创建对象
Object.prototype.show = function () {
console.log('对象 自己的show方法');
};
obj.show();
万物皆对象
利用原型对象的方式,在任意的构造函数上添加想要的行为任意的构造函数, 包括 自己定义的构造函数,也包括 js中 -内置就有的构造函数 Array数组,标签 都可以利用原型对象的方式 添加自己想要的行为
/*
原型链
一个对象 它可以通过 prototype 来 找到被它继承父亲的方法
如果一个对象从底层触发 可以通过 prototype 一层一层往上找到 继承的关系 = 原型链
// 作用
1 如果我需要给 某个数据 (字符串、数组、对象) 统一添加一个方法 ,可以直接在原型上添加
2 初学者 不要乱在原型上定义方法 - 影响巨大
*/
// const obj = {
// username: '悟空',
// say() {
// console.log('这个是say方法');
// },
// };
// // 万物皆对象
// Object.prototype.show = function () {
// console.log('这个是原型上的show方法');
// };
// // 你看要 dom对象 大哥大
// console.dir(document.querySelector("div"));
// const arr = [];
// console.log(arr);
// arr.show();
// console.log();
// Math.show()
// const str="123";
// console.dir(str.show);
// str.show();
// console.log(obj);// 直接看到定义在自己身上的属性和方法 看不见定义在 原型对象上的属性和方法
// console.log([]);
// const arr=[];
// arr.push
// console.log(arr);
// obj.say();
// obj.show();
// const arr1=[];
// const arr2=[];
// const arr3=[];
Array.prototype.forEach=function(){
console.log("老子罢工了");
}
Array.prototype.map=function(){
console.log("老子罢工了");
}
const arr=[1,2,3];
arr.forEach(); // forEach 循环 到了你这个项目 这个知识用不了
// 对于新入门小小员工来说 毁灭性的打击
// 10多年代码 用不上 心态。。。。
// arr.map()// 以前我学都是啥 想不开 你要有责任!!