1.我们现在要实现一个红绿灯,把一个圆形 div 按照绿色 3 秒,黄色 1 秒,红色 2 秒循环改变背景色
function sleep(duration){
return new Promise(function(reslove){
setTimeont(reslove, duration)
})
}
async function changeColor(duration, color) {
documet.getElementById('light').style.background = color
await sleep(duration)
}
async function main() {
while(true) {
await changeColor(3000,"green");
await changeColor(1000, "yellow");
await changeColor(2000, "red");
}
}
2、找出整型数组中乘积最大的三个数
var unsorted_array = [-10, 7, 29, 30, 5, -10, -70];
computeProduct(unsorted_array)
function sortIntegers(a,b) {
return a - b
}
// 最大乘积场景 (min1 * min2 * max1 || max1 * max2 * max3)
function computeProduct(unsorted){
var sorted_array = unsorted.sort(sortIntegers),
pruduct1 = 1,
product2 = 2,
array_n_element = sorted_array.length - 1;
// max1 * max2 * max3
for (var x = array_n_element; x > array_n_element - 3; x--){
product1 = product1 * sorted_array[x]
}
//min1 * min2 * max1
product2 = sorted_array[0] * sorted_array[1] * sorted_array[2]
if (product1 > product2) return product1
return product2
}
3、寻找连续数组中的缺失数
tips:给定某个无序数组,其包含了n个连续数字中的n-1个,已知上下边界,要求以O(n)的复杂度找出缺失的数字
// The output of the function should be 8
var array_of_integers = [2, 5, 1, 4, 9, 6, 3, 7];
var upper_bound = 9;
var lower_bound = 1;
findMissingNumber(array_of_integers, upper_bound, lower_bound);
function findMissingNumber(array_of_integers, upper_bound, lower_bound){
// 已知数组的和
var sum_of_integers = 0;
for (var i = 0; i < array_of_integers; i++) {
sum_of_integers += array_of_integers[i]
}
// 使用高斯公式,计算“理论上的”数组和
// [(N * (N + 1)) / 2] - [(M * (M - 1)) / 2]; N,为最大数,M为最小
upper_limit_sum = (upper_bound * (upper_bound + 1)) / 2;
lower_limit_sum = (lower_bound * (lower_bound - 1)) / 2;
theoretical_sum = upper_limit_sum - lower_limit_sum;
return (theoretical_sum - sum_of_integers)
}
4、数组中元素最大差值计算
tips:给定某无序数组,求取任意两个元素之间的最大差值,注意,这里要求差值计算中较小的元素下标必须小于较大元素的下标。
譬如[7, 8, 4, 9, 9, 15, 3, 1, 10]这个数组的计算值是 11( 15 - 4 ) 而不是 14(15 - 1),因为 15 的下标小于 1。
var array = [7, 8, 4, 9, 9, 15, 3, 1, 10];
findLargestDifference(array);
function findLargestDifference(array) {
// 如果数组仅有一个元素,则直接返回 -1
if (array.length <= 1) return -1;
// current_min 指向当前的最小值
var current_min = array[0];
var current_max_difference = 0;
// 遍历整个数组以求取当前最大差值,如果发现某个最大差值,则将新的值覆盖 current_max_difference
// 同时也会追踪当前数组中的最小值,从而保证 `较小的元素下标必须小于较大元素的下标`。
for (var i = 1; i < array.length; i++) {
if (array[i] > current_min && (array[i] - current_min > current_max_difference)) {
current_max_difference = array[i] - current_min;
} else if (array[i] <= current_min) {
current_min = array[i];
}
}
// If negative or 0, there is no largest difference
if (current_max_difference <= 0) return -1;
return current_max_difference;
}
5、数组中元素乘积
tips:给定某无序数组,要求返回新数组 output ,其中 output[i] 为原数组中除了下标为 i 的元素之外的元素乘积,要求以 O(n) 复杂度实现:
var firstArray = [2, 2, 4, 1];
var secondArray = [0, 0, 0, 2];
var thirdArray = [-2, -2, -3, 2];
productExceptSelf(firstArray); // [8, 8, 4, 16]
productExceptSelf(secondArray); // [0, 0, 0, 0]
productExceptSelf(thirdArray); // [12, 12, 8, -12]
function productExceptSelf (numArray) {
var product = 1;
var size = numArray.length;
var output = [];
// product 原数组,0 ~index-1 的乘积
for (var x = 0; x < size; x++) {
output.push(product);
product = product * numArray[x];
}
// 入参为first array;output: [1, 2, 4, 16]
var product = 1;
// product 原数组,index ~0 的乘积
for (var i = size - 1; i > -1; i--) {
output[i] = output[i] * product
product = product * numArray[i]
}
return output
}
6、使用两个栈实现入队与出队
var inputStack = [];
var outputStack = [];
function enqueue(stackInput, item) {
return stackInput.push(item)
}
function dequeue(stackInput, stackOutput) {
if (stackOutput.length <= 0) {
while(stackInput.length > 0) {
var elementToOutput = stackInput.pop();
stackOutput.push(elementToOutput)
}
}
return stackOutput.pop()
}
7、判断大括号是否闭合
tips:每出现一个‘}’,就对应删除一个“{”,如果最后数组中长度大于0,则为false
var expression = "{{}}{}{}"
var expressionFalse = "{}{{}";
isBalanced(expression); // true
isBalanced(expressionFalse); // false
isBalanced(""); // true
function isBalanced (expression) {
var checkString = expression;
var stack = [];
if (checkString.length <= 0) return true;
for(var i = 0; i < checkString.length ; i++) {
if (checkString[i] === '{') {
stack.push(checkString[i])
} else if {
if (stack.length > 0) {
stack.pop()
} else {
return false
}
}
}
if(stack.pop()) return false
return true
}
8、二进制转换
tips:通过递归函数将输入的数字转化为二进制字符串
decimalToBinary(3); // 11
decimalToBinary(8); // 1000
decimalToBinary(1000); // 1111101000
function decimalToBinary(digit) {
if (digit >= 1) {
if (digit % 2){
return decimalToBinary((digit - 1) / 2) + 1
} else {
return decimalToBinary(digit/2) + 0
}
} else {
return ''
}
}
9、二分搜索
function recursiveBinarySearch(array, value, leftPosition, rightPosition) {
// Value DNE
if (leftPosition > rightPosition) return -1;
var middlePivot = Math.floor((leftPosition + rightPosition) / 2);
if (array[middlePivot] === value) {
return middlePivot;
} else if (array[middlePivot] > value) {
return recursiveBinarySearch(array, value, leftPosition, middlePivot - 1);
} else {
return recursiveBinarySearch(array, value, middlePivot + 1, rightPosition);
}
}
10、数组交集
普通数组
const arr1 = [1, 2, 3, 4, 5 , 8 ,9],
arr2 = [5, 6, 7, 8, 9];
const intersection = arr1.filter(function (val) {
return arr2.indexOf(val) > -1
})
数组对象
const arr1 = [{ name: 'name1', id: 1 }, { name: 'name2', id: 2 }, { name: 'name3', id: 3 }, { name: 'name5', id: 5 }];
const arr2 = [{ name: 'name1', id: 1 }, { name: 'name2', id: 2 }, { name: 'name3', id: 3 }, { name: 'name4', id: 4 }, { name: 'name5', id: 5 }];
const result = arr2.filter( function(v) {
return arr1.some(n => JSON.stringfy(n) === JSON.strongfy(v))
})
11、数组并集
普通数组
const arr1 = [1, 2, 3, 4, 5, 8, 9]
const arr2 = [5, 6, 7, 8, 9];
const result = arr1.concat(arr2.filter(v => !arr1.includes(v)))
数组对象
const arr1 = [{ name: 'name1', id: 1 }, { name: 'name2', id: 2 }, { name: 'name3', id: 3 }];
const arr2 = [{ name: 'name1', id: 1 }, { name: 'name4', id: 4 }, { name: 'name5', id: 5 }];
let arr3 = arr1.concat(arr2)
let result = []
let obj = [];
result = arr3.reduce( (prev, cur, index, arr) => {
obj[cur.id] ? '' : obj[cur.id] = true && prev.push[cur]
return prev
}, [])
12、数组差集
tips:数组arr1相对于数组arr2没有的
普通数组
const arr1 = [1, 2, 3, 4, 5, 8, 9]
const arr2 = [5, 6, 7, 8, 9];
const diff = arr1.filter(item => !new Set(arr2).has(item)})
数组对象
let arr1 = [{ name: 'name1', id: 1 }, { name: 'name2', id: 2 }, { name: 'name3', id: 3 }];
let arr2 = [{ name: 'name1', id: 1 }, { name: 'name4', id: 4 }, { name: 'name5', id: 5 }];
let result = arr1.filter( v => {
return arr2.every( n => JSON.stringfy(n) !== JSON.stringfy(v))
})
13、数组去重
数组对象
const arr = [{ name: 'name1', id: 1 }, { name: 'name2', id: 2 }, { name: 'name3', id: 3 }, { name: 'name1', id: 1 }, { name: 'name4', id: 4 }, { name: 'name5', id: 5 }];
const result = [];
arr.forEach( item => {
!result.some(v => JSON.stringfy(v) === JSON.stringfy(v)) && result.push(item)
})
14、数组求和
普通数组
[1, 2, 3, 4].reduce((prev, cur) => {
return prev + cur
}, 0)
数组对象
const sum = [{age:1},{age:2}].reduce(function (prev, cur) {
return prev + cur.age;
}, 0) //3
15、数组转对象
const arrName = ['张三', '李四', '王五']
const arrAge=['20','30','40']
const arrDec = ['描述1', '描述2', '描述3'
const obj = arrName.map( (item, index) => {
return { name: item, age: arrAge[index], dec:arrDec[index]}
})
16、对象多余属性删除
const { name, age, ...obj } = { name: '张三', age: 13, dec: '描述1', info: '信息' }
console.log(name) // 张三
console.log(age) // 13
console.log(obj) // {dec: '描述1', info: '信息' }
17、拦截对象
利用Object.defineProperty拦截对象,无法拦截数组的值
let obj = [ name:'', age:'', sex:'']
let defaultName = ["这是姓名默认值1", "这是年龄默认值1", "这是性别默认值1"];
Object.keys(obj).forEach(key => {
Object.defineProperty(obj, key, {
get() {
return defaultName; // get获取当前值
},
set(value) {
defaultName = value // set设置值
}
})
})
console.log(obj.name); // [ '这是姓名默认值1', '这是年龄默认值1', '这是性别默认值1' ]
console.log(obj.age); // [ '这是姓名默认值1', '这是年龄默认值1', '这是性别默认值1' ]
console.log(obj.sex); // [ '这是姓名默认值1', '这是年龄默认值1', '这是性别默认值1' ]
obj.name = "这是改变值1";
console.log(obj.name); // 这是改变值1
console.log(obj.age); // 这是改变值1
console.log(obj.sex); // 这是改变值1
let objOne = {}, defaultNameOne = '这是默认值2'
Object.defineProperty(obj, 'name', {
get() {
return defaultNameOne;
},
set(value) {
defaultNameOne = value;
}
});
console.log(objOne.name); // undefined
objOne.name = "这是改变值2";
console.log(objOne.name); // 这是改变值2
利用proxy拦截对象
let obj = { name: '', age: '', sex: '' }
let handler = {
get (target, key, receiver) {
console.log('get', key)
return Reflect.get(target, key, receiver)
},
set (target, key, value, receiver) {
console.log("set", key, value); // set name 李四 // set age 24
return Reflect.set(target, key, value, receiver)
}
}
let proxy = new Proxy(obj, handler)
console.log(proxy.name) // get name
proxy.name = '李四'
proxy.age = 24
defineProterty和proxy的对比:
1.defineProperty是es5的标准,proxy是es6的标准
2.proxy可以监听到数组索引值,改变数组长度的变化
3.proxy是监听对象,不用深层遍历,defineProperty是监听属性
4.利用defineProperty实现双向绑定数据