代码片段
深拷贝
js
// 一个简单的深拷贝函数,去掉了一些胶水部分
// 用户态输入一定是一个 Plain Object,并且所有 value 也是 Plain Object
function deepClone(obj) {
const keys = Object.keys(obj);
return keys.reduce((memo, current) => {
const value = obj[current];
if (typeof value === "object") {
return {
...memo,
[current]: deepClone(value)
};
}
return {
...memo,
[current]: value
};
}, {});
}
let a = {
val: 1,
desc: {
text: "a"
}
};
let b = deepClone(a);
b.val = 2;
console.log(a.val); // 1
console.log(b.val); // 2
b.desc.text = "b";
console.log(a.desc.text); // 'a'
console.log(b.desc.text); // 'b'
// 一个简单的深拷贝函数,去掉了一些胶水部分
// 用户态输入一定是一个 Plain Object,并且所有 value 也是 Plain Object
function deepClone(obj) {
const keys = Object.keys(obj);
return keys.reduce((memo, current) => {
const value = obj[current];
if (typeof value === "object") {
return {
...memo,
[current]: deepClone(value)
};
}
return {
...memo,
[current]: value
};
}, {});
}
let a = {
val: 1,
desc: {
text: "a"
}
};
let b = deepClone(a);
b.val = 2;
console.log(a.val); // 1
console.log(b.val); // 2
b.desc.text = "b";
console.log(a.desc.text); // 'a'
console.log(b.desc.text); // 'b'
柯里化1
js
// 实现一个add方法,使计算结果能够满足如下预期:
function add() {
// 第一次执行时,定义一个数组专门用来存储所有的参数
// let _args = Array.prototype.slice.call(arguments);
let _args = Array.from(arguments);
console.log("_args=" + _args);
// 在内部声明一个函数,利用闭包的特性保存_args并收集所有的参数值
let _adder = function () {
_args.push(...arguments);
return _adder;
};
// 利用toString隐式转换的特性,当最后执行时隐式转换,并计算最终的值返回
_adder.toString = () => _args.reduce((a, b) => a + b);
return _adder;
}
add(1)(2)(3); // 6
// add(1, 2, 3)(4); // 10
// add(1)(2)(3)(4)(5); // 15
// add(2, 6)(1); // 9
const curry = (fn, arr = []) => {
return (...args) => {
//判断参数总数是否和fn参数个数相等
if ([...arr, ...args].length === fn.length) {
return fn(...arr, ...args); //拓展参数,调用fn
} else {
return curry(fn, [...arr, ...args]); //迭代,传入现有的所有参数
}
};
};
//test
function sum(a, b, c, d, e) {
console.log("curry success");
console.log([a, b, c, d, e]);
}
let sumFn = curry(sum);
sumFn(1)(2)(3)(5, 4); //6
sumFn(1)(2, 3)(4)(5); //6
// 实现一个add方法,使计算结果能够满足如下预期:
function add() {
// 第一次执行时,定义一个数组专门用来存储所有的参数
// let _args = Array.prototype.slice.call(arguments);
let _args = Array.from(arguments);
console.log("_args=" + _args);
// 在内部声明一个函数,利用闭包的特性保存_args并收集所有的参数值
let _adder = function () {
_args.push(...arguments);
return _adder;
};
// 利用toString隐式转换的特性,当最后执行时隐式转换,并计算最终的值返回
_adder.toString = () => _args.reduce((a, b) => a + b);
return _adder;
}
add(1)(2)(3); // 6
// add(1, 2, 3)(4); // 10
// add(1)(2)(3)(4)(5); // 15
// add(2, 6)(1); // 9
const curry = (fn, arr = []) => {
return (...args) => {
//判断参数总数是否和fn参数个数相等
if ([...arr, ...args].length === fn.length) {
return fn(...arr, ...args); //拓展参数,调用fn
} else {
return curry(fn, [...arr, ...args]); //迭代,传入现有的所有参数
}
};
};
//test
function sum(a, b, c, d, e) {
console.log("curry success");
console.log([a, b, c, d, e]);
}
let sumFn = curry(sum);
sumFn(1)(2)(3)(5, 4); //6
sumFn(1)(2, 3)(4)(5); //6
柯里化2
js
function curryingHelper(fn, ...args) {
//第一个括号里的
return function(...args2) {
//第二个括号里的args2
let _totalArgs = args.concat(args2);
return fn.apply(this, _totalArgs);
};
}
function betterCurryingHelper(fn, len=fn.length) {
return function(...args2) {
let allArgsFulfilled = args2.length >= len;//后面参数大于方法参数就停止便利
// 如果参数全部满足,就可以终止递归调用
if (allArgsFulfilled) {
return fn.apply(this, args2);
} else {
let argsNeedFulfilled = [fn].concat(...args2);
return betterCurryingHelper(
curryingHelper.apply(this, argsNeedFulfilled),
len- args2.length
);
}
};
}
function showMsg(name, age, fruit) {
console.log(
`My name is ${name}, I'm ${age} years old, and I like eat ${fruit}`
);
}
let betterShowMsg = betterCurryingHelper(showMsg);
betterShowMsg("dreamapple", 22, "apple"); // My name is dreamapple, I'm 22 years old, and I like eat apple
betterShowMsg("dreamapple", 22)("apple"); // My name is dreamapple, I'm 22 years old, and I like eat apple
betterShowMsg("dreamapple")(22, "apple"); // My name is dreamapple, I'm 22 years old, and I like eat apple
betterShowMsg("dreamapple")(22)("apple"); // My name is dreamapple, I'm 22 years old, and I like eat apple
function curryingHelper(fn, ...args) {
//第一个括号里的
return function(...args2) {
//第二个括号里的args2
let _totalArgs = args.concat(args2);
return fn.apply(this, _totalArgs);
};
}
function betterCurryingHelper(fn, len=fn.length) {
return function(...args2) {
let allArgsFulfilled = args2.length >= len;//后面参数大于方法参数就停止便利
// 如果参数全部满足,就可以终止递归调用
if (allArgsFulfilled) {
return fn.apply(this, args2);
} else {
let argsNeedFulfilled = [fn].concat(...args2);
return betterCurryingHelper(
curryingHelper.apply(this, argsNeedFulfilled),
len- args2.length
);
}
};
}
function showMsg(name, age, fruit) {
console.log(
`My name is ${name}, I'm ${age} years old, and I like eat ${fruit}`
);
}
let betterShowMsg = betterCurryingHelper(showMsg);
betterShowMsg("dreamapple", 22, "apple"); // My name is dreamapple, I'm 22 years old, and I like eat apple
betterShowMsg("dreamapple", 22)("apple"); // My name is dreamapple, I'm 22 years old, and I like eat apple
betterShowMsg("dreamapple")(22, "apple"); // My name is dreamapple, I'm 22 years old, and I like eat apple
betterShowMsg("dreamapple")(22)("apple"); // My name is dreamapple, I'm 22 years old, and I like eat apple
柯里化es6版本
js
const curry = (fn, ...args) =>
// 函数的参数个数可以直接通过函数数的.length属性来访问
args.length >= fn.length // 这个判断很关键!!!
// 传入的参数大于等于原始函数fn的参数个数,则直接执行该函数
? fn(...args)
/**
* 传入的参数小于原始函数fn的参数个数时
* 则继续对当前函数进行柯里化,返回一个接受所有参数(当前参数和剩余参数) 的函数
*/
: (..._args) => curry(fn, ...args, ..._args);
function add1(x, y, z) {
return x + y + z;
}
const add = curry(add1);
console.log(add(1, 2, 3));
console.log(add(1)(2)(3));
console.log(add(1, 2)(3));
console.log(add(1)(2, 3));
const curry = (fn, ...args) =>
// 函数的参数个数可以直接通过函数数的.length属性来访问
args.length >= fn.length // 这个判断很关键!!!
// 传入的参数大于等于原始函数fn的参数个数,则直接执行该函数
? fn(...args)
/**
* 传入的参数小于原始函数fn的参数个数时
* 则继续对当前函数进行柯里化,返回一个接受所有参数(当前参数和剩余参数) 的函数
*/
: (..._args) => curry(fn, ...args, ..._args);
function add1(x, y, z) {
return x + y + z;
}
const add = curry(add1);
console.log(add(1, 2, 3));
console.log(add(1)(2)(3));
console.log(add(1, 2)(3));
console.log(add(1)(2, 3));
debunce和throttle
js
const debounce = (fn, delay) => {
let timer = null;
return (...args) => {
clearTimeout(timer);
console.log(this);
timer = setTimeout(() => {
fn.apply(this, args);
}, delay);
};
};
const throttle = (fn, delay = 500) => {
let flag = true;
return (...args) => {
if (!flag) return;
flag = false;
setTimeout(() => {
fn.apply(this, args);
flag = true;
}, delay);
};
};
function con(...args) {
console.log(args);
console.log("hello");
}
throttle(con, 2000);
const debounce = (fn, delay) => {
let timer = null;
return (...args) => {
clearTimeout(timer);
console.log(this);
timer = setTimeout(() => {
fn.apply(this, args);
}, delay);
};
};
const throttle = (fn, delay = 500) => {
let flag = true;
return (...args) => {
if (!flag) return;
flag = false;
setTimeout(() => {
fn.apply(this, args);
flag = true;
}, delay);
};
};
function con(...args) {
console.log(args);
console.log("hello");
}
throttle(con, 2000);
deepfreeze
js
function deepFreeze(object) {
let propNames = Object.getOwnPropertyNames(object);
for (let name of propNames) {
let value = object[name];
object[name] =
value && typeof value === "object" ? deepFreeze(value) : value;
}
return Object.freeze(object);
}
//? hlsdfjsdlkfs
//x dkfdlsfj k
let person = {
name: "Leonardo",
profession: {
name: "developer",
},
};
deepFreeze(person);
person.profession.name = "doctor"; // TypeError: Cannot assign to read only property 'name' of object
function deepFreeze(object) {
let propNames = Object.getOwnPropertyNames(object);
for (let name of propNames) {
let value = object[name];
object[name] =
value && typeof value === "object" ? deepFreeze(value) : value;
}
return Object.freeze(object);
}
//? hlsdfjsdlkfs
//x dkfdlsfj k
let person = {
name: "Leonardo",
profession: {
name: "developer",
},
};
deepFreeze(person);
person.profession.name = "doctor"; // TypeError: Cannot assign to read only property 'name' of object
不可复制
vue
<template>
<p id="h">和律师费</p>
<p id="h1">和律师费</p>
<p id="h2">和律师费</p>
<p id="h3">和律师费</p>
<input type="text" />
</template>
<script setup lang="ts">
// 禁止右键菜单
document.body.oncontextmenu = (e) => {
console.log(e, '右键')
return false
// e.preventDefault();
}
// 禁止文字选择。
document.body.onselectstart = (e) => {
console.log(e, '文字选择')
return false
// e.preventDefault();
}
// 禁止复制
document.body.oncopy = (e) => {
console.log(e, 'copy')
return false
// e.preventDefault();
}
// 禁止剪切
document.body.oncut = (e) => {
console.log(e, 'cut')
return false
// e.preventDefault();
}
// 禁止粘贴
document.body.onpaste = (e) => {
console.log(e, 'paste')
return false
// e.preventDefault();
}
window.onload = function f1() {
f2()
}
function f2() {
console.log('hello')
arraytest()
}
function arraytest() {
for (let i = 1; i < 100; i++) {
console.log((i + i) ^ 2)
}
}
console.log('代码执行结束')
document.body.onpaste = (e) => {
let clipboardData = e.clipboardData || window.clipboardData // 兼容处理
console.log('要粘贴的数据', clipboardData.getData('text'))
}
</script>
<template>
<p id="h">和律师费</p>
<p id="h1">和律师费</p>
<p id="h2">和律师费</p>
<p id="h3">和律师费</p>
<input type="text" />
</template>
<script setup lang="ts">
// 禁止右键菜单
document.body.oncontextmenu = (e) => {
console.log(e, '右键')
return false
// e.preventDefault();
}
// 禁止文字选择。
document.body.onselectstart = (e) => {
console.log(e, '文字选择')
return false
// e.preventDefault();
}
// 禁止复制
document.body.oncopy = (e) => {
console.log(e, 'copy')
return false
// e.preventDefault();
}
// 禁止剪切
document.body.oncut = (e) => {
console.log(e, 'cut')
return false
// e.preventDefault();
}
// 禁止粘贴
document.body.onpaste = (e) => {
console.log(e, 'paste')
return false
// e.preventDefault();
}
window.onload = function f1() {
f2()
}
function f2() {
console.log('hello')
arraytest()
}
function arraytest() {
for (let i = 1; i < 100; i++) {
console.log((i + i) ^ 2)
}
}
console.log('代码执行结束')
document.body.onpaste = (e) => {
let clipboardData = e.clipboardData || window.clipboardData // 兼容处理
console.log('要粘贴的数据', clipboardData.getData('text'))
}
</script>
去重
ts
function useFilter() {
let str =
// 长度为14的数组
[4, 5, 56, 56, 78, 23, 4, 5, 6, 90, 56, 34]
let res = []
str.forEach((item, index) => {
if (!res.includes(item)) {
res.push(item)
}
})
console.log(res)
}
function useIndexof() {
let str =
// 长度为14的数组
[4, 5, 56, 56, 78, 23, 4, 5, 6, 90, 56, 34]
let result = []
str.forEach((item, index) => {
if (str.indexOf(item) === index) {
result.push(item)
}
})
console.log(result)
}
function useReduce() {
let str =
// 长度为14的数组
[4, 5, 56, 56, 78, 23, 4, 5, 6, 90, 56, 34]
let unique = (arr) => {
if (!Array.isArray(arr)) return
return arr.reduce(
(prev, cur) => (prev.includes(cur) ? prev : [...prev, cur]),
[],
)
}
console.log(unique(str))
// 打印数组长度20:[false, "true", Infinity, true, 0, [], [], {b: 2, a: 1}, {b: 2, a: 1}, {}, {}, "false", "0", null, undefined, {a: 1, b: 2}, {a: 1, b: 2}, NaN, function(){}, function(){}]
}
function useSet() {
let str =
// 长度为14的数组
[4, 5, 56, 56, 78, 23, 4, 5, 6, 90, 56, 34]
let s = [...new Set(str)]
console.log(s)
}
function useFilter() {
let str =
// 长度为14的数组
[4, 5, 56, 56, 78, 23, 4, 5, 6, 90, 56, 34]
let res = []
str.forEach((item, index) => {
if (!res.includes(item)) {
res.push(item)
}
})
console.log(res)
}
function useIndexof() {
let str =
// 长度为14的数组
[4, 5, 56, 56, 78, 23, 4, 5, 6, 90, 56, 34]
let result = []
str.forEach((item, index) => {
if (str.indexOf(item) === index) {
result.push(item)
}
})
console.log(result)
}
function useReduce() {
let str =
// 长度为14的数组
[4, 5, 56, 56, 78, 23, 4, 5, 6, 90, 56, 34]
let unique = (arr) => {
if (!Array.isArray(arr)) return
return arr.reduce(
(prev, cur) => (prev.includes(cur) ? prev : [...prev, cur]),
[],
)
}
console.log(unique(str))
// 打印数组长度20:[false, "true", Infinity, true, 0, [], [], {b: 2, a: 1}, {b: 2, a: 1}, {}, {}, "false", "0", null, undefined, {a: 1, b: 2}, {a: 1, b: 2}, NaN, function(){}, function(){}]
}
function useSet() {
let str =
// 长度为14的数组
[4, 5, 56, 56, 78, 23, 4, 5, 6, 90, 56, 34]
let s = [...new Set(str)]
console.log(s)
}
一些技巧
ts
/**
* 1. 确保数组值
* @type {any[]}
*/
const array = Array(5).fill(``)
console.log(array)
/*2. 获取数组唯一值*/
const cars = [`Mazda`, `Ford`, `Renault`, `Opel`, `Mazda`]
const uniqueWithArrayFrom = Array.from(new Set(cars))
console.log(uniqueWithArrayFrom)
const uniqueWithSpreadOperator = [...new Set(cars)]
console.log(uniqueWithSpreadOperator)
// Merging objects
const product = { name: `Milk`, packaging: `Plastic`, price: `5$` }
const manufacturer = { name: `Company Name`, address: `The Company Address` }
/*3.使用展开运算符合并对象和对象数组*/
const productManufacturer = { ...product, ...manufacturer }
console.log(productManufacturer)
// Merging an array of objects into one
const cities = [
{ name: `Paris`, visited: `no` },
{ name: `Lyon`, visited: `no` },
{ name: `Marseille`, visited: `yes` },
{ name: `Rome`, visited: `yes` },
{ name: `Milan`, visited: `no` },
{ name: `Palermo`, visited: `yes` },
{ name: `Genoa`, visited: `yes` },
{ name: `Berlin`, visited: `no` },
{ name: `Hamburg`, visited: `yes` },
{ name: `New York`, visited: `yes` },
]
const result = cities.reduce(
(accumulator, item) => ({
...accumulator,
[item.name]: item.visited,
}),
{},
)
console.log(result)
/*数组map的方法*/
const cityNames = Array.from(cities, ({ name }) => name)
console.log(cityNames)
//有条件的对象属性
const getUser = (emailIncluded) => ({
name: `John`,
surname: `Doe`,
...(emailIncluded && { email: 'john@doe.com' }),
})
const user = getUser(true)
console.log(user) // Outputs { name: "John", surname: "Doe", email: "john@doe.com" }
const userWithoutEmail = getUser(false)
console.log(userWithoutEmail) // Outputs { name: "John", surname: "Doe" }
//结构原始数据
const rawUser = {
name: `John`,
surname: `Doe`,
email: `john@doe.com`,
displayName: `SuperCoolJohn`,
joined: `2016-05-05`,
image: `path-to-the-image`,
followers: 45,
}
const user3 = {}
let userDetails = {}
;({ name: user.name, surname: user.surname, ...userDetails } = rawUser)
console.log(user3)
console.log(userDetails)
//动态属性名
const dynamic = `email`
const user4 = {
name: `John`,
[dynamic]: `john@doe.com`,
}
console.log(user4)
//字符串差值
const user5 = {
name: `John`,
surname: `Doe`,
details: {
email: `john@doe.com`,
displayName: `SuperCoolJohn`,
joined: `2016-05-05`,
image: `path-to-the-image`,
followers: 45,
},
}
const printUserInfo = (user) => {
const text = `The user is ${user.name} ${user.surname}. Email: ${user.details.email}. Display Name: ${user.details.displayName}. ${user.name} has ${user.details.followers} followers.`
console.log(text)
}
printUserInfo(user5)
/**
* 1. 确保数组值
* @type {any[]}
*/
const array = Array(5).fill(``)
console.log(array)
/*2. 获取数组唯一值*/
const cars = [`Mazda`, `Ford`, `Renault`, `Opel`, `Mazda`]
const uniqueWithArrayFrom = Array.from(new Set(cars))
console.log(uniqueWithArrayFrom)
const uniqueWithSpreadOperator = [...new Set(cars)]
console.log(uniqueWithSpreadOperator)
// Merging objects
const product = { name: `Milk`, packaging: `Plastic`, price: `5$` }
const manufacturer = { name: `Company Name`, address: `The Company Address` }
/*3.使用展开运算符合并对象和对象数组*/
const productManufacturer = { ...product, ...manufacturer }
console.log(productManufacturer)
// Merging an array of objects into one
const cities = [
{ name: `Paris`, visited: `no` },
{ name: `Lyon`, visited: `no` },
{ name: `Marseille`, visited: `yes` },
{ name: `Rome`, visited: `yes` },
{ name: `Milan`, visited: `no` },
{ name: `Palermo`, visited: `yes` },
{ name: `Genoa`, visited: `yes` },
{ name: `Berlin`, visited: `no` },
{ name: `Hamburg`, visited: `yes` },
{ name: `New York`, visited: `yes` },
]
const result = cities.reduce(
(accumulator, item) => ({
...accumulator,
[item.name]: item.visited,
}),
{},
)
console.log(result)
/*数组map的方法*/
const cityNames = Array.from(cities, ({ name }) => name)
console.log(cityNames)
//有条件的对象属性
const getUser = (emailIncluded) => ({
name: `John`,
surname: `Doe`,
...(emailIncluded && { email: 'john@doe.com' }),
})
const user = getUser(true)
console.log(user) // Outputs { name: "John", surname: "Doe", email: "john@doe.com" }
const userWithoutEmail = getUser(false)
console.log(userWithoutEmail) // Outputs { name: "John", surname: "Doe" }
//结构原始数据
const rawUser = {
name: `John`,
surname: `Doe`,
email: `john@doe.com`,
displayName: `SuperCoolJohn`,
joined: `2016-05-05`,
image: `path-to-the-image`,
followers: 45,
}
const user3 = {}
let userDetails = {}
;({ name: user.name, surname: user.surname, ...userDetails } = rawUser)
console.log(user3)
console.log(userDetails)
//动态属性名
const dynamic = `email`
const user4 = {
name: `John`,
[dynamic]: `john@doe.com`,
}
console.log(user4)
//字符串差值
const user5 = {
name: `John`,
surname: `Doe`,
details: {
email: `john@doe.com`,
displayName: `SuperCoolJohn`,
joined: `2016-05-05`,
image: `path-to-the-image`,
followers: 45,
},
}
const printUserInfo = (user) => {
const text = `The user is ${user.name} ${user.surname}. Email: ${user.details.email}. Display Name: ${user.details.displayName}. ${user.name} has ${user.details.followers} followers.`
console.log(text)
}
printUserInfo(user5)
ts
{
/**
* @Author yanni
* @Description //TODO
* 1.使用 Array.includes 来处理多个条件
* @Date 18:32 2019/7/14
* @Modified By:
*/
console.log(`__________1.使用 Array.includes 来处理多个条件_________________`)
// bad
const testbad = (fruit: string) => {
if (fruit === `apple` || fruit === `strawberry`) {
console.log(`red`)
}
}
// good
const testgood = (fruit: string) => {
// 条件提取到数组中
const redFruits = [`apple`, `strawberry`, `cherry`, `cranberries`]
if (redFruits.includes(fruit)) {
console.log(`red`)
}
}
}
{
console.log(`__________2.减少嵌套,提前使用 return 语句_________________`)
/**
* @Author yanni
* @Description //TODO
* 2.减少嵌套,提前使用 return 语句
* @Date 18:33 2019/7/14
* @Modified By:
*/
//good
const testredfruit = (fruit: string, quantity: number | undefined) => {
const redFruits = [`apple`, `strawberry`, `cherry`, `cranberries`]
// 条件 1:fruit 必须有值
if (fruit) {
// 条件 2:必须为红色
if (redFruits.includes(fruit)) {
console.log(`red`)
// 条件 3:数量必须大于 10
if (quantity > 10) {
console.log(`big quantity`)
}
}
} else {
throw new Error(`No fruit!`)
}
}
// 测试结果
// testredfruit(null); // 抛出错误:No fruits
testredfruit(`apple`) // 打印:red
testredfruit(`apple`, 20) // 打印:red,big quantity
/* 在发现无效条件时提前 return */
// better
const test2 = (fruit, quantity) => {
const redFruits = [`apple`, `strawberry`, `cherry`, `cranberries`]
// 条件 1:提前抛出错误
if (!fruit) throw new Error(`No fruit!`)
// 条件2:必须为红色
if (redFruits.includes(fruit)) {
console.log(`red`)
// 条件 3:数量必须大于 10
if (quantity > 10) {
console.log(`big quantity`)
}
}
}
//best
/* 在发现无效条件时提前 return */
const test3 = (fruit: string, quantity: number) => {
const redFruits = [`apple`, `strawberry`, `cherry`, `cranberries`]
if (!fruit) throw new Error(`No fruit!`) // 条件 1:提前抛出错误
if (!redFruits.includes(fruit)) return // 条件 2:当 fruit 不是红色的时候,提前 return
console.log(`red`)
// 条件 3:必须是大量存在
if (quantity > 10) {
console.log(`big quantity`)
}
}
}
{
console.log(`_________3.使用函数的默认参数 和 解构____________________`)
const testfrout = (fruit, quantity = 1) => {
// i如果没有提供 quantity 参数,则默认为 1
if (!fruit) return
console.log(`We have ${quantity} ${fruit}!`)
}
// 测试结果
testfrout(`banana`) // We have 1 banana!
testfrout(`apple`, 2) // We have 2 apple!
}
{
console.log(
`___________4.选择 Map / Object 字面量,而不是Switch语句_________________`,
)
//bad
function testapple1(color) {
// 使用 switch case 语句,根据颜色找出对应的水果
switch (color) {
case `red`:
return [`apple`, `strawberry`]
case `yellow`:
return [`banana`, `pineapple`]
case `purple`:
return [`grape`, `plum`]
default:
return []
}
}
//测试结果
testapple1(null) // []
testapple1(`yellow`) // ['banana', 'pineapple']
//good
// 使用对象字面量,根据颜色找出对应的水果
const fruitColor = {
red: [`apple`, `strawberry`],
yellow: [`banana`, `pineapple`],
purple: [`grape`, `plum`],
}
function testapple2(color) {
return fruitColor[color] || []
}
//best
// 使用 Map ,根据颜色找出对应的水果
const fruitColorMap = new Map()
.set(`red`, [`apple`, `strawberry`])
.set(`yellow`, [`banana`, `pineapple`])
.set(`purple`, [`grape`, `plum`])
function testapple3(color) {
return fruitColorMap.get(color) || []
}
console.log(
`我们是不是应该禁止使用 switch 语句呢? 不要局限于此。 就个人而言,我尽可能使用对象字面量,但我不会设置硬规则来阻止使用 switch ,是否使用应该根据你的场景而决定`,
)
const fruits = [
{ name: `apple`, color: `red` },
{ name: `strawberry`, color: `red` },
{ name: `banana`, color: `yellow` },
{ name: `pineapple`, color: `yellow` },
{ name: `grape`, color: `purple` },
{ name: `plum`, color: `purple` },
]
function testapple4(color) {
// 使用 Array filter ,根据颜色找出对应的水果
return fruits.filter((f) => f.color === color)
}
}
{
console.log(`________________________________________________`)
const fruits1 = [
{ name: `apple`, color: `red` },
{ name: `banana`, color: `yellow` },
{ name: `grape`, color: `purple` },
]
function test3() {
// 条件:简短方式,所有的水果都必须是红色
const isAllRed = fruits1.every((f) => f.color === `red`)
console.log(isAllRed) // false
}
const fruits2 = [
{ name: `apple`, color: `red` },
{ name: `banana`, color: `yellow` },
{ name: `grape`, color: `purple` },
]
function testredfruit() {
// 条件:是否存在红色的水果
const isAnyRed = fruits2.some((f) => f.color == `red`)
console.log(isAnyRed) // true
}
}
export {}
{
/**
* @Author yanni
* @Description //TODO
* 1.使用 Array.includes 来处理多个条件
* @Date 18:32 2019/7/14
* @Modified By:
*/
console.log(`__________1.使用 Array.includes 来处理多个条件_________________`)
// bad
const testbad = (fruit: string) => {
if (fruit === `apple` || fruit === `strawberry`) {
console.log(`red`)
}
}
// good
const testgood = (fruit: string) => {
// 条件提取到数组中
const redFruits = [`apple`, `strawberry`, `cherry`, `cranberries`]
if (redFruits.includes(fruit)) {
console.log(`red`)
}
}
}
{
console.log(`__________2.减少嵌套,提前使用 return 语句_________________`)
/**
* @Author yanni
* @Description //TODO
* 2.减少嵌套,提前使用 return 语句
* @Date 18:33 2019/7/14
* @Modified By:
*/
//good
const testredfruit = (fruit: string, quantity: number | undefined) => {
const redFruits = [`apple`, `strawberry`, `cherry`, `cranberries`]
// 条件 1:fruit 必须有值
if (fruit) {
// 条件 2:必须为红色
if (redFruits.includes(fruit)) {
console.log(`red`)
// 条件 3:数量必须大于 10
if (quantity > 10) {
console.log(`big quantity`)
}
}
} else {
throw new Error(`No fruit!`)
}
}
// 测试结果
// testredfruit(null); // 抛出错误:No fruits
testredfruit(`apple`) // 打印:red
testredfruit(`apple`, 20) // 打印:red,big quantity
/* 在发现无效条件时提前 return */
// better
const test2 = (fruit, quantity) => {
const redFruits = [`apple`, `strawberry`, `cherry`, `cranberries`]
// 条件 1:提前抛出错误
if (!fruit) throw new Error(`No fruit!`)
// 条件2:必须为红色
if (redFruits.includes(fruit)) {
console.log(`red`)
// 条件 3:数量必须大于 10
if (quantity > 10) {
console.log(`big quantity`)
}
}
}
//best
/* 在发现无效条件时提前 return */
const test3 = (fruit: string, quantity: number) => {
const redFruits = [`apple`, `strawberry`, `cherry`, `cranberries`]
if (!fruit) throw new Error(`No fruit!`) // 条件 1:提前抛出错误
if (!redFruits.includes(fruit)) return // 条件 2:当 fruit 不是红色的时候,提前 return
console.log(`red`)
// 条件 3:必须是大量存在
if (quantity > 10) {
console.log(`big quantity`)
}
}
}
{
console.log(`_________3.使用函数的默认参数 和 解构____________________`)
const testfrout = (fruit, quantity = 1) => {
// i如果没有提供 quantity 参数,则默认为 1
if (!fruit) return
console.log(`We have ${quantity} ${fruit}!`)
}
// 测试结果
testfrout(`banana`) // We have 1 banana!
testfrout(`apple`, 2) // We have 2 apple!
}
{
console.log(
`___________4.选择 Map / Object 字面量,而不是Switch语句_________________`,
)
//bad
function testapple1(color) {
// 使用 switch case 语句,根据颜色找出对应的水果
switch (color) {
case `red`:
return [`apple`, `strawberry`]
case `yellow`:
return [`banana`, `pineapple`]
case `purple`:
return [`grape`, `plum`]
default:
return []
}
}
//测试结果
testapple1(null) // []
testapple1(`yellow`) // ['banana', 'pineapple']
//good
// 使用对象字面量,根据颜色找出对应的水果
const fruitColor = {
red: [`apple`, `strawberry`],
yellow: [`banana`, `pineapple`],
purple: [`grape`, `plum`],
}
function testapple2(color) {
return fruitColor[color] || []
}
//best
// 使用 Map ,根据颜色找出对应的水果
const fruitColorMap = new Map()
.set(`red`, [`apple`, `strawberry`])
.set(`yellow`, [`banana`, `pineapple`])
.set(`purple`, [`grape`, `plum`])
function testapple3(color) {
return fruitColorMap.get(color) || []
}
console.log(
`我们是不是应该禁止使用 switch 语句呢? 不要局限于此。 就个人而言,我尽可能使用对象字面量,但我不会设置硬规则来阻止使用 switch ,是否使用应该根据你的场景而决定`,
)
const fruits = [
{ name: `apple`, color: `red` },
{ name: `strawberry`, color: `red` },
{ name: `banana`, color: `yellow` },
{ name: `pineapple`, color: `yellow` },
{ name: `grape`, color: `purple` },
{ name: `plum`, color: `purple` },
]
function testapple4(color) {
// 使用 Array filter ,根据颜色找出对应的水果
return fruits.filter((f) => f.color === color)
}
}
{
console.log(`________________________________________________`)
const fruits1 = [
{ name: `apple`, color: `red` },
{ name: `banana`, color: `yellow` },
{ name: `grape`, color: `purple` },
]
function test3() {
// 条件:简短方式,所有的水果都必须是红色
const isAllRed = fruits1.every((f) => f.color === `red`)
console.log(isAllRed) // false
}
const fruits2 = [
{ name: `apple`, color: `red` },
{ name: `banana`, color: `yellow` },
{ name: `grape`, color: `purple` },
]
function testredfruit() {
// 条件:是否存在红色的水果
const isAnyRed = fruits2.some((f) => f.color == `red`)
console.log(isAnyRed) // true
}
}
export {}