Skip to content

Commit c3907b1

Browse files
committed
JavaScript
1 parent 83587a4 commit c3907b1

4 files changed

Lines changed: 243 additions & 0 deletions

File tree

‎getMiddle.js‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//根据传入的字符串,如果长度为偶数,返回中间两个字母,如果为奇数则返回中间的字符
2+
//string.substr() 截取指定长度的字符串
3+
function getMiddle(str) {
4+
let numStyle = 0
5+
let len =str.length
6+
let index = 0
7+
len % 2 === 0 ? numStyle = 0 : numStyle = 1
8+
if (numStyle === 0 ){
9+
index = len/2-1
10+
return str.substr(index,2)
11+
}else {
12+
index = parseInt(len/2)
13+
return str.substr(index,1)
14+
}
15+
}
16+
//简洁写法 Math.ceil() 函数返回大于或等于一个给定数字的最小整数(向上取整)
17+
function getMiddle(str){
18+
return str.substr(Math.ceil(str.length/2 - 1),str.length % 2 ===0 ? 2 : 1)
19+
}

‎reverString.js‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
//如果字符串的长度大于5,则翻转长度5以后的字符串
2+
function reverseString(str) {
3+
let len = str.length
4+
if (len < 5){
5+
return
6+
} else {
7+
let strArr = str.slice(5).split('').reverse().join("").trim()
8+
return str.substr(0,5).concat([' '],strArr)
9+
}
10+
}
11+
reverseString('hello world wewew')

‎数组对象去重.md‎

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
2+
有一天有一个朋友给我发来消息 “数组对象根据对象中指定的属性去重?让我写写看”,看到这个的时候我有点懵逼,好像不太会。
3+
4+
我只能咬着牙硬着头皮死磕,差点从入门到放弃,在朋友一步一步指导下面终于写好了,朋友总结好了发了我一份,本着自愿共享的精神。过来两天我就把这个给忘了
5+
6+
在项目中刚好遇到这个东西,那时候脑子仅剩一点点的思路,努力回想时却早已记忆模糊。很无奈呀,怎么办?项目开发需要,硬着头皮又找朋友要了一份哈哈。现在我决定我要建立一个自己的 `js` 小仓库,里面就放我不懂的,有事没事去翻翻,温故
7+
8+
喜欢和朋友交流,偶尔会抛一些技术问题给我,我不会,每次都在指导下慢慢的一步一步明白懂了,顺便学到了新知识。哈哈一起学习进步,欢迎技术交流
9+
10+
11+
问题:数组对象根据对象中指定的属性去重?
12+
13+
> 方法一: `reduce` 方法
14+
```
15+
function unique(arr,u_key){
16+
let obj = {}
17+
arr.reduce((prev,next)=>{
18+
obj[next[u_key]+typeof next[u_key]] ? '' :
19+
obj[next[u_key]+typeof next[u_key]] = true && prev.push(next)
20+
return prev
21+
},[])
22+
}
23+
```
24+
`push` 方法是返回新数组的长度,&& 返回的是后面那个值,而我们需要的是一个第一次执行的数组对象,所以另写了一行 `return prev`
25+
26+
> 方法二: 计数器原理
27+
```
28+
function unique(arr,u_key){
29+
let result = []
30+
result[0] = arr[0]
31+
arr.forEach((meta_item,i)=>{
32+
//声明计数变量,如果源数组中的一个对象和result结果数组中的所有对象不同,就push
33+
let num = 0
34+
result.forEach((r_item,j)=>{
35+
if (meta_item[u_key]!==r_item[u_key]) {
36+
num++
37+
}
38+
if (num === result.length) {
39+
result.push(meta_item)
40+
}
41+
})
42+
})
43+
return result
44+
}
45+
```
46+
47+
> 方法三 : 简单粗暴循环,利用原理是对象的同名属性会被覆盖(和第一种方法有点像)
48+
```
49+
function unique(arr,u_key) {
50+
let obj = {}
51+
let result = []
52+
arr.forEach(item=>{
53+
let typeof_key = typeof item[u_key] + item[u_key]
54+
obj[typeof_key] = item
55+
})
56+
for (let key in obj) {
57+
result.push(obj[key])
58+
}
59+
return result
60+
}
61+
```
62+
测试案例
63+
```
64+
let arrayList = [{
65+
id:'1',
66+
name:'one'
67+
},{
68+
id:'2',
69+
name:'tow',
70+
},{
71+
id:'3',
72+
name:'three'
73+
},{
74+
id:'1',
75+
name:'one'
76+
},{
77+
id:2,
78+
name:'tow',
79+
},{
80+
id:'3',
81+
name:'three'
82+
}]
83+
unique(arrayList,'id')
84+
```
85+
86+
87+

