学习ES6-三
42.利用数组查询商品
<div class="search">
按照价格查询:
<input type="text" class="start">--<input type="text" class="end">
<button class="search-price">搜索</button>
按照商品名称查询:<input type="text" class="product">
<button class="search-pro">查询</button>
</div>
<table>
<thread>
<tr>
<th>id</th>
<th>产品名称</th>
<th>价格</th>
</tr>
</thread>
<tbody>
<!--
<tr>
<td>1</td>
<td>小米</td>
<td>3999</td>
</tr>
<tr>
<td>2</td>
<td>oppo</td>
<td>999</td>
</tr>
<tr>
<td>3</td>
<td>荣耀</td>
<td>1299</td>
</tr>
<tr>
<td>4</td>
<td>华为</td>
<td>1999</td>
</tr>
-->
</tbody>
</table>
<script>
//利用新增数组方法操作数据
var data=[
{
id:1,
pname:'小米',
price:3999
},
{
id:2,
pname:'oppo',
price:999
},
{
id:3,
pname:'荣耀',
price:1299
},
{
id:4,
pname:'华为',
price:1999
},
]
//1.获取相应的元素
var tbody=document.querySelector('tbody');
var search_price=document.querySelector(".search-price");
var start=document.querySelector(".start");
var end=document.querySelector(".end");
var product=document.querySelector(".product");
var search_pro=document.querySelector(".search-pro")
setData(data)
//2.把数据渲染到页面中
function setData(myData){
//先清空原来tbody里面的数据
tbody.innerHTML='';
myData.forEach(function(value){
//console.log(value);
var tr=document.createElement('tr');
// tr.innerHTML='<td>1</td><td>1</td><td>1</td>';
tr.innerHTML=`<td>${value.id}</td><td>${value.pname}</td><td>${value.price}</td>`
tbody.appendChild(tr);
})
}
//3、根据价格查询商品
//当我们点击了按钮,就可以根据我们的商品价格去筛选数组里面的对象
search_price.addEventListener('click',function(){
//alert('111')
var newData =data.filter(function(value){
return value.price>=start.value && value.price<=end.value;
});
console.log(newData)
//把筛选完之后的对象渲染到页面中
setData(newData) ;
})
//4.根据商品名称查找商品
//如果查询数组中唯一的元素,用some方法更合适,因为他找到这个元素,就不再进行循环,效率更高
search_pro.addEventListener('click',function(){
var arr=[];
data.some(function(value){
if(value.pname===product.value){
//console.log(value);
arr.push(value);
return true;//后面必须写true
}
});
//把拿到的数据渲染到页面中
setData(arr);
})
</script>
43.forEach和some区别
<script>
var arr=['red','green','blue','pink'];
//1.forEach迭代 遍历
//如果查询数组中唯一的元素,用some方法更合适
// arr.some(function(value){
// if(value==='green'){
// console.log('找到了该元素')
// return true;//在some里面,遇到return true 就会终止遍历 迭代效率更高
// }
// console.log(111)
// })
arr.filter(function(value){
if(value==='green'){
console.log('找到了该元素')
return true;//filter里面 return 不会终止迭代
}
console.log(111)
})
// arr.forEach(function(value){
// if(value==='green'){
// console.log('找到了该元素')
// return true;//在forEach里面,不会终止return 迭代
// }
// console.log(111)
// })
</script>
44.trim去除两侧空格
<input type="text">
<button>点击</button>
<div></div>
<script>
//trim方法去除字符串两侧孔哥哥
var str=' andy ';
console.log(str);
var str1=str.trim()
console.log(str1)
var input=document.querySelector('input')
var btn=document.querySelector('button');
var div=document.querySelector('div')
btn.onclick=function(){
var str=input.value.trim();
if(str===''){
alert('请输入内容');
}else{
console.log(str);
console.log(str.length);
div.innerHTML=str;
}
}
</script>
45-Object.keys遍历对象属性
<script>
//用于获取对象自身所有的属性
var obj={
id:1,
pname:'小米',
price:1999,
num:2000
};
var arr=Object.keys(obj);
console.log(arr);
arr.forEach(function(value){
console.log(value)
})
</script>
46-Object.defineProperty属性
<!--
3.4对象方法
2.Object.defineProperty0定义新属性或修改原有的属性。
object.defineproperty(obj, (prop, descriptor)
Object.definePropertyO第三个参数descriptor说明:以对象形式{}书写
● value:设置属性的值默认为undefined
● writable:值是否可以重写。true| false 默认为false
enumerable:目标属性是否可以被枚举。true| false 默认为false
·
● configurable:目标属性是否可以被删除或是否可以再次修改特性true| false 默认为false
-->
<script>
//Object.defineProperty()定义新属性或修改原有的属性
var obj={
id:1,
pname:'小米',
price:1999
};
//1.以前的对象添加和修改属性的形式
// obj.num=1000;
// obj.price=99;
// console.log(obj)
//2.Object.defineProtoperty()定义新属性或修改原有的属性
Object.defineProperty(obj,'num',{
value:1000
});
console.log(obj);
Object.defineProperty(obj,'price',{
value:9.9
});
console.log(obj);
Object.defineProperty(obj,'id',{
//如果只为false 不允许修改这个属性值 默认值也是false
writable:false
});
obj.id=2;
console.log(obj);
Object.defineProperty(obj,'address',{
value:"中国山东蓝翔技校xx单元",
//如果只为false 不允许修改这个属性值 默认值也是false
writtable:false,
//enumerable如果值为false则不允许遍历,默认的值是false
enumerable:false,
//configurable如果为false 则不允许删除这个属性 默认为false
configurable:false
});
console.log(obj);
console.log(Object.keys(obj));
delete obj.address;
console.log(obj)
delete obj.pname;
console.log(obj)
</script>
47-函数的定义和调用方式
<script>
//函数的定义方式
//1.自定义函数(命名函数)
function fn(){};
//2.函数表达式(匿名函数)
var fun=function(){};
//3.利用 new Function('参数1','参数2','函数体');
var f=new Function('a','b','console.log(a+b)')
f(2,5)
//4.所有函数都是Function的实例(对象)
console.dir(f);
console.log(f instanceof Object);
</script>
48-函数的调用
<script>
//函数调用方式
//1.普通函数调用
function fn(){
console.log("人生的巅峰")
}
//fn(); fn.call()
//2.对象的方法
var o={
sayHi:function(){
console.log('人生的巅峰');
}
}
o.sayHi();
// 3.构造函数
function Star(){};
new Star();
// 4.绑定事件函数
//btn.onclick=function(){};//点击了按钮就可以调用这个函数
// 5.定时器函数
//setInterval(function(){},1000);这个函数是定时器自动1秒钟调用一次
// 6.立即执行函数
(function(){
console.log('人生的巅峰');
})()
//立即执行函数是自动调用函数
</script>
49-this指向
<!--
2.1函数内 this 的指向
这些this的指向,是当我们调用函数的时候确定的。调用方式的不同决定了this的指向不同
一般指向我们的调用者。
调用方式 this指向
普通函数调用 window
构造函数调用 实例对象 原型对象里面的方法也指向实例对象
对象方法调用 该方法所属对象
事件绑定方法 绑定事件对象
定时器函数 window
立即执行函数 window
-->
<button>点击</button>
<script>
//函数的不同调用方式决定了this 的指向不同
//1.普通函数调用 this 指向window
function fn(){
console.log("普通函数的this"+this);
}
window.fn();
//fn.call()
//2.对象的方法 this 指向对象o
// var o={
// sayHi:function(){
// console.log('对象函数的this'+this);
// }
// }
// o.sayHi();
// 3.构造函数 this 指向ldh 这个实例对象 原型对象里面的this 指向的也是 ldh这个实例对象
function Star(){};
Star.prototype.sing=function(){};
var ldh=new Star();
// 4.绑定事件函数 this 指向的是函数的调用者 btn 这个按钮对象
var btn=document.querySelector('button');
btn.onclick=function(){
console.log('绑定点击事件函数的this'+this);
};//点击了按钮就可以调用这个函数
// 5.定时器函数 this 指向的也是window
window.setTimeout(function(){
console.log('定时器的this:'+this);
},1000);//这个函数是定时器自动1秒钟调用一次
// 6.立即执行函数 this还是指向window
(function(){
console.log('立即执行函数的this'+this);
})()
//立即执行函数是自动调用函数
</script>
50.改变函数内this指向
<script>
//改变函数内this指向 js提供了三种方法 call() apply() bind()
//1.call()
var o={
name:'andy'
}
function fn(a,b){
console.log(this);
console.log(a+b);
};
fn.call(o,1,2);
//call 第一个可以调用函数 第二个可以改变函数内的this 指向
//call的主要作用可以实现继承
function Father(uname,age,sex){
this.uname=uname;
this.age=age;
this.sex=sex;
}
function Son(uname,age,sex){
Father.call(this,uname,age,sex);
}
var son=new Son('刘德华',18,'男');
console.log(son);
</script>
51.apply改变函数内this指向
<script>
//改变函数内this指向 js提供了三种方法 call() apply() bind()
var o={
name:'andy'
};
function fn(arr){
console.log(this);
console.log(arr);
}
fn.apply(o,['pink'])
//1.也是调用函数 第二个可以改变函数内部的this指向
//2.但是他的参数必须是数组(伪数组)
//3.apply的主要应用 比如说我们可以利用apply 借助于数学对象求最大值
//Math.max()
var arr=[1,22,3,56,34];
//var max=Math.max.apply(null,arr);
var max=Math.max.apply(Math,arr);
console.log(max)
</script>
52.class类constructor方法
<!--
constructor()方法是类的构造函数(默认方法),用于传递参数,返回实例对象,通过new命令生成对象实例时
自动调用该方法。如果没有显示定义,类内部会自动给我们创建一个constructor()
-->
<script>
// 1. 创建类 class 创建一个 明星类
class Star {
constructor(uname, age) {
this.uname = uname;
this.age = age;
}
}
// 2. 利用类创建对象 new
var ldh = new Star('刘德华', 18);
var zxy = new Star('张学友', 20);
console.log(ldh);
console.log(zxy);
//(1) 通过class 关键字创建类, 类名我们还是习惯性定义首字母大写
//(2) 类里面有个constructor 函数,可以接受传递过来的参数,同时返回实例对象
//(3) constructor 函数 只要 new 生成实例时,就会自动调用这个函数, 如果我们不写这个函数,类也会自动生成这个函数
//(4) 生成实例 new 不能省略
//(5) 最后注意语法规范, 创建类 类名后面不要加小括号,生成实例 类名后面加小括号, 构造函数不需要加function
</script>
53.class类添加方法
<script>
// 1. 创建类 class 创建一个 明星类
class Star {
// 类的共有属性放到 constructor 里面
constructor(uname, age) {
this.uname = uname;
this.age = age;
}
sing(song) {
// console.log('我唱歌');
console.log(this.uname + song);
}
}
// 2. 利用类创建对象 new
var ldh = new Star('刘德华', 18);
var zxy = new Star('张学友', 20);
console.log(ldh);
console.log(zxy);
// (1) 我们类里面所有的函数不需要写function
//(2) 多个函数方法之间不需要添加逗号分隔
ldh.sing('冰雨');
zxy.sing('李香兰');
</script>
54.继承-extends-super
<!--
1.extends关键字可以实现子类继承父类
2.super可以实现子类继承父类的方法和构造函数
-->
<script>
class Father{
constructor(x,y){
this.x=x;
this.y=y;
}
sum(){
console.log(this.x+this.y);
}
}
class Son extends Father{
constructor(x,y){
super(x,y);//调用了父类中的构造函数
}
}
var son=new Son(1,2);
var son2=new Son(11,22);
son.sum();
son2.sum();
</script>
55.super就近原则
<!--
super
1.super关键字可以调用父类普通函数和构造函数
2.继承中的属性或者方法查找原则四个字(就近原则)
-->
<script>
// super 关键字调用父类普通函数
class Father {
say() {
return '我是爸爸';
}
}
class Son extends Father {
say() {
// console.log('我是儿子');
console.log(super.say() + '的儿子');
// super.say() 就是调用父类中的普通函数 say()
}
}
var son = new Son();
son.say();
// 继承中的属性或者方法查找原则: 就近原则
// 1. 继承中,如果实例化子类输出一个方法,先看子类有没有这个方法,如果有就先执行子类的
// 2. 继承中,如果子类里面没有,就去查找父类有没有这个方法,如果有,就执行父类的这个方法(就近原则)
</script>
56.super必须放在子类之前调用
<script>
// 父类有加法方法
class Father {
constructor(x, y) {
this.x = x;
this.y = y;
}
sum() {
console.log(this.x + this.y);
}
}
// 子类继承父类加法方法 同时 扩展减法方法
class Son extends Father {
constructor(x, y) {
// 利用super 调用父类的构造函数
// super 必须在子类this之前调用
super(x, y);
this.x = x;
this.y = y;
}
subtract() {
console.log(this.x - this.y);
}
}
var son = new Son(5, 3);
son.subtract();
son.sum();
</script>
57.super调用注意事项二
<!--
super 必须放到子类this之前
三个注意点:
1.在ES6中类没有变量提升,所以必须先定义类,才能通过类实例化对象。
2.类里面的共有属性和方法一定要加this使用
3.类里面的this指向问题
4.constructor 里面的this指向实例对象方法里面的this 指向这个方法的调用者
-->
<button>点击</button>
<script>
var that;
var _that;
class Star{
// constructor 里面的this 指向的是 创建的实例对象
constructor(uname,age){
that=this;
console.log(this)
this.uname=uname;
this.age=age;
// this.sing();
this.btn=document.querySelector('button');
this.btn.onclick=this.sing;
}
sing(){
// 这个sing方法里面的this 指向的是 btn 这个按钮,因为这个按钮调用了这个函数
console.log(this);
console.log(that.uname)
}
dance(){
// 这个dance里面的this 指向的是实例对象 ldh 因为ldh 调用了这个函数
_that=this;
console.log(this);
}
}
var ldh=new Star('刘德华');
console.log(that===ldh)
ldh.dance();
console.log(_that===ldh);
// 1. 在 ES6 中类没有变量提升,所以必须先定义类,才能通过类实例化对象
// 2. 类里面的共有的属性和方法一定要加this使用.
</script>
58.TAB切换
<!--
面向对象版 tab栏切换
功能需求:
抽象对象:Tab对象
1.该对象具有切换功能
1.点击tab栏可以切换效果。
2.点击+号,可以添加tab项和内容项
2.该对象具有添加功能
3.点击x号,可以删除当前的tab项和内容项。
3.该对象具有删除功能
4.双击tab项文字或者内容项文字,可以和改望面的文内春。
4.该对象具有修改功能
面向对象版tab栏切换:添加功能
1.点击+可以实现添加新的选项卡和内容
2.第一步:创建新的选项卡li和新的内容section
3.第二步:把创建的两个元素追加到对应的父元素中。
4.以前的做法:动态创建元素createElement,但是元素里面内容较多,需要innerHTML赋值,在appendChild
追加到父元素里面.
5.现在高级做法:利用insertAdjacentHTML(0可以直接把字符串格式元素添加到父元素中
6.appendChild不支持追加字符串的子元素,insertAdjacentHTML支持追加字符串的元素
面向对象版tab栏切换删除功能
1.点击×可以删除当前的li选项卡和当前的section
2.X是没有索引号的,但是它的父亲li有索引号,这个索引号正是我们想要的索引号
3.所以核心思路是:点击x号可以删除这个索引号对应的li和section
面向对象版tab栏切换编辑功能
1.双击选项卡li或者section里面的文字,可以实现修改功能
2.双击事件是:ondblclick
3.如果双击文字,会默认选定文字,此时需要双击禁止选中文字
4. window.getSelection? window.getSelection0.removeAllRanges0:document.selection.empty0;
5.核心思路:双击文字的时候,在里面生成一个文本框,当失去焦点或者按下回车然后把文本框输入的值给原先
元素即可.
-->
<main>
<h4>
Js 面向对象 动态添加标签页
</h4>
<div class="tabsbox" id="tab">
<!-- tab 标签 -->
<nav class="fisrstnav">
<ul>
<li class="liactive"><span>测试1</span><span class="iconfont icon-guanbi"></span></li>
<li><span>测试2</span><span class="iconfont icon-guanbi"></span></li>
<li><span>测试3</span><span class="iconfont icon-guanbi"></span></li>
</ul>
<div class="tabadd">
<span>+</span>
</div>
</nav>
<!-- tab 内容 -->
<div class="tabscon">
<section class="conactive">测试1</section>
<section>测试2</section>
<section>测试3</section>
</div>
</div>
</main>
<script src="js/tab.js"></script>
59.bind基本使用
<button>点击</button><button>点击</button><button>点击</button>
<script>
//3.bind()绑定 捆绑的意思
var o={
name:'andy'
};
function fn(a,b){
console.log(this)
console.log(a+b)
}
var f=fn.bind(o,1,3);
f()
//1.不会调用原来的函数 可以改变原来函数内部的this 指向
//2.返回的是原函数改变this之后产生的新函数
//3.如果有的函数我们不需要立即调用,但是又想改变这个函数内部的this指向此时用bind
//4.我们有一个按钮,当我们点击了之后,就禁用这个按钮,3秒之后开启这个按钮
// var btn=document.querySelector('button');
// var btn=document.getElementById("btn");
// btn.onclick=function(){
// this.disabled=true;//这个this 指向的是btn这个按钮
// //var that=this
// setTimeout(function(){
// // that.disabled=false;//定时器函数里面的this 指向的是window
// this.disabled=false;//此时定时器函数里面的this 指向的是btn
// }.bind(this),3000) ;//这个this 指向的是btn这个对象
// }
btns=document.querySelectorAll('button');
for(var i=0;i<btns.length;i++){
btns[i].onclick=function(){
this.disabled=true;
setTimeout(function(){
this.disabled=false;
}.bind(this),2000)
}
}
</script>
60.call apply bind总结
<!--
call apply bind总结
相同点:
都可以改变函数内部的this指向
区别点L:
1.call和apply会调用函数,并且改变函数内部this指向
2.call和apply传递的参数不一样,call传递参数aru1,aru2...形式 apply必须数组形式[arg]
3.bind不会调用函数,可以改变函数内部this指向
主要应用场景:
1.call经常做继承
2.apply经常跟数组有关系,比如借助于数学对象实现数组最大值最小值
3.bind不调用函数,但是还想改变this指向,比如改变定时器内部的this指向
-->
<script>
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现