# 手写JS
**Repository Path**: weiyao11/handwritten-js
## Basic Information
- **Project Name**: 手写JS
- **Description**: 用原生的方法手写了相关JS的API,包括ES6等在内的常用方法
- **Primary Language**: Unknown
- **License**: MIT
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 1
- **Forks**: 0
- **Created**: 2021-05-18
- **Last Updated**: 2021-05-18
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
## 手写部分API
### Array
#### 1. _every
> 方法测试一个数组内的所有元素是否都能通过某个指定函数的测试。它返回一个布尔值。
>
> **注意**:**若收到一个空数组,此方法在一切情况下都会返回 `true`。**
代码:
```js
Array.prototype._every = function (fn) {
// 1. 判断他是不是一个函数
if(typeof fn !== 'function'){
throw new Error('The arg should a function');
}
let _this = this;
for(let i = 0; i < _this.length; i++){
let res = fn(_this[i],i,_this);
if(!res){
return false;
}
}
rturn true;
}
```
#### 2. _some
> 方法测试数组中是不是至少有1个元素通过了被提供的函数测试。它返回的是一个Boolean类型的值。
>
> **注意**:**若收到一个空数组,此方法在一切情况下都会返回 `false`。**
代码:
```js
Array.prototype._some = function (fn) {
// 1. 判断他是不是一个函数
if(typeof fn !== 'function'){
throw new Error('The arg should a function');
}
let _this = this;
for(let i = 0; i< _this.length;i++){
let res = fn(_this[i],i ,_this);
if(res){
return true;
}
}
return false;
}
```
#### 3._filter
> `filter() `方法创建一个新数组, 其包含通过所提供函数实现的测试的所有元素。
代码:
```js
Array.prototype._filter = function (fn) {
// 1. 判断他是不是一个函数
if(typeof fn !== 'function'){
throw new Error('The arg should a function');
}
let _this = this;
let result = [];
for(let i = 0; i<_this.length; i++){
let res = fn(_this[i],i,_this);
if(res){
result.push(_this[i]);
}
}
return result;
}
```
#### 4. _forEach
> `forEach()` 方法对数组的每个元素执行一次给定的函数。
代码:
```js
Array.prototype._forEach = function (fn){
if(typeof fn !== 'function'){
throw new Error('The fn not is function,you must be is function');
}
let _this = this;
for(let i = 0;i<_this.length;i++){
fn(_this[i],i,_this);
}
}
```
#### 5. _map
> `map()` 方法创建一个新数组,其结果是该数组中的每个元素是调用一次提供的函数后的返回值
```js
Array.prototype._map = function(fn){
//1. 判断他是不是函数,如果不是函数就new 一个 error
if(typeof fn !== 'function'){
throw new Error('The fn not is function,you must be is function');
}
let _this = this;
let result = [];
for(let i =0 ;i<_this.length;i++) {
result.push(fn(_this[i],i,_this));
}
return result;
}
```
#### 6. _reduce
> `reduce()` 方法对数组中的每个元素执行一个由您提供的**reducer**函数(升序执行),将其结果汇总为单个返回值。
```js
Array.prototype._reduce = function(fn,initVal = 0){
if(typeof fn !== 'function') {
throw new Error('The fn not is function,you must be is function');
}
let _this = this;
for(let i = 0;i< _this.length;i++){
initVal = fn(initVal, _this[i], i, _this);
}
return initVal;
}
```
#### 7. _find
> `**find()**` 方法返回数组中满足提供的测试函数的第一个元素的值。否则返回 [`undefined`](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/undefined)。
```js
Array.prototype._find = function(fn) {
if (typeof fn !== 'function') {
throw new Error('The fn not is function,you must be is function');
}
let _this = this;
for(let i = 0; i<_this.length; i++ ){
let res = fn(_this[i],i,_this);
if(res){
return _this[i];
}
}
return undefined;
}
```
#### 8._findAll
> `**find()**` 方法返回数组中满足提供的测试函数的全部元素的值。否则返回 []。
```js
Array.prototype._findAll = function(fn) {
if (typeof fn !== 'function') {
throw new Error('The fn not is function,you must be is function');
}
let _this = this;
let result = [];
for(let i = 0; i<_this.length; i++ ){
let res = fn(_this[i],i,_this);
if(res){
result.push(_this[i]);
}
}
return result;
}
```
#### 9._findIndex
> `**find()**` 方法返回数组中满足提供的测试函数的第一个元素的下标。否则返回 [`undefined`](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/undefined)。
```js
Array.prototype._findIndex = function(fn){
if(typeof fn !== 'function') {
throw new Error('The fn not is function,you must be is function');
}
let _this = this;
for(let i = 0; i< _this.length; i++){
let res = fn(_this[i],i,_this);
if(res) {
return i
}
}
return undefined;
}
```
#### 10._findAllIndex
>`**find()**` 方法返回数组中满足提供的测试函数的全部元素的下标。否则返回 []。
```js
Array.prototype._findAllIndex = function(fn){
if(typeof fn !== 'function') {
throw new Error('The fn not is function,you must be is function');
}
let _this = this;
let result = [];
for(let i = 0; i< _this.length; i++){
let res = fn(_this[i],i,_this);
if(res) {
result.push(i)
}
}
return result;
}
```
#### 11. _join
>`**join()**` 方法将一个数组(或一个[类数组对象](https://developer.mozilla.org/zh-CN_docs/Web/JavaScript/Guide/Indexed_collections#working_with_array-like_objects))的所有元素连接成一个字符串并返回这个字符串。如果数组只有一个项目,那么将返回该项目而不使用分隔符。
```js
Array.prototype._join = function(str){
// 1. 判断这个数组是不是字符串
if(typeof str === 'function') throw new Error('The str should’t function ');
if(typeof str === "undefined") throw new Error("The str should't a undefined,you must be give a string,for example ','")
if(typeof str !== 'string') str = ',';
let _this = this;
if(_this.length == 0) return "";
let s = ''
for(let i = 0; i< _this.length; i++){
if(this.length-1=== i){
s+= _this[i];
}else {
s += _this[i]+str;
}
}
return s;
}
```
#### 12._reverse
> 反转数组, flag=false 正常反转
>
> flag = true 怪异反转
```js
Array.prototype._reverse = function(flag = false){
let _this =this;
let result = [];
if(!flag){
for(let i = _this.length - 1; i >= 0; i--){
result.push(_this[i]);
}
}else {
for(let i = _this.length - 1; i >= 0; i--){
let s;
if(typeof this[i] === 'string'){
s = _this[i].split('')._reverse().join('');
}else if(typeof this[i] === 'number'){
s =Number(_this[i].toString().split('')._reverse().join('')) ;
}else if( typeof _this[i] === 'boolean') {
s = _this[i];
}else {
s = _this[i];
}
result.push(s);
}
}
return result;
}
```
#### 13._fill
> `**fill()**` 方法用一个固定值填充一个数组中从起始索引到终止索引内的全部元素。不包括终止索引。
```js
Array.prototype._fill = function (value = 0,indexStart =0 ,indexEnd = this.length){
let _this = this;
if(indexStart>indexEnd) {
indexStart =0,indexEnd =_this.length;
console.warn('The indexStart not should > indexEnd,we will indexStart=0,indexEnd=this.length');
}
for(let i = indexStart ; i < indexEnd; i++){
_this[i] = value;
}
return _this;
}
```
#### 14._includes
>`**includes()**` 方法用来判断一个数组是否包含一个指定的值,根据情况,如果包含则返回 true,否则返回false。
```js
Array.prototype._includes = function(value , startIndex = 0){
if( typeof startIndex != 'number') throw new Error('This must be a number');
if(startIndex >= this.length || startIndex < 0) return false;
let _this = this;
for(let i = startIndex; i < _this.length; i ++) {
if(_this[i] === value) return true;
}
return false;
}
```
#### 15._shuffle
> 洗牌算法
```js
Array.prototype._shuffle = function(){
// 1. 洗牌算法
let _this = this;
for(let i = _this.length - 1; i>0 ; i-- ) {
let j = Math.floor(Math.random()*(i+1));
[_this[i],_this[j]] = [_this[j],_this[i]];
}
return _this;
}
```
#### 16._sample
> 从已知数组中去n个,如果n大于数组长度,就相当于洗牌算法
```js
Array.prototype._sample = function(value=1){
let _this = this;
let Indexarr = _this._Index();
let res = [];
if(value>_this.length) value = _this.length;
while (value !==0){
let i = Math.floor(Math.random()*Indexarr.length);
let j = Indexarr[i];
Indexarr.splice(i,1);
res.push(_this[j]);
value--;
}
return res;
}
```
#### 17. _Index
> 辅助算法(实用性小) 填充数组的下标
```js
Array.prototype._Index = function(){
let _this = this;
let number = _this.length;
let fillArr=Array.from(new Array(number).keys())
return fillArr;
}
```
#### 18._partition
> 对数组按一定规则进行拆分,for example : 奇数和偶数两组
```js
Array.prototype._partition = function(fn){
if(typeof fn !== 'function')
throw new Error('The fn must be a function');
let _this = this;
let _left = [],_right =[];
for(let i = 0; i < _this.length; i++){
let res = fn(_this[i],i,_this);
if(!res){
_left.push(_this[i]);
}else {
_right.push(_this[i]);
}
}
return [_left,_right];
}
```
#### 19._compact
> 取出数组中的不可视的值
>
> false、0、null、undefined、NaN、“”
```js
Array.prototype._compact = function(){
let _this = this;
let res = []
_this.forEach((item,index)=>{
if(item == false || item == 0 || item == null || item == undefined || Object.is(item,NaN) || item == ""){
}else {
res.push(item);
}
})
return res;
}
```
#### 20._isEmpty
> 判断数组是否为空
```js
Array.prototype._isEmpty = function (){
let _this = this;
return _this.length === 0;
}
```
#### 21._rest
> 取出数组中的第一项后返回
```js
Array.prototype._rest = function (){
let _this = this;
_this.splice(0,1);
return _this;
}
```
#### 22._initial
>取出数组中的第最后一项项后返回
```js
Array.prototype._initial = function(){
let _this = this;
_this.splice(this.length-1,1);
return _this;
}
```
#### 23._without
> 过滤掉不想要的数据,参数是数字
````js
Array.prototype._without = function (...args){
let b = Object.prototype.toString.call(...args) === "[object Number]";
if(!b) throw new Error('args should a number')
let set = new Set(args);
let _this = this;
let res = [];
for(let i = 0; i < _this.length;i ++) {
if(!set.has(_this[i])) {
res.push(_this[i])
}
}
return res;
}
````
#### 24._union
> 并集
```js
Array.prototype._union = function(...args){
// [...]
let _this = this;
return [...new Set([...args,..._this].flat(2))];
}
```
#### 25._difference
> 过滤掉不想要的数据,参数是数组
```js
Array.prototype._difference = function (...args){
let b = Object.prototype.toString.call(...args) === '[object Array]';
if(!b){
throw new Error('args should a Array') ;
}
let set = new Set(...args);
let _this = this;
let res = [];
for(let i = 0; i < _this.length;i ++) {
if(!set.has(_this[i])) {
res.push(_this[i])
}
}
return res;
}
```
#### 26_range
> 按一定的规则返回下标,不传值是默认下标
```
Array.prototype._range = function(value = 0){
let _this = this;
// 1.获取这个数组的长度
let len = _this.length;
let result = [];
for(let i = value; i < len + value;i++){
result.push(i);
}
return result;
}
```
#### 27._dropRight
> 删除过滤掉右边数组
```js
Array.prototype._dropRight = function(size){
let _this = this;
return _this._filter((value,index)=>{
return index<_this.length-size;
})
}
```
#### 28._slice
>`**slice()**` 方法返回一个新的数组对象,这一对象是一个由 `begin` 和 `end` 决定的原数组的**浅拷贝**(包括 `begin`,不包括`end`)。原始数组不会被改变。
```js
Array.prototype._slice = function (Start = 0,End = this.length){
let _this = this;
if(Start<0) Start = 0;
if(Start>this.length) return [];
if(Start>End) End = _this.length;
if(End>=_this.length) End = _this.length;
let result = [];
for(let i = Start;i< End; i ++) {
result._push(_this[i]);
}
return result;
}
```
#### 29._concat
> `**concat()**` 方法用于合并两个或多个数组。此方法不会更改现有数组,而是返回一个新数组。
```js
Array.prototype._concat =function (...args){
let _this = this;
let res = _this;
args._forEach((item,index)=>{
if(Array.isArray(item)){
res._push(...item);
}else {
res._push(item);
}
});
return res;
}
```
#### 30._push
> 模拟push方法
```js
Array.prototype._push = function (...args){
let _this = this;
for(let i = 0; i < args.length; i++){
_this[this.length] = args[i];
}
return _this;
}
```