Js高级:
一.原型链继承:
利用代码的能力实现 面向对象的特性 封装 和 继承
<script>
function Person(name, age, height) {
this.username = name;
this.age = age;
this.height = height;
}
function Student(name, age, height, color) {
// 这一行代码解决了继承的问题!!
// call 借用别人的方法
// 谁有方法
// 谁想要借用person方法 this = 实例 = 下面代码的s1
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('奥特之父', 5000, 200);
const s1 = new Student('迪迦', 2000, 100, 'yellow');
// console.log(p1);
console.log(s1);
</script>
- 子类strudent 继承了父类 Person的属性
继承案例:
<script>
/*
封装 代码 实现以下的功能
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/b_01.jpg');
imgModel.append('div');
// 如果代码重复实现了 很有可能就是我们要封装的时候
// 以前的封装 仅仅是封装一个小小的函数而已
// 现在的封装, 面相对象的思维来封装
// 封装 属性 父亲
// 封装 方法 父亲
// 两个儿子的代码 有重复部分
// 创建标签重复 this.dom=dom append方法也重复
// 儿子1 有要什么功能
// 先复用父亲的属性和方法
</script>
方法借用模式:call
call方法可以调用一个函数,并且可以指定这个函数的 this 指向
<script>
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); // obj 有没有 username属性(不用管属性值)、有没有age属性(不用属性值)
// 可以实现 了 一个空对象 obj 通过call的使用 来实现了 借别人的方法add 来给obj添加新的属性
</script>
二.es6(重点):
<script>
// 目前浏览器 支持的js的代码版本
// 主要都支持 es5 (for if while 函数 forEach ) 版本
// 新的语法 es6 (提供了更加简单强大的代码更能力) 提高我们的开发效率
// 常用 重要的部分
// 如果大家有空 了解全部 阮一峰
// 体验一下
// 交换
let a = 1;
let b = 2;
// 交换两个值
[a, b] = [b, a];
console.log(a, b);
// let c = a;
// a = b;
// b = c;
// console.log(a, b);
</script>
函数参数默认值:
定义函数的同时,可以给形参一个默认值
<script>
// 定义函数的同时,可以给形参一个默认值
function show(msg = '大家一起快活呀') {
console.log(msg);
}
show() // 打印 大家一起快活呀
show('搞笑不') // 打印 搞笑不
</script>
对象简写:
在定义对象的时候,如果属性名和变量名一直,那么可以实现简写
<script>
// 简写 如果变量的名字和属性的名字 一致的话,对象可以简写
// 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");
},// 常规写法
// es6 关于 方法简写
say() {
console.log("say");
} // es6 关于 方法简写
}
person.show();
person.say();
/*
小结:
1 变量名如果和你的对象的属性名一致 可以简写
let username='悟空'
const obj = { username }
2 对象的方法 简写
const obj ={
say(){ // 简写的方法
}
}
*/
</script>
三.解构:
提供更加方便获取数组中元素或者对象中属性的写法
获取数组中的元素:
<script>
const [a, b, c, d] = [0, 1, 2, 3]
console.log(a, b, c, d);//0,1,2,3
</script>
元素交互顺序:
<script>
let a = 1111;
let b = 2222;
[b, a] = [a, b];
console.log(a, b);// 2222 1111
</script>
获取对象中的属性(重点):
<script>
const obj = {
name: "悟空",
skill: '72变',
say() {
}
}
const { name, height, say } = obj;
console.log(name, height, say); //悟空,72变,function(){}
</script>
四.拓展运算符 || 剩余运算符:
通过 ...符号来获取剩下的参数
函数内获取:
<script>
function show(a, ...all) {
console.log(a);
console.log(all);
}
show(1) //a=1 all=[]
show(1, 2, 3) //a=1 all=[2,3]
</script>
数组内获取:
<script>
const [a, ...rest] = [1, 2, 3, 4, 5, 6]
console.log(a); //a=1
console.log(rest); //rest=[2,3,4,5,6]
</script>
对象内获取:
<script>
const obj = {
name: '悟空',
skill: '72变',
say() {
}
}
const { name, ...others } = obj
console.log(name) //悟空
console.log(others) //{skill:72变,say:f}
</script>
计算最大值:
<script>
// 计算最大值的写法
function getMax(...args) {
// args= 数组 接收 所有传递给 getMax方法的 参数
// console.log(args);
// 计算最大值 的
let max = args[0];
args.forEach((value) => {
if (value > max) {
max = value;
}
});
console.log(max);
}
getMax(1); //1
getMax(1, 2); //2
getMax(1, 2, 3); //3
getMax(11, 33, 2, 3); //33
</script>
拓展:
<script>
// 展开 ... 用法
const obj = {
username: '悟空',
height: 200,
};
// // 新创建一个对象 这个对象 具有 所有 obj的属性
// // 同时 还有多一个属性,color
// // const newObj = obj;// 对象是引用类型 写 = 将 obj的地址 给了一份 newObj 两个变量指向的地址同样的 同一个对象
// // newObj.color = 'yellow';
// // console.log("新的对象",newObj);
// // console.log("旧的对象",obj);
// // 建议这做 互补影响
// const newObj = { ...obj, color: 'yellow' }; // 给newObj 开辟新的内存空间
const newObj={ username:"悟空",height:20}; // 给newObj 开辟新的内存空间
newObj.username = '八戒';
newObj.weight = 100;
// console.log(obj);
console.log(newObj);
// 展开运算符 对数组操作
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 来实现
</script>
五.数组去重:
提示:方案中this.value等于input.value
方案一 some方法:
<input type="text">
<ul>
</ul>
<script>
let arr = ['1', '2']
const input = document.querySelector('input')
const ul = document.querySelector('ul')
gethtml()
input.addEventListener("keydown", function (event) {
if (event.key === 'Enter') {
// some 如果数组中有一项 是返回了true 整个some方法就返回了true
// 调用some方法的时候,在它的回调函数中 拿数组中的元素 和 当前要添加的元素 做比较 如果相等 就返回true 表示找到了重复
const isHas = arr.some((value) => value === this.value) // 在我的数组中找到了和你待添加的元素 一样的值 返回true
if (isHas) {
// 有重复了 不要再添加
alert('输入重复了')
}
else {
// 没有重复 你可以添加
// 把它添加到数组中
arr.push(this.value)
// 数组发生了改变 重新调用render方法 来实现页面的渲染
gethtml()
}
}
})
function gethtml() {
const html = arr.map((value) => `<li>${value}</li>`).join('')
ul.innerHTML = html
}
</script>
方案二 for循环 定一个变量,表示数组有没有重复的数据:
<input type="text">
<ul>
</ul>
<script>
let arr = ['1', '2']
const input = document.querySelector('input')
const ul = document.querySelector('ul')
gethtml()
input.addEventListener("keydown", function (event) {
// 定一个变量,表示数组有没有重复的数据
// 假设它 没有重复
let isHas = false
for (let index = 0; index < arr.length; index++) {
// 判断数组中的每一个元素 和 当前要输入的值做比较
// 如果找到了,设置 isHas=true 同时 打断循环
if (arr[index] === this.value) {
// 找到重复了
isHas = true
break
}
}
// 判断数据有没有重复
if (isHas) {
//有重复
console.log('重复');
} else {
// 没有重复 添加
arr.push(this.value)
gethtml()
}
})
function gethtml() {
const html = arr.map(value => `<li>${value}</li>`).join('')
ul.innerHTML = html
}
</script>
方案三 filter方法 :
<input type="text">
<ul>
</ul>
<script>
let arr = ['1', '2']
const input = document.querySelector('input')
const ul = document.querySelector('ul')
gethtml()
input.addEventListener("keydown", function (event) {
// filter 来解决
// filter 过滤
// 先过滤出 和当前的输入框的值 不相等的 数据
// 然后再添加
// 当前输入框的值 "d"
// 我数组 ['a','c','d']
// 数组过滤 不包含 "d" => ['a','c']
// ['a','c'] 再次添加 'd' 进去 就可以了
// 过滤出不包含 当前输入框的值的数组
let newArr = arr.filter(value => value !== this.value)
// 让我们的旧的数组 等于你过滤后的数组
arr = newArr
arr.push(this.value)
gethtml()
})
function gethtml() {
const html = arr.map(value => `<li>${value}</li>`).join('')
ul.innerHTML = html
}
</script>
方案四 声明一个变量 量等于数组没有的下标:let i = -1
<input type="text">
<ul>
</ul>
<script>
let arr = ['1', '2']
const input = document.querySelector('input')
const ul = document.querySelector('ul')
gethtml()
input.addEventListener("keydown", function (event) {
// this.value = "b"
// arr = ["a","b","c"]
// 先找到 “b” 在我数组的索引 位置
// 执行 数组 删除元素 arr = [a,c]
// 然后 再去执行 添加元素的操作
let i = -1 // -1 表示没有找到
for (let index = 0; index < arr.length; index++) {
if (arr[index] === this.value) {
i = index
break
}
}
// 判断 i 等于-1 表示没有相同,直接添加
// i 不等于-1 表示有相同,先执行删除 再添加
if (i === -1) {
} else {
// 找到相同 删除它
arr.splice(i, 1)
}
arr.push(this.value)
gethtml()
})
function gethtml() {
const html = arr.map(value => `<li>${value}</li>`).join('')
ul.innerHTML = html
}
</script>
其他方法 了解:
<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') {
// 数组去重 一堆方法
// for forEach some
// 没有细讲 indexOf find findIndex includes set every
// 没有足够的技术积累和代码量 优雅不起来!!
// indexOf find findIndex includes set
// const index=arr.indexOf(this.value);
const index=arr.findIndex(value=>value===this.value)
const item=arr.find(value=>value===this.value);
const isHas=arr.includes(this.value)
if(!isHas){
// 没有找到
arr.push(this.value);
render();
}
const set = new Set(arr);
set.add(this.value);
arr = [...set];
render();
}
});
function render() {
const html = arr.map((value) => `<li>${value}</li>`).join('');
ul.innerHTML = html;
}