|
| 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 | +``` |
0 commit comments