方法技巧
JS方法技巧
Git中拉取代码
第一种,有分支拉取
git clone -b home git clone -b home [拉取地址]
第二种,没有分支拉取
git clone [拉取地址]
离开页面弹出确认对话框
window.onbeforeunload = () => '你确定要离开吗?';
其中 home是分支
初始化数组
我们可以使用默认值(如""、null或 )初始化特定大小的数组0。您可能已经将这些用于一维数组,但如何初始化二维数组/矩阵呢?
const array = Array(5).fill('');
// 输出
(5) ["", "", "", "", ""]
const matrix = Array(5).fill(0).map(()=>Array(5).fill(0));
// 输出
(5) [Array(5), Array(5), Array(5), Array(5), Array(5)]
0: (5) [0, 0, 0, 0, 0]
1: (5) [0, 0, 0, 0, 0]
2: (5) [0, 0, 0, 0, 0]
3: (5) [0, 0, 0, 0, 0]
4: (5) [0, 0, 0, 0, 0]
length: 5
过滤特殊字符
function filterCharacter(str){
// 首先设置一个模式
let pattern = new RegExp("[`~!@#$^&*()=:”“'。,、?|{}':;'%,\[\].<>/?~!@#¥……&*()&;—|{ }【】‘;]")
let resultStr = "";
for (let i = 0; i < str.length; i++) {
// 主要通过 replace ,pattern 规则 去把字符替换成空 最后拼接在 resultStr
resultStr = resultStr + str.substr(i, 1).replace(pattern, '');
}
// 当循环结束的时候返回最后结果 resultStr
return resultStr;
}
// 示例
filterCharacter('gyaskjdhy12316789#$%^&!@#1=123,./[') // 结果:gyaskjdhy123167891123
深拷贝 structuredClone()
此前,如果开发人员想要深拷贝对象,经常需要依赖第三方库来实现或者手动实现一个神拷贝,或者采取 const cloneObj = JSON.parse(JSON.stringify(obj)); 的 hack, 但其在处理包含循环引用或不符合 JSON 的数据类型(如 Map 和 Set,Blob 等 ) 的更复杂对象时,是有很多不足之处的
而现在,JavaScript 内置了一个 structuredClone() 的方法, 此方法提供了一种简单有效的方法来深度克隆对象, 且适用于大多数现代浏览器和 Node.js v17 以上
// 将原始对象传递给该函数, 它将返回一个具有不同引用和对象属性引用的深层副本
const obj = { name: 'Mike', friends: [{ name: 'Sam' }] };
const clonedObj = structuredClone(obj);
console.log(obj.name === clonedObj); // false
console.log(obj.friends === clonedObj.friends); // false
与众所周知的 JSON.parse(JSON.stringify()) 不同, structuredClone() 允许您克隆循环引用,这是目前在 JavaScript 中使用深拷贝最简单的方法。
空合并运算符 ??
空合并运算符 ?? (Nullish coalescing operator) 是一个逻辑运算符,当其左侧操作数为 null 或 undefined 时,它返回其右侧操作数,否则返回其左侧操作数
const foo = null ?? 'default string';
console.log(foo); //output: "default string"
const bar = 0 ?? 'default string'
console.log(bar); //output: 0
- ?? 仅当左操作数为 null 或 undefined 时, ?? 运算符才会将结果作为右操作数。
- ||运算符会将左操作数的所有假值(falsy) 的结果作为右操作数
案例
// 1. 使用 0 作为输入
const a = 0;
console.log(`a || 10 = ${a || 10}`); // a || 10 = 10
console.log(`a ?? 10 = ${a ?? 10}`); // a ?? 10 = 0
// 2. 空字符串 '' 作为输入
const a = ''
console.log(`a || "ABC" = ${a || "ABC"}`); // a || "ABC" = ABC
console.log(`a ?? "ABC" = ${a ?? "ABC"}`); // a ?? "ABC" =
// 3. 使用 null 作为输入
const a = null;
console.log(`a || 10 = ${a || 10}`); // a || 10 = 10v
console.log(`a ?? 10 = ${a ?? 10}`); // a ?? 10 = 10
// 4. 使用 undefined 作为输入
const a = {name: ''}
console.log(`a.name ?? 'varun 1' = ${a.name ?? 'varun 1'}`);
console.log(`a.name || 'varun 2' = ${a.name || 'varun 2'}`);
// a.name ?? 'varun 1' =
// a.name || 'varun 2' = varun 2
// 5. 使用 false 作为输入
const a = false;
console.log(`a || 10 = ${a || 10}`); // a || 10 = 10
console.log(`a ?? 10 = ${a ?? 10}`); // a ?? 10 = false
字符串首字母大写
该方法用于将英文字符串的首字母大写处理:
const capitalize = str => str.charAt(0).toUpperCase() + str.slice(1)
capitalize("hello world") // Hello world
翻转字符串
该方法用于将一个字符串进行翻转操作,返回翻转后的字符串:
const reverse = str => str.split('').reverse().join('');
reverse('hello world'); // 'dlrow olleh'
截断字符串
该方法可以从指定长度处截断字符串:
const truncateString = (string, length) => string.length < length ? string : `${string.slice(0, length - 3)}...`;
truncateString('Hi, I should be truncated because I am too loooong!', 36) // 'Hi, I should be truncated because...'
去除字符串中的HTML
该方法用于去除字符串中的HTML元素:
const stripHtml = html => (new DOMParser().parseFromString(html, 'text/html')).body.textContent || '';
从数组中移除重复项
该方法用于移除数组中的重复项:
const removeDuplicates = (arr) => [...new Set(arr)];
console.log(removeDuplicates([1, 2, 2, 3, 3, 4, 4, 5, 5, 6]));
判断数组是否为空
该方法用于判断一个数组是否为空数组,它将返回一个布尔值:
const isNotEmpty = arr => Array.isArray(arr) && arr.length > 0;
isNotEmpty([1, 2, 3]); // true
复制内容到剪切板
该方法使用 navigator.clipboard.writeText 来实现将文本复制到剪贴板: (但目前各大浏览器支持度还不是很高,需要考虑兼容性问题)
const copyToClipboard = (text) => navigator.clipboard.writeText(text);
copyToClipboard("Hello World");
清除所有cookie
该方法可以通过使用 document.cookie 来访问 cookie 并清除存储在网页中的所有 cookie:
const clearCookies = document.cookie.split(';').forEach(cookie => document.cookie = cookie.replace(/^ +/, '').replace(/=.*/, `=;expires=${new Date(0).toUTCString()};path=/`));
滚动到页面顶部
该方法用于在页面中返回顶部:
const goToTop = () => window.scrollTo(0, 0);
goToTop();
判断当前标签页是否激活
该方法用于检测当前标签页是否已经激活:
const isTabInView = () => !document.hidden;
判断当前是否是苹果设备
该方法用于检测当前的设备是否是苹果的设备:
const isAppleDevice = () => /Mac|iPod|iPhone|iPad/.test(navigator.platform);
isAppleDevice();
是否滚动到页面底部
该方法用于判断页面是否已经底部:
const scrolledToBottom = () => document.documentElement.clientHeight + window.scrollY >= document.documentElement.scrollHeight;
重定向到一个URL
该方法用于重定向到一个新的URL:
const redirect = url => location.href = url
redirect("https://www.google.com/")
对整个对象赋值为空
// 查询条件
let selectForm: any = ref({
interfaceCode: "",
interfaceName: "",
supplierCode: "",
supplierType: "",
interfaceType: "",
creator: "",
createTimeStart: "",
createTimeEnd: "",
createTimes: "",
offset: 1,//当前页
limit: 20//每页条目数
})
// 赋值为空
Object.keys(selectForm.value).forEach(key => {
if (key != "offset" && key != "limit") {
selectForm.value[key] = ''
}
})
在没有第三个变量的情况下交换两个变量
在 JavaScript 中,你可以使用解构从数组中拆分值。这可以应用于交换两个变量而无需第三个
let x = 1;
let y = 2;
// LONGER FORM
let temp = x;
x = y;
y = temp;
// SHORTHAND
[x, y] = [y, x];
将对象的值收集到数组中
用于Object.values()将对象的所有值收集到一个新数组中
const info = { name: "Matt", country: "Finland", age: 35 };
// LONGER FORM
let data = [];
for (let key in info) {
data.push(info[key]);
}
// SHORTHAND
const data = Object.values(info);
判断对象是否是空对象
// 方法1
Object.keys(obj).length === 0
// 方法2
JSON.stringify(obj) === '{}'
序列化与反序列化
将字符串反序列化为原始值
JSON.parse
let str = '{"a": 12, "b": 5, "c": "abc"}';
let json1 = JSON.parse(str); //字符串转json
console.log(json1);
将原始值序列化为字符串
JSON.stringify
let json={a:12,b:5};
alert(JSON.stringify(json)); //json转字符串
console.log(json);
## 防抖节流 防抖就是(当持续触发事件时,一定时间段内没有再触发事件,事件处理函数才会执行一次,如果设定的时间到来之前,又一次触发了事件,就重新开始延时,销毁上一次的定时器)
// 防抖操作
const self = this;
//频繁点击的时候销毁上一个定时器
clearTimeout(self.tiems);
//当没有频繁点击后,最后执行的定时器
self.tiems = setTimeout(() => {
//里面写执行代码
}, 1000)
使用?.简化&&和三元运算符
我们从后端接口获取数据时,经常会遇到后端缺字段的情况,导致前端不得不去做空值兼容,防止后端不给字段,例如我们需要获取商品价格时,我们会写:
const price = res.data?.price || '暂无标价'
但是其实这种做法是有问题的,显然易见,如果一个免费商品的价格为0的话,我们这里的||就会产生一个bug。而且习惯了||写法的时候,很容易会忽略这个潜在问题。等到bug产生的时候,我们只能改成:
const price = (res.data?.price === null || res.data?.price === undefined) ? '暂无标价' : res.data?.price
显然这个代码又长,可读性也差。有没有更好的判断字段为空的方式呢,有,那就是空值合并运算符??。
const price = res.data?.price ?? '暂无标价'
在一些业务场景下,可以取代||,用来规避使用||来为某些变量设置默认值,可能会遇到意料之外的行为。(例如,''或 0)
MDN: 空值合并操作符(??)是一个逻辑操作符,当左侧的操作数为 null 或者 undefined 时,返回其右侧操作数,否则返回左侧操作数。
条件非空的判断
在处理输入框相关业务时,往往会判断输入框未输入值的场景。
if(value !== null && value !== undefined && value !== ''){
//...
}
改善 ES6中新出的空值合并运算符了解过吗,要写那么多条件吗?
if((value??'') !== ''){
//...
}
使用??代替||
??运算符是 ES2020 引入,也被称为null判断运算符( Nullish coalescing operator) 它的行为类似||,但是更严 ||运算符是左边是空字符串或false或0等falsy值,都会返回后侧的值。而??必须运算符左侧的值为null或undefined时,才会返回右侧的值。因此0||1的结果为1,0??1的结果为0
const response = {
settings: {
nullValue: null,
height: 400,
animationDuration: 0,
headerText: '',
showSplashScreen: false
}
};
const yed = response.settings.udValue ?? 'some other default'; // result: 'some other default'
const nVal = response.settings.nullValue ?? 'some other default'; // result: 'some other default'
const hText = response.settings.headerText ?? 'Hello, world!'; // result: ''
const aTion = response.settings.animationDuration ?? 300; // result: 0
const sreen = response.settings.showSplashScreen ?? true; // result: false
对象/数组取值
取值在程序中非常常见,比如从对象obj中取值。
const obj = {
a:1,
b:2,
c:3,
d:4,
e:5,
}
取值:
const {a,b,c,d,e} = obj;
const f = a + d;
const g = c + e;
改善 ES6的解构赋值虽然好用。但是要注意解构的对象不能为undefined、null。否则会报错,故要给被解构的对象一个默认值。
const {a,b,c,d,e} = obj || {};
if中判断条件
if(
type == 1 ||
type == 2 ||
type == 3 ||
type == 4 ||
){
//...
}
改进 ES6中数组实例方法includes会不会使用呢?
const condition = [1,2,3,4];
if( condition.includes(type) ){
//...
}
js实现手机号中间几位数字变成***
第一种,使用字符串和数组中常见的几个方法。字符串方法:split()。数组方法:splice(),join()
1、split(): 将一个字符串拆分为一个子字符串数组,并返回该数组 注释:该方法返回新数组,不会更改原始字符串。 注意:如果("")用作分隔符,则会对字符串进行逐个字符拆分。
案例
const str = “hello”
let arr = str.split("");
console.log(arr); // h,e,l,l,o
2、splice():方法向数组添加或从数组中删除项目,并返回删除的项目。 注释:splice() 该方法会改变原始数组
const arr = ["a","b","c","d"];
arr.splice(1,2,"e","gg"); //从数字索引的第一位开始,删除两个索引的内容,向数组添加”e“he”gg“两项。
console.log(arr); // ["a","e","gg"];
3、join():将数组作为一个字符串返回。元素将由指定的分隔符分隔。默认分隔符是逗号 (,)。 注释:join()该方法不会改变原数组
const arr = ['a','b','b','d'];
let result = arr.join();
console.log(result); // a,b,c,d
功能实现
const telphone = '13300009999';
let telArr = telphone.split();
telArr.splice(3,4,'****');
let result = telArr.join(); //因为不会改变原数组,需要用一个新的变量去接收
console.log(result); // 1330****999
第二种,利用字符串的substr()
1、substr():该方法用于提取字符串的一部分。该方法从指定位置开始,并返回指定数量的字符。 注释:substr() 方法不会更改原始字符串。
const str = 'Hello World';
let result = str.substr(1,4);
console.log(result); //ello
实现功能
const telphone = '13300009999';
let result = telphone.substr(0,4 + '****' + telphone(8);
console.log(result);// 1330****999
第三种,利用字符串的substring()和replace();
1、substring():该方法用于从字符串中提取指定的索引(位置)之间的字符,并返回子字符串。 注释:substring() 方法不会更改原始字符串。
const str = 'Hello World';
let result = str.substring(1,4);
console.log(result); //ell
2、replace():该方法在字符串中搜索值或正则表达式;该方法返回已替换值的新字符串。 注释:replace() 方法不会更改原始字符串。
const str = 'Hello World';
let result = str.replace("Hello","Hi");
console.log(result); //Hi World
实现功能
const telphone = '13300009999';
let result = telphone.replace(telphone.substring(3,8),'****');
console.log(result);// 1330****999
采用正则来实现功能
const telphone = '13300009999';
const reg = /(\d{4})\d{4}(\d{3})/;
let result = telphone.replace(reg,"$1****$2");
console.log(result);// 1330****999
日期时间基本操作
let data = new Date();
// 当前时间戳(精确到秒)
console.log(Date.now())
// 返回本地时间的日期时间,与实现有关,如:Tue Jul 07 2020 23:56:14 GMT+0800 (中国标准时间)。
console.log(data)
// 返回本地时间的年。
console.log('年:' + data.getFullYear())
// 返回本地时间的月。 返回值是 0(一月) 到 11(十二月) 之间的一个整数。
console.log('月:' + data.getMonth())
//返回本地时间的日。 返回值是 1 ~ 31 之间的一个整数
console.log('日:' + data.getDate())
//返回本地时间的星期。 返回值为0(周日)至6(周六)。
console.log('星期:' + data.getDay())
//返回本地时间的时。 返回值是 0 (午夜) 到 23 (晚上 11 点)之间的一个整数。
console.log('时:' + data.getHours())
//返回本地时间的分。 返回值是 0 ~ 59 之间的一个整数。
console.log('分:' + data.getMinutes())
//返回本地时间的秒。返回值是 0 ~ 59 之间的一个整数。
console.log('秒:' + data.getSeconds())
//返回本地时间的毫秒。 返回值是 0 ~ 999 之间的一个整数。
console.log('毫秒:' + data.getMilliseconds())
// 返回本地时间本地习惯的日期时间字符串,与实现有关,如:2020/7/7 下午11:56:14。
console.log('日期时间:' + data.toLocaleString())
// 返回本地时间本地习惯的日期时间字符串,与实现有关,如:2020/7/7
console.log('日期:' + data.toLocaleDateString())
// 返回本地时间本地习惯的时间字符串,与实现有关,如:下午11:56:14。
console.log('时间:' + data.toLocaleTimeString());

时间戳转时间
dateFormat(originVal) {
const dt = new Date(originVal);
// 年份
const y = dt.getFullYear();
// 月份是从0开始的所以这儿加1,后面不足两位就补0,所以把前面加上引号变成字符串才可以补足
// padStart(2,'0'),第一位总长度多少位,第二个不足多少位用这个字符来填充
const m = (dt.getMonth() + 1 + '').padStart(2, '0');
// 日期
const d = (dt.getDate() + '').padStart(2, '0');
// 时
const hh = (dt.getHours() + '').padStart(2, '0');
// 分
const mm = (dt.getMinutes() + '').padStart(2, '0');
// 秒
const ss = (dt.getSeconds() + '').padStart(2, '0');
// 拼接返回
return `${y}-${m}-${d} ${hh}:${mm}:${ss}`;
},
编码与解码
encodeURI 编码URI。将字母、数字、-.!~'()和;/?😡&=+$,#以外的字符编码为%开头的16进制转义序列,不会对那些用于分隔URI组件的字符 encodeURIComponent 编码URI组件。将字母、数字和-.!~'()以外的字符编码为%开头的16进制转义序列,会对那些用于分隔URI组件的字符进行转义。
decodeURI 解码URI,将%开头的16进制转义序列解码为其代表的字符。encodeURI的逆操作。 decodeURIComponent 解码URI的组件,将%开头的16进制转义序列解码为其代表的字符。encodeURIComponent的逆操作。
<script type="text/javascript">
let code = "、-_.!~*'()和;/?😡&=+$,#";
//编码
let encodes = encodeURI(code);
let encodes01 = encodeURIComponent(code);
// 解码
let decodes = decodeURI(encodes);
let decodes01 = decodeURIComponent(encodes);
console.log("编码:" + encodes)
console.log("编码:" + encodes01)
console.log("解码:" + decodes)
console.log("解码:" + decodes01)
</script>

//字符串转base64
function encode(str) {
// 对字符串进行编码
var encode = encodeURI(str);
// 对编码的字符串转化base64
var base64 = btoa(encode);
return base64;
}
//base64转字符串
function decode(base64) {
// 对base64转编码
var decode = atob(base64);
// 编码转字符串
var str = decodeURI(decode);
return str;
}
搜索模糊查询
当我们在设计查询的使用,需要模糊查询操作,最终效果如下: 第一种方法
<div id="box">
<input type="text" @input="handleInput">
<ul>
<li v-for="(item,index) in datalist">
{{item}}
</li>
</ul>
</div>
<script>
var vm = new Vue({
el:"#box",
data:{
datalist:[],
orderlist:['aaa','bbb','ccc','ddd','add','cee','eee']
},
methods:{
handleInput(ev){
// filter()方法会创建一个新数组,原数组的每个元素传入回调函数中,
// 回调函数中有return返回值,若返回值为true,这个元素保存到新数组中;
// 若返回值为false,则该元素不保存到新数组中;原数组不发生改变。
// includes方法是检测字符串中是否包含另一字符串,如果包含返回true,如果不包含返回false
this.datalist = this.orderlist.filter(item=>item.includes(evt.target.value))
}
}
})
</script>
第二种方法
<div id="box">
<input type="text" v-model="mytext">
<ul>
<!-- 用函数表达式来做, mymethod()调用这个方法 -->
<li v-for="(item,index) in mymethod()">
{{item}}
</li>
</ul>
</div>
<script>
var vm = new Vue({
el:"#box",
data:{
mytext:'',
datalist:['aaa','bbb','ccc','ddd','add','cee','eee']
},
methods:{
mymethod(){
// filter()方法会创建一个新数组,原数组的每个元素传入回调函数中,
// 回调函数中有return返回值,若返回值为true,这个元素保存到新数组中;
// 若返回值为false,则该元素不保存到新数组中;原数组不发生改变。
// includes方法是检测字符串中是否包含另一字符串,如果包含返回true,如果不包含返回false
return this.datalist.filter(item=>item.includes(this.mytext))
}
}
})
</script>

定时器
一次性定时器 setTimeout(callback, delay, rest)
self.time = setTimeout(() => {
}, 1000);
取消定时器
clearTimeout(self.time)
定时加载定时器 setInterval(callback, delay, rest)
self.time = setInterval(() => {
}, 1000);
取消定时器
clearInterval(self.time)
扁平化数组
一个部门JSON数据中,属性名是部门id,属性值是个部门成员id数组集合,现在要把有部门的成员id都提取到一个数组集合中。
const deps = {
'采购部':[1,2,3],
'人事部':[5,8,12],
'行政部':[5,14,79],
'运输部':[3,64,105],
}
let member = [];
for (let item in deps){
const value = deps[item];
if(Array.isArray(value)){
member = [...member,...value]
}
}
member = [...new Set(member)]
获取对象的全部属性值还要遍历吗?Object.values忘记了吗?还有涉及到数组的扁平化处理,为啥不用ES6提供的flat方法呢,还好这次的数组的深度最多只到2维,还要是遇到4维、5维深度的数组,是不是得循环嵌套循环来扁平化? 改进
const deps = {
'采购部':[1,2,3],
'人事部':[5,8,12],
'行政部':[5,14,79],
'运输部':[3,64,105],
}
let member = Object.values(deps).flat(Infinity);
其中使用Infinity作为flat的参数,使得无需知道被扁平化的数组的维度。
补充
flat方法不支持IE浏览器
异步函数
异步函数很常见,经常是用 Promise 来实现。
const fn1 = () =>{
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(1);
}, 300);
});
}
const fn2 = () =>{
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(2);
}, 600);
});
}
const fn = () =>{
fn1().then(res1 =>{
console.log(res1);// 1
fn2().then(res2 =>{
console.log(res2)
})
})
}
如果这样调用异步函数,不怕形成地狱回调啊! 改进
const fn = async () =>{
const res1 = await fn1();
const res2 = await fn2();
console.log(res1);// 1
console.log(res2);// 2
}
补充
但是要做并发请求时,还是要用到Promise.all()。
const fn = () =>{
Promise.all([fn1(),fn2()]).then(res =>{
console.log(res);// [1,2]
})
}
如果并发请求时,只要其中一个异步函数处理完成,就返回结果,要用到Promise.race()
去除数字之外的所有字符
const str = 'xieyezi 23213 23213 is 95994 so hansome 223333'
const numbers = str.replace(/\D/g,'')
console.log(numbers)
//2321395994223333
反转字符串或者单词
const sentence = 'xieyezi js so handsome,lol.'
const reverseSentence = reverseBySeparator(sentence,"")
console.log(reverseSentence);
// .lol,emosdnah os sj izeyeix
const reverseEachWord = reverseBySeparator(reverseSentence,"")
console.log(reverseEachWord);
//izeyeix sj os,emosdnah.lol
function reverseBySeparator(string,separator){
return string.split(separator).reverse().join(separator)
}
清空数组
const numbers = [1,2,3,4,5]
numbers.length = 0
console.log(numbers) // []
从数组中获取最大值和最小值
const nums = [1,2,3,4,5,-3,99,-45,-1]
const max = Math.max(...nums)
const min = Math.min(...nums)
console.log(max) //99
console.log(min) //-45
十进制转二进制或十六进制
const num = 43
const binaryNum = num.toString(2)
const hexadecimalNum = num.toString(16)
console.log(binaryNum) // 101011
console.log(hexadecimalNum) //2b