Skip to content

Commit 1522711

Browse files
committed
feat: js的自实现
1 parent 0984578 commit 1522711

File tree

3 files changed

+152
-0
lines changed

3 files changed

+152
-0
lines changed

source/_posts/js自实现.md

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
---
2+
title: js自实现
3+
code_block_shrink: false
4+
date: 2024-08-22 12:30:45
5+
updated: 2024-08-22 12:30:45
6+
excerpt: js的一些api的自实现
7+
tags: [js]
8+
---
9+
# js的自实现
10+
## new的实现
11+
### 过程
12+
1. 新建一个对象p,把构造函数中的this设置为对象的变量
13+
2. 把p的__proto__指向其构造器的原型对象P.prototype
14+
3. 如果构造函数中有`返回值,且返回值为对象,则返回该对象`,否者返回新建的对象
15+
16+
{% asset_img 原型链图.png 原型链图 %}
17+
18+
### 代码实现
19+
```js
20+
function Person(name, age) {
21+
this.name = name;
22+
this.age = age;
23+
}
24+
25+
Person.prototype.sayYourName = function() {
26+
console.log("i am" + this.name);
27+
};
28+
29+
function New(constructor, ...args) {
30+
let obj = {};
31+
if (constructor.prototype !== null) {
32+
obj.__proto__ = constructor.prototype;
33+
}
34+
// 执行构造函数 把属性或者方法添加到创建的空对象上
35+
let ret = constructor.apply(obj, args);
36+
return ret instanceof Object ? ret : obj
37+
}
38+
39+
const p = New(Person, "sdfs", 12);
40+
p.sayYourName();
41+
```
42+
43+
## call的实现
44+
### 思路
45+
1. 将函数设置为对象的方法(this的指向为该对象)
46+
2. 调用该方法
47+
3. 删除该方法
48+
49+
```js
50+
Function.prototype.call2 = function(content = window,...args) {
51+
// this为该方法
52+
content.fn = this;
53+
let result = content.fn(...args);
54+
delete content.fn;
55+
return result;
56+
}
57+
58+
const obj = {
59+
name: 'lcb',
60+
age: 24,
61+
}
62+
63+
function bar(name, age) {
64+
console.(this.name)
65+
console.log(this.age)
66+
}
67+
68+
console.log(bar.call2(obj));
69+
```
70+
71+
## apply
72+
### 思路
73+
同call
74+
### 实现
75+
```js
76+
Function.prototype.apply2 = function(context = window,args) {
77+
context.fn = this;
78+
let obj;
79+
obj = context.fn(args);
80+
delete obj.fn;
81+
return obj;
82+
};
83+
```
84+
85+
## 函数科里化
86+
### 思路
87+
1. 如果传入的参数没有到原函数需要的数量 则继续执行curry函数接收参数
88+
2. 如果参数达到了,则执行科里化了的函数
89+
90+
### 实现
91+
```js
92+
function curry(fn, ...args) {
93+
let length = fn.length; // Function.length 为 函数需要几个参数
94+
return function(...params){
95+
newArgs = args.concat(params);
96+
if (newArgs.length < length) {
97+
return curry.call(this,fn,...newArgs);
98+
}else{
99+
return fn.apply(this,newArgs);
100+
}
101+
}
102+
}
103+
104+
function multiFn(a, b, c) {
105+
return a * b * c;
106+
}
107+
108+
let multi = curry(multiFn);
109+
console.log(multi(2)(3)(4));
110+
console.log(multi(2,3,4));
111+
console.log(multi(2)(3,4));
112+
console.log(multi(2,3)(4));
113+
```
114+
115+
## JSON.stringfy
116+
### 思路
117+
转化类型:
118+
1. Boolean | Number | String 类型会转换为对应的原始类型
119+
2. undefined、任意函数以及symbol,会被忽略(出现在非数组对象的属性值中时),或者被转换成 null(出现在数组中时)
120+
3. 不可枚举的属性会被忽略
121+
4. 如果一个对象的属性值通过某种间接的方式指回该对象本身,即循环引用,属性也会被忽略。// todo
122+
5. 递归/循环
123+
124+
### 实现
125+
```js
126+
function jsonStringify(obj) {
127+
let type = typeof obj;
128+
// 判断是否为对象
129+
if (type === "object") {
130+
let json = [];
131+
let arr = Array.isArray(obj); // 判断数组
132+
for (let k in obj) {
133+
let v = obj[k];
134+
let type = typeof v;
135+
if (/string|undefined|function/.test(type)) {
136+
v = '"' + v + '"';
137+
} else if (type === "object") {
138+
v = jsonStringify(v);
139+
}
140+
json.push((arr ? "" : '"' + k + '":') + String(v));
141+
}
142+
} else {
143+
if (/string|undefined|function/.test(type)) {
144+
obj = '"' + obj + '"';
145+
}
146+
return String(obj);
147+
}
148+
return (arr ? "[" : "{") + String(json) + (arr ? "]" : "}");
149+
}
150+
151+
```
21.3 KB
Loading

source/_posts/泛型从入门到骚操作.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ title: 泛型从入门到骚操作
33
excerpt: 介绍了ts泛型infer的使用
44
tags: TypeScript
55
code_block_shrink: false
6+
date: 2024-07-07 17:02:40
67
updated: 2024-08-01 11:50:44
78
---
89
泛型可以用来创建可重用的数据类型

0 commit comments

Comments
 (0)