01-this指向
<div class="box">box</div>
<script>
// 1.普通函数的this指向window
function fun() {
console.log(this);
}
fun();
// 2.对象中的this指向,指向向的是该对象
var obj = {
name: '张美丽',
sayHi: function() {
console.log(this);
}
};
obj.sayHi();
// 3.事件绑定中的this指向:该事件的绑定者
var box = document.querySelector('.box');
box.addEventListener('click', function() {
console.log(this);
});
// 4.构造函数的this指向:实例化对象
function Person(name, age) {
this.name = name;
this.age = age;
this.sayHi = function() {
console.log(this);
}
};
var p1 = new Person('wangsir', 20);
p1.sayHi();
// 5.定时器的this指向window
setTimeout(function() {
console.log(this);
}, 1000);
// 6.立即执行函数this指向也是window
(function() {
console.log(this);
})()
</script>
02-call()方法的使用
var obj = {
sign: 'huohua222'
};
function fun(num1, num2) {
console.log(this);
console.log(num1);
console.log(num2);
console.log(num1 + num2 + this.sign);
};
// fun(1,2);
// this指向的是对象o,参数使用逗号隔开,运行结果为3huohua222
// call():调用函数,改变this指向
fun.call(obj, 1, 2);
03-apply()方法的使用
var obj = {
sign: 'huohua222'
};
function fun(num1, num2) {
console.log(this);
console.log(num1);
console.log(num2);
console.log(num1 + num2 + this.sign);
};
// fun(1,2);
// this指向的是对象o,参数使用数组,运行结果为3huohua222
// apply():调用函数,改变this指向
fun.apply(obj, [1, 2]);
04-bind()方法的使用
var o = {
name: '小谷'
};
function fn(a, b) {
console.log(this);
console.log(a + b);
};
var f = fn.bind(o, 1, 2); //此处的f是bind返回的新函数
f();//调用新函数 this指向的是对象o 参数使用逗号隔开
05-总结改变this指向的方法
var obj = {
sign: 'huohua222'
};
function fun(num1, num2) {
console.log(this);
console.log(num1);
console.log(num2);
console.log(num1 + num2 + this.sign);
};
// - 共同点 : 都可以改变this指向
// - 不同点:
// - call和apply会立即调用函数.bind不会立即调用函数, 需要手动调用.
// - call及bind 和 apply传递的参数不一样,call和bind传递参数使用逗号隔开,apply使用数组传递.
fun.call(obj, 1, 2);
fun.apply(obj, [1, 2]);
fun.bind(obj, 1, 2)();
06-call()方法的应用-判断数据类型
var num = 10;
var str = 'Hello';
var flag = false;
var obj = {
name: '张美丽'
};
var arr = [1, 2, 3];
function fun() {
console.log('函数');
}
var date = new Date();
// 1.typeof基本数据类型
console.log(typeof num); //'number'
console.log(typeof NaN); //'number'
console.log(typeof str); //'string'
console.log(typeof flag); //'boolean'
console.log(typeof null); //'object'
console.log(typeof undefined); //'undefined'
console.log(typeof obj); //'object'
console.log(typeof arr); //'object'
console.log(typeof fun); //'function'
// 2.instanceof判断复杂数据类型的方法 true false
console.log(arr instanceof Array);
console.log(fun instanceof Function);
console.log(obj instanceof Object);
console.log('*******************');
console.log(arr instanceof Object);
console.log(fun instanceof Object);
// 3.call():使用原型的toString.call()方法进行判断数据类型
console.dir(Object);
console.log(Object.prototype.toString); //'[object Object]'
console.log(Object.prototype.toString()); //'[object Object]'
console.log(Object.prototype.toString.call(num)); //'[object Number]'
console.log(Object.prototype.toString.call(str)); //'[object String]'
console.log(Object.prototype.toString.call(flag)); //'[object Boolean]'
console.log(Object.prototype.toString.call(null)); //'[object Null]'
console.log(Object.prototype.toString.call(undefined)); //'[object Undefined]'
console.log(Object.prototype.toString.call(arr)); //'[object Array]'
console.log(Object.prototype.toString.call(fun)); //'[object Function]'
console.log(Object.prototype.toString.call(date)); //'[object Date]'
// 使用原型方式进行数据类型的判定
function dataType(data) {
var rel = Object.prototype.toString.call(data);
if (rel === '[object Null]') {
console.log('数据是Null类型');
} else if (rel === '[object Function]') {
console.log('数据是Function类型');
}
};
dataType(null);
07-apply()方法的应用-运用到数学方法
console.log(Math.max(2, 45, 23, 15, 87));
var arr = [2, 3, 34, 12, 67, 13, 45, 18, 56];
// 更方便传递参数
console.log(Math.max.apply(null, arr));
08-bind()方法的应用-定时器的this指向
<!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>
<style>
button {
border: 0;
width: 100px;
height: 50px;
color: #fff;
background-color: skyblue;
}
:disabled {
background-color: grey;
/* 鼠标禁用 */
cursor: not-allowed;
}
</style>
</head>
<body>
<button>等待N秒</button>
<button>等待N秒</button>
<button>等待N秒</button>
<button>等待N秒</button>
<button>等待N秒</button>
<script>
var btns = document.querySelectorAll('button');
// for (var i = 0; i < btns.length; i++) {
// btns[i].onclick = function() {
// var count = 5;
// // 改变样式
// this.innerText = '等待' + count + '秒';
// this.disabled = true;
// var that = this;
// this.interId = setInterval(function() {
// console.log(this);
// if (count == 0) {
// that.innerText = '等待N秒';
// that.disabled = false;
// clearInterval(that.interId);
// } else {
// count--;
// that.innerText = '等待' + count + '秒';
// }
// }, 1000);
// }
// };
// for (var i = 0; i < btns.length; i++) {
// btns[i].onclick = function(e) {
// var count = 5;
// // 改变样式
// this.innerText = '等待' + count + '秒';
// this.disabled = true;
// this.interId = setInterval(function() {
// console.log(e.target);
// if (count == 0) {
// e.target.innerText = '等待N秒';
// e.target.disabled = false;
// clearInterval(e.target.interId);
// } else {
// count--;
// e.target.innerText = '等待' + count + '秒';
// }
// }, 1000);
// }
// };
for (var i = 0; i < btns.length; i++) {
btns[i].onclick = function(e) {
var count = 5;
// 改变样式
this.innerText = '等待' + count + '秒';
this.disabled = true;
this.interId = setInterval(function() {
console.log(this);
if (count == 0) {
this.innerText = '等待N秒';
this.disabled = false;
clearInterval(this.interId);
} else {
count--;
this.innerText = '等待' + count + '秒';
}
}.bind(this), 1000);
}
};
</script>
</body>
</html>
09-construtor构造函数判断数据类型
var num = 10;
var str = 'Hello';
var flag = false;
var obj = {
name: '张美丽'
};
var arr = [1, 2, 3];
function fun() {
console.log('函数');
}
var date = new Date();
console.log(num.constructor);
console.log(NaN.constructor);
console.log(str.constructor);
console.log(flag.constructor);
console.log(obj.constructor);
console.log(arr.constructor);
console.log(fun.constructor);
console.log(date.constructor);
// console.log(null.constructor);
// console.log(undefined.constructor);
// 总结:通过constructor来判断数据的类型,但是除了null、undefined,
console.log(num.constructor == Number);
console.log(date.constructor == Date);
10-通过构造函数进行继承
// 父类构造函数
function Father(name, age) {
this.name = name;
this.age = age;
};
// 子类构造函数
function Son(name, age, height) {
// 构造函数继承
Father.call(this, name, age);
this.height = height;
};
var father = new Father('小头爸爸', 30);
var son = new Son('大头儿子', 5, 100);
console.log(father);
console.log(son);
11-原型链继承和构造函数继承结合
// 父类构造函数
function Father(name, age) {
this.name = name;
this.age = age;
};
// 父类中的方法
Father.prototype.makeMoney = function() {
console.log('挣钱');
};
// 子类构造函数
function Son(name, age, height) {
// 构造函数继承
Father.call(this, name, age);
this.height = height;
};
// 不能直接将Father的prototype赋值给son的prototype会导致影响父类的原型
// Son.prototype = Father.prototype;
// 可以使儿子拥有父类原型上的方法
Son.prototype = new Father();
// 由于Son的prototype上没有constructor构造函数指回Son
Son.prototype.constructor = Son;
// 添加子类的方法
Son.prototype.spend = function() {
console.log('花钱');
};
var father = new Father('小头爸爸', 30);
var son = new Son('大头儿子', 5, 100);
console.log(father);
console.log(son);
son.makeMoney();
son.spend();
12-Object.create()方法的作用
var obj = {
name: '张美丽'
};
var newObj = {
name: '王一茗',
age: 20,
sayHi: function() {
console.log('你好');
}
};
// Object.create():使用现有对象来提供新创建对象的__proto__
var rel1Obj = Object.create(obj);
var rel2Obj = Object.create(newObj, {
sex: {
value: '男',
configurable: true,
enumerable: true,
writable: true
}
});
console.log(rel1Obj);
console.log(rel2Obj);
13-使用Object.create()方法来实现继承
// 父类构造函数
function Father(name, age) {
this.name = name;
this.age = age;
};
// 父类中的方法
Father.prototype.makeMoney = function() {
console.log('挣钱');
};
// 子类构造函数
function Son(name, age, height) {
// 构造函数继承
Father.call(this, name, age);
this.height = height;
};
// Son.prototype = Father.prototype;
// 使用Object.create()方法实现继承
Son.prototype = Object.create(Father.prototype, {
constructor: {
value: Son,
configurable: true,
enumerable: true,
writable: true
},
spend: {
value: function() {
console.log('花钱');
},
configurable: true,
enumerable: true,
writable: true
}
});
// // 添加子类的方法
// Son.prototype.spend = function() {
// console.log('花钱');
// };
var father = new Father('小头爸爸', 30);
var son = new Son('大头儿子', 5, 100);
console.log(father);
console.log(son);
son.makeMoney();
son.spend();
14-数组的操作方法-forEach
var arr = ['a', 'b', 'c', 'd', 'e'];
// arr.forEach(function(value, index, array) {
// //参数一是:数组元素
// //参数二是:数组元素的索引
// //参数三是:当前的数组
// })
var rel = arr.forEach(function(value, index, array) {
console.log(value);
console.log(index);
console.log(array);
});
// forEach方法没有返回值
console.log(rel);
15-数组的操作方法-map
var arr = ['a', 'b', 'c', 'd', 'e'];
var rel = arr.map(function(value, index, array) {
console.log(value);
console.log(index);
console.log(array);
// 需要return结果通过操作的返回值进行接受
// map返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值
// return value + '操作后';
return '认真听';
});
console.log(rel);
16-forEach和map的区别
var arr = ['a', 'b', {
id: 's001',
name: 'momoko'
}, 'd', 'e'];
// 操作会直接修改数组
// arr.forEach(function(value, index, array) {
// console.log(this);
// if (value instanceof Object) {
// value.id = 'x001';
// }
// });
// console.log(arr);
arr.map(function(value, index, array) {
if (value instanceof Object) {
value.id = 'x001';
}
});
console.log(arr);
// 如果仅仅只是遍历,那么使用forEach
// 总结:
// 对数组中复杂数据类型的内容修改时会直接修改
// this:指向的window
// 如果仅仅只是遍历,那么使用forEach
17-数组的操作方法-filter
var arr = [12, 4, 23, 5, 87];
// filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。
var rel = arr.filter(function(value) {
console.log(value);
return value >= 20
});
console.log(rel);
18-数组的操作方法-some
// some 查找数组中是否有满足条件的元素 ,如果数组中有元素满足条件返回 true,否则返回 false。
// 只要查找到满足条件的一个元素就立马终止循环
var arr = [12, 4, 23, 5, 87];
var rel = arr.some(function(value) {
console.log(value);
return value >= 20;
});
console.log(rel);
19-数组的操作方法-every
// every() 方法用于检测数组所有元素是否都符合指定条件(通过函数提供)。返回true/false
// 只要查找到不满足条件的一个元素就立马终止循环
var arr = [12, 4, 23, 5, 87];
var rel = arr.every(function(value) {
console.log(value);
return value <= 20;
});
console.log(rel);
20-数组的操作方法-find
// find() 方法返回符合查找条件的第一个数组元素的值。
// 只要查找到满足条件的一个元素就立马终止循环
// 如果没有符合条件的元素返回 undefined
var arr = [12, 4, 23, 5, 87];
var rel = arr.find(function(value) {
console.log(value);
// return value >= 20;
return value >= 100;
});
console.log(rel);
21-数组的操作方法-reduce
// 定义了一个初始值(也可以直接在参数后面直接写)
const initialValue = 0;
// 定义了一个数组
const sum = [0,1,2,3,4,5,6];
// 开始循环计算
// 接收一个返回值
const sumTotal = sum.reduce(function(previousValue,currentValue){
return perviousValue + currentValue
},initialValue)
// 打印总和
console.log('sumTotal:' + sumTotal) // sumTotal:21
// 2.求最大值
var max = arr.reduce(function(total, value) {
console.log(value);
return Math.max(total, value)
});
console.log(max);
3.数组去重
var arrsp = [12, 34, 12, 12, 56, 67];
var newArr = arrsp.reduce(function(total, value) {
console.log(total);
if (!total.includes(value)) {
total.push(value);
};
// 然后将total值返回
return total;
}, []);
console.log(newArr);
作业
<style>
table {
width: 400px;
border: 1px solid #000;
border-collapse: collapse;
margin: 0 auto;
}
td,
th {
border: 1px solid #000;
text-align: center;
}
input {
width: 50px;
}
.search {
width: 600px;
margin: 20px auto;
}
</style>
</head>
<body>
<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>
<thead>
<tr>
<th>id</th>
<th>产品名称</th>
<th>价格</th>
</tr>
</thead>
<tbody>
<!-- <tr>
<td></td>
<td></td>
<td></td>
</tr> -->
</tbody>
</table>
<script>
// 利用新增数组方法操作数据
var data = [{
id: 1,
pname: '小米10',
price: 9899
}, {
id: 2,
pname: 'oppoA52',
price: 1299
}, {
id: 3,
pname: '荣耀10',
price: 1299
}, {
id: 4,
pname: '华为p20',
price: 2999
}, {
id: 5,
pname: '华为p30',
price: 3999
}, ];
// 1. 获取相应的元素
var tbody = document.querySelector('tbody');
var searchPriceBtn = document.querySelector('.search-price');
var start = document.querySelector('.start');
var end = document.querySelector('.end');
var product = document.querySelector('.product');
var searchProBtn = document.querySelector('.search-pro');
// 1.进入页面进行初始化页面数据
function showPage(data) {
var showData = '';
data.forEach(function(value) {
// showData += '<tr>';
// var tempData = '<td>' + value.id + '</td><td>' + value.pname + '</td><td>' + value.price + '</td>';
// // 添加到一起
// showData += tempData;
// showData += '</tr>';
// 模板字符串 `` ${}:包裹变量
var tempData = `
<tr>
<td>${value.id}</td>
<td>${value.pname}</td>
<td>${value.price}</td>
</tr>`
showData += tempData;
});
// 设置到页面
tbody.innerHTML = showData;
};
showPage(data);
// 2.根据价格进行搜索
// 对输入的内容进行左正则的替换
start.onkeyup = function() {
var str = start.value;
start.value = str.replace(/\D/, '');
};
// 价格搜索点击事件
searchPriceBtn.onclick = function() {
// 由于输入框的内容是字符串,需要转换数据类型
var startNum = Number(start.value);
var endNum = Number(end.value);
console.log(startNum);
console.log(endNum);
// 对输入的内容进行做判定
if (startNum == 0 && endNum == 0) {
showPage(data);
return;
};
if (startNum > endNum) {
alert('请输入有效的价格区间');
return;
};
// 过滤出符合价格区间的数据
var rel = data.filter(function(value) {
console.log(value);
var dataPrice = value.price;
return dataPrice >= startNum && dataPrice <= endNum;
});
if (rel.length == 0) {
alert('无此价格区间的商品');
showPage(data);
} else {
showPage(rel);
};
};
searchProBtn.onclick = function() {
var productName = product.value;
// 输入为空进行判定
if (productName == '') {
showPage(data);
return;
};
// 过滤出符合条件的数据
var rel = data.filter(function(value) {
return value.pname.includes(productName);
});
// 对最后的结果进行渲染页面
if (rel.length == 0) {
alert('无此名称商品');
showPage(data);
} else {
showPage(rel);
};
};
</script>