写的不好,如有问题的地方忘大家提出,互相学习,谢谢
数据去重的方法
let arr = [1, 3, 5, 7, 9, 2, 6, 1, 7, 9]
/*
使用indexOf方法
indexOf:在数组中查找某个元素,找到返回对应的下标,否则返回 -1 (在等于-1也就是未查找到元素的时候把该元素添加到新数组中去)
*/
function repeat(arr) {
var newArr = []
for (var i = 0; i < arr.length; i++) {
if (newArr.indexOf(arr[i]) === -1) {
newArr.push(arr[i])
}
}
return newArr
}
/*
使用ES6中的 Set() 方法
*/
function repeat(arr) {
return Array.from(new Set(arr));
}
/*
使用数组原型对象上的 forEach 和 includes方法
*/
function repeat(arr) {
let newArr = [];
arr.forEach(item => {
return newArr.includes(item) ? '' : newArr.push(item);
});
return newArr;
}
/*
使用数组原型对象上的includes方法
*/
function repeat(arr) {
var newArr = []
for (var i = 0; i < arr.length; i++) {
if (!newArr.includes(arr[i])) {
newArr.push(arr[i])
}
}
return newArr;
}
/*
使用对象属性的特性,没有该属性的时候存入新数组
*/
function repeat(arr) {
var obj = {}
var newArr = []
for (let i = 0; i < arr.length; i++) {
if (!obj[arr[i]]) {
obj[arr[i]] = 1
newArr.push(arr[i])
}
}
return newArr;
}
console.log(repeat(arr))
防抖
<!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>
<input type="button" value="防抖按钮">
</body>
</html>
<script>
const button = document.querySelector('input')
function antiShake() {
console.log('防抖')
}
function debounce(func, delay) {
let timer // 多个函数共用外部变量
return function () {
let _this = this // 在使用防抖函数时antiShake() this会指向window 在这里使用apply改变this指向input
let args = arguments // 增加参数
clearTimeout(timer)
timer = setTimeout(function () {
func.apply(_this, args)
}, delay)
}
}
button.addEventListener('click', debounce(antiShake, 2000))
</script>
节流
<!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>
节流:<input type="text">
</body>
</html>
<script>
const input = document.querySelector('input')
function getInputContent() {
console.log('当前输入的值:', input.value)
}
function throttle(func, delay) {
let timer
return function () {
let _this = this // 在使用防抖函数时antiShake() this会指向window 在这里使用apply改变this指向input
let args = arguments // 增加参数
if (timer) { // 如果timer为true也就是被赋值了(直接返回不执行任务)
return
}
// timer为false也就是没有被赋值或者任务已经结束了,那么就为timer赋值进行延迟执行,延迟执行以后清空timer的值,可以不使用clearTimeout直接清空timer的值就行了
timer = setTimeout(function () {
func.apply(_this, args)
timer = null
}, delay)
}
}
input.addEventListener('input', throttle(getInputContent, 2000))
</script>
冒泡排序
const arr = [122, 421, 32, 521, 3, 984, 53, 874]
function bubblingSort(arr) {
let temp;
for (let i = 0; i < arr.length - 1; i++) { // 确定循环的次数(重要的作用就是下一轮不会重复对比最后一个元素)
for (let j = 0; j < arr.length - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
temp = arr[j]
arr[j] = arr[j + 1]
arr[j + 1] = temp
}
}
}
return arr;
}
console.log(bubblingSort(arr))
二分查找数组下标
// 需要先将数组排序
const arr = [3, 32, 64, 88, 110, 143, 164, 185, 230, 289]
function searching(target) {
var start = 0, end = arr.length - 1, middle, element;
while (start <= end) {
middle = Math.floor((start + end) / 2)
element = arr[middle]
if (element === target) {
return middle
} else if (target < element) {
end = middle - 1
} else {
start = middle + 1
}
} return -1
}
console.log(searching(185))
二分数组排序
const arr = [110, 289, 3, 32, 64, 164, 88, 143, 185, 230]
function binarySorting(arr) {
if (arr.length == 0) {
return [];
}
var middle = Math.floor(arr.length / 2);
var c = arr.splice(middle, 1);
var left = [];
var right = [];
for (var i = 0; i < arr.length; i++) {
arr[i] < c ? left.push(arr[i]) : right.push(arr[i]);
}
return binarySorting(left).concat(c, binarySorting(right));
}
console.log(binarySorting(arr));
了解Promise
const isEmpower = true
const promise = new Promise((resolve, reject) => {
if (isEmpower) {
resolve('成功授权了') // 返回成功结果
} else {
reject('授权失败了') // 返回失败结果
}
})
promise.then(res => {
console.log(res) // 成功时的回掉
}).catch(res => {
console.log(res) // 失败时的回掉
}).finally(() => {
console.log('最终我还是访问了') // 无论成功还是失败都会执行
})
class类
这里只是一个简单的例子
深入了解请看 深入理解Javascript中的class类
<!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_1 {
border: none;
width: 100px;
height: 42px;
border-radius: 5px;
cursor: pointer;
color: #fff;
background-color: #409EFF;
}
</style>
</head>
<body>
<button class="button_1">一级</button>
</body>
<script>
// 拿到两个按钮
const button_1 = document.querySelector('.button_1');
// 创建 Speech class类
class Speech {
// 使用 constructor 初始化操作 (每次new的时候都会触发 constructor)
constructor(name, say) {
this.name = name;
this.say = say;
}
work() {
console.log(this.name, this.say)
}
}
button_1.addEventListener('click', () => {
const speech = new Speech('张三', '说,你是谁')
speech.work() // 调用 speech 的 work 方法
})
</script>
原生实现Call
// 原生实现call
// 先回顾一下call的用法
function person() {
console.log(this.name)
}
var people = {
name: '张三'
}
/**
* call是从哪里来的
* 在Javascript中每个函数其实都是Function对象
* 而Function则是构造函数,构造函数是有原型对象的,也就是Function.prototype
* Function.prototype中可以有很多属性可以使用,call就是从里面来的
* 因此我们需要在原型中添加新的call属性,call是一种属性也是一种方法,可以看到上面的例子调用call的时候加了括号
* 接下来我们为原型对象添加新的方法
*/
function person() { console.log(this.name) }
var people = { name: '张三' }
Function.prototype.newCall = function (obj) {
console.log(this)
}
person.newCall(people); // 这个时候newCall中输出的this是person
// 函数person开始进行调用然后执行newCall然后发现了this,因此需要绑定,person是真正调用的地方,this自然绑定到person
// 接下来我们来调整代码
Function.prototype.newCall = function (obj) {
// 为行参添加一个函数,并且吧this赋值给这个函数,然后在执行这个方法,相当于给对象添加了一个person函数,要记得讲这个函数删掉
// 因为我们不能改写了对象,现在执行就得到和call一样的方法了
obj.p = this
obj.p()
delete obj.p
}
person.newCall(people); // 输出:张三
// 到这里还没有结束,我们知道call第一个参数是this的指向,后面还可以有很多参数
function person(a, b, c, d) { // 这里的参数就是函数本身的参数了
console.log(this.name);
console.log(a, b, c, d); // undefined undefined undefined undefined 输出 undefined 肯定是不可行的
}
var people = { name: '张三' }
// 函数本身的参数是没有this的,我们需要吧所有的参数另外保存起来,并且不保留第一个this参数
// 要获取函数的参数需要用到arguments对象
Function.prototype.newCall = function (obj) {
obj.p = this
var newArguments = []
for (var i = 1; i < arguments.length; i++) {
newArguments.push(arguments[i])
}
console.log(newArguments) // 输出 ['a','b','c','d']
obj.p()
delete obj.p
}
person.newCall(people, 'a', 'b', 'c', 'd');
// 修改后代码 for 循环
function person(a, b, c, d) {
console.log(this.name); // 输出:张三
console.log(a, b, c, d); // 输出 a,b,c,d
}
var people = { name: '张三' }
Function.prototype.newCall = function (obj) {
obj.p = this
var newArguments = []
for (var i = 1; i < arguments.length; i++) {
newArguments.push('arguments[' + i + ']')
}
eval('obj.p(' + newArguments + ')')
delete obj.p
}
person.newCall(people, 'a', 'b', 'c', 'd');
// 这个时候如果我们吧people传入null就会出错
Function.prototype.newCall = function (obj) {
var obj = obj || window // 如果对象存在就不管,如果是null就指向window
obj.p = this
var newArguments = []
for (var i = 1; i < arguments.length; i++) {
newArguments.push('arguments[' + i + ']')
}
eval('obj.p(' + newArguments + ')')
delete obj.p
}
person.newCall(null, 'a', 'b', 'c', 'd'); // 修改obj对象,存在就忽略不存在就指向window
// 值的返回
function person(a, b, c, d) {
return {
name: this.name,
a: a, b: b, c: c, d: d
}
}
var people = { name: '张三' }
Function.prototype.newCall = function (obj) {
var obj = obj || window
obj.p = this
var newArguments = []
for (var i = 1; i < arguments.length; i++) {
newArguments.push('arguments[' + i + ']')
}
let result = eval('obj.p(' + newArguments + ')') // 保存到一个变量进行返回
delete obj.p
return result // 返回语句写在最后
}
var value = person.newCall(people, 'a', 'b', 'c', 'd');
console.log(value) // 输出 {name: '张三', a: 'a', b: 'b', c: 'c', d: 'd'}
原生实现apply
// 原生实现apply
// apply和call有一个重要的区别,就是参数都放在一个数组里
// 把上面实现call的思路拿过来
function person(a, b, c, d) {
console.log(this.name); // 输出:张三
console.log(a, b, c, d); // 输出:a,b,c,d
}
var people = { name: '张三' }
Function.prototype.newApply = function (obj, arr) {
var obj = obj || null;
obj.p = this
if (!arr) { // 先判断,如果没有输入数组就直接执行
obj.p()
} else { // 有参数时:和刚刚实现call的方法是类似的
var newArguments = []
for (var i = 0; i < arr.length; i++) {// 注意初始值 i = 0 因为要数组的所有元素
newArguments.push('arr[' + i + ']')
}
eval('obj.p(' + newArguments + ')')
}
delete obj.p
}
person.newApply(people, ['a', 'b', 'c', 'd']);
// 接下来说函数中返回对象的问题
function person(a, b, c, d) {
return {
name: this.name,
a: a, b: b, c: c, d: d
}
}
var people = { name: '张三' }
Function.prototype.newApply = function (obj, arr) {
var obj = obj || null;
var result; // 因为有if提前声明
obj.p = this
if (!arr) {
result = obj.p()
} else {
var newArguments = []
for (var i = 0; i < arr.length; i++) {
newArguments.push('arr[' + i + ']')
}
result = eval('obj.p(' + newArguments + ')')
}
delete obj.p
return result
}
var value = person.newApply(people, ['a', 'b', 'c', 'd']);
console.log(value) // 输出 {name: '张三', a: 'a', b: 'b', c: 'c', d: 'd'}