前端小题(长期更新)

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实现双向绑定数据
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值