‎深拷贝.md‎

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
曾在项目中遇到过使用深拷贝,萌新的我,居然傻傻把地址引用当做深拷贝,南辕北辙。在朋友的帮助下知道了深拷贝可以简单粗暴一句话解决
2+
3+
```
4+
JSON.parse(JSON.stringify(source));
5+
```
6+
`js` 中的引用类型和基本类型复制傻傻分不清的原因吧,堆内存,栈内存也不知道,一定是个假前端。
7+
8+
强烈推荐一篇文章 [深拷贝的终极探索(90%的人都不知道)](https://juejin.im/post/5bc1ae9be51d450e8b140b0c),原有一天我们成为那10%。哈哈
9+
10+
> 深拷贝和浅拷贝
11+
12+
深拷贝和浅拷贝都是针对的引用类型,`JS` 中的变量类型分为值类型(基本类型)和引用类型;对值类型进行复制操作会对值进行一份拷贝,而对引用类型赋值,则会进行地址的拷贝,最终两个变量指向同一份数据
13+
```
14+
let arr1 = [{
15+
label: '一级 1',
16+
children: [{
17+
label: '二级 1-1',
18+
children: [{
19+
label: '三级 1-1-1'
20+
}]
21+
}]
22+
}, {
23+
label: '一级 2',
24+
children: [{
25+
label: '二级 2-1',
26+
children: [{
27+
label: '三级 2-1-1'
28+
}]
29+
}, {
30+
label: '二级 2-2',
31+
children: [{
32+
label: '三级 2-2-1'
33+
}]
34+
}]
35+
}, {
36+
label: '一级 3',
37+
children: [{
38+
label: '二级 3-1',
39+
children: [{
40+
label: '三级 3-1-1'
41+
}]
42+
}, {
43+
label: '二级 3-2',
44+
children: [{
45+
label: '三级 3-2-1'
46+
}]
47+
}]
48+
}]
49+
let arr2 = arr1//arr1 和arr2指向了同一个地址
50+
51+
arr1[1].children[0].children[0].label = "我被修改了"
52+
53+
arr1 === arr2 // true arr1 和 arr2 复制的是地址,而不是是值
54+
55+
arr1 = []//arr1 指向一个新的地址
56+
57+
arr1 == arr2 //false
58+
59+
```
60+
61+
> 引用类型的深层拷贝,深层拷贝是拷贝创建另一空间
62+
```
63+
let arr3 = JSON.parse(JSON.stringify(arr1))
64+
arr1 === arr3 //false,他们虽然长的一模一样,但是不是同一个地址
65+
66+
arr1[1].children[0].children[0].label = "我又被修改了" // arr1和arr3 现在长得也不一样了,他们互相之前没有任何关系
67+
```
68+
69+
推荐文章中提到了另外两种实现深拷贝方法,我就直接在这敲一遍
70+
```
71+
function clone (source) {
72+
let target = {}
73+
for (let i in source) {
74+
if (source.hasOwnProperty(i)) {
75+
console.log(i)
76+
if( typeof source[i] === 'object'){
77+
target[i] = clone(source[i])//注意这里,typeof 不能区分数组和对象,instanceof 可区分数组和对象
78+
}else {
79+
target[i] = source[i]
80+
}
81+
}
82+
}
83+
return target;
84+
}
85+
let object1 = {
86+
label: '一级 3',
87+
children: [{
88+
label: '二级 3-1',
89+
children: [{
90+
label: '三级 3-1-1'
91+
}]
92+
}]
93+
}
94+
clone(object1)
95+
```
96+
期待被改善的:
97+
98+
1.没有对参数做检验
99+
100+
2.判断是否对象的逻辑不够严谨
101+
102+
3.没有考虑数组的兼容
103+
104+
> 生成指定深度和每层广度的代码
105+
106+
这段代码的 `temp = temp['data'] = {}` 我硬是看了好久才明白,原来又是引用类型,挽狂澜于既倒,扶大厦之将倾
107+
108+
```
109+
function createData(deep,breadth) {
110+
let data = {}
111+
let temp = data
112+
for (let i = 0; i < deep; i++) {
113+
temp = temp['data'] = {}//注意看后面注释
114+
for (let j = 0; j < breadth; j++) {
115+
temp[j] = j
116+
}
117+
}
118+
return data
119+
}
120+
createData(1, 3);// 1层深度,每层有3个数据 {data: {0: 0, 1: 1, 2: 2}}
121+
let data = {}
122+
let temp = data//此时data和temp共同指向同一个地址
123+
temp = temp['data'] = {}
124+
//temp和data指向同一个地址,temp添加了一个data属性,那么data也添加了这个属性即data=temp={data:{}}
125+
//,temp=temp['data']={},temp重新指向了一个新的地址并且和data.data指向同一个地址,只要temp发生改变,data.data 也会发生改变
126+
```

0 commit comments

Comments
 (0)