记录手写JS
Posted 三水草肃
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了记录手写JS相关的知识,希望对你有一定的参考价值。
手写JS:
有了这些手写JS,从此不在怕面试手撕JS
不定时更新
手写Call
Function.prototype.myCall = function (context) {
if (typeof this !== 'function') {
throw new TypeError('error')
}
context = context || window
context.fn = this
const args = [...arguments].slice(1)
const result = context.fn(...args)
delete context.fn
return result
}
/* apply */
Function.prototype.myApply = function (context) {
if (typeof this !== 'function') {
throw new TypeError('Error')
}
context = context || window
context.fn = this
let result
if (arguments[1]) { // 取得除了fn之外的数据
result = context.fn(...arguments[1])
} else {
result = context.fn()
}
delete result.fn
return result
}
/* bind */
Function.prototype.myBind = function (context) {
if (typeof this !== 'function') {
throw new TypeError('error')
}
const that = this
const args = [...arguments].slice(1)
return function F() {
if (this instanceof F) {
return new that(...args, ...arguments)
}
return that.apply(context, args.concat(...arguments))
}
}
深拷贝
function deepClone(obj) {
let objClone = Array.isArray(obj) ? [] : {};
if (obj && typeof obj === "object") {
for (key in obj) {
if (obj.hasOwnProperty(key)) {
if (obj[key] && typeof obj[key] == "object") {
objClone[key] = deepClone(obj[key]);
} else {
objClone[key] = obj[key];
}
}
}
}
return objClone;
}
手写instance
function instanceOf_my(left, right) {
const rightPrototype = right.prototype
let leftInst = Object.getPrototypeOf(left)
while(true) {
if(leftInst === null) {
return false
}
if(leftInst === rightPrototype) {
return true
}
leftInst = Object.getPrototypeOf(leftInst)
}
}
扩展instanceof,判断 let num = 1
class MyNumber {
static [Symbol.hasInstace](instance) {
return typeof instace === 'number'
}
}
console.log(num instanceof MyNumber)
数组扁平化
function flatten(arr) {
return arr.reduce((prev, curr) => {
return prev.concat(Array.isArray(curr) ? flatten(curr) : curr)
}, [])
}
合并多个数组
function fn() {
return arr = [].concat.apply([],arguments)
}
把类数组转化为数组,类数组是原型中有length属性
[].shift.call(arguments)
实现new
function My_new () {
let res = {}
let con = [].shift.call(arguments)
res.__proto__ = con.prototype
let conRes = con.apply(res,arguments)
return conRes instanceof Object ? conRes : res
}
// 节流
function throttle(fn, time) {
let last = 0;
return function () {
let context = this;
let args = arguments;
let now = +new Date();
if (now - last >= time) {
last = now;
fn.apply(context, args);
}
};
}
// 防抖
function debounce(fn, time) {
let timer = null;
return function () {
let context = this;
let args = arguments;
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(() => {
fn.apply(context, args);
timer = null;
}, time);
};
}
书写map
Array.function.Map = function (cb, context) {
let newArr = []
for (let i = 0; i < this.length; i++) {
if (cb && typeof cb === 'function') {
let val = cb.call(context, this[i], i, this)
newArr.push(val)
}
}
return newArr
}
数组乱序
let arr = [9,8,7,5,6,5,4,5,2,2,2]
arr.sort(() => {
return Math.random() - 0.5
})
冒泡排序
/* 两两比较 */
function bubleSort(arr) {
var len = arr.length
for (let outer = len; outer >= 2; outer--) {
for (let inner = 0; inner <= outer - 1; inner++) {
if (arr[inner] > arr[inner + 1]) {
[arr[inner], arr[inner + 1]] = [arr[inner + 1], arr[inner]]
}
}
}
return arr
}
console.log(bubleSort([1, 2, 5, 44, 56, 5, 85, 5]));
function fn(arr) {
for(let i = 0 ; i < arr.length -1; i++) {
for(let j = i+1;j <arr.length;j++){
if(arr[i] > arr[j]) {
[arr[i], arr[j]] = [arr[j], arr[i]]
}
}
}
return arr
}
/* 选择排序: 遍历自身以后的元素,最小的元素跟自己调换位置 */
function selectSort(arr) {
var len = arr.length
for (let i = 0; i < len - 1; i++) {
for (let j = 1; j < len; j++) {
if (arr[i] > arr[j]) {
[arr[i], arr[j]] = [arr[j], arr[i]];
}
}
}
return arr
}
/* 插入排序:即将元素插入到已排序好的数组中 */
function insertSort(arr) {
for (let i = 1; i < arr.length; i++) {
for (let j = i; j > 0; j++) {
if (arr[j] < arr[j - 1]) {
[arr[j], arr[j - 1]] = [arr[j - 1], arr[j]];
} else {
break;
}
}
}
return arr;
}
Number 扩展
Function.prototype.method = function (name, func) {
this.prototype[name] = func
// Number.intergegege = function () { return Math[this < 0 ? 'ceil' : 'floor'](this) }
return this
}
Number.method('intergegege', function () {
return Math[this < 0 ? 'ceil' : 'floor'](this)
})
console.log(Boolean instanceof Function) // true
随机数
function getRandom(start, end) {
return Math.floor(Math.random() * (end - start + 1) + start)
}
洗牌算法
function shuas(arr) {
for (let i = 0; i < arr.length; i++) {
const j = Math.floor(Math.random() * (i + 1));
[arr[i], arr[j]] = [arr[j], arr[i]]
}
return arr
}
console.log(shuas([1,5,6,8,6,5,6,2,21,4,54]));
手写Object.is()
function ObjectIs(x, y) {
if (x === y) {
return x !== 0 || 1 / x === 1 / y;
} else {
return x !== x && y !== y;
}
}
console.log(NaN == NaN) false
console.log(+0 == -0)true
console.log(ObjectIs(+0 , -0))false
console.log(ObjectIs(+NaN , -NaN)) true
寄生组合继承
function Parent5 () {
this.name = 'parent5';
this.play = [1, 2, 3];
}
function Child5() {
Parent5.call(this);
this.type = 'child5';
}
Child5.prototype = Object.create(Parent5.prototype);
Child5.prototype.constructor = Child5;
数组扁平化
function flatten(arr) {
return arr.reduce((prev, curr) => {
return prev.concat(Array.isArray(curr) ? flatten(curr) : curr)
}, [])
}
while(arr.some(Array.isArray)) {
arr = [].concat(...arr)
}
Map手写
Array.prototype.map = function(callbackFn, thisArg) {
// 处理数组类型异常
if (this === null || this === undefined) {
throw new TypeError("Cannot read property 'map' of null or undefined");
}
// 处理回调类型异常
if (Object.prototype.toString.call(callbackfn) != "[object Function]") {
throw new TypeError(callbackfn + ' is not a function')
}
// 草案中提到要先转换为对象
let O = Object(this);
let T = thisArg;
let len = O.length >>> 0;
let A = new Array(len);
for(let k = 0; k < len; k++) {
// 还记得原型链那一节提到的 in 吗?in 表示在原型链查找
// 如果用 hasOwnProperty 是有问题的,它只能找私有属性
if (k in O) {
let kValue = O[k];
// 依次传入this, 当前项,当前索引,整个数组
let mappedValue = callbackfn.call(T, KValue, k, O);
A[k] = mappedValue;
}
}
return A;
}
length >>> 0, 字面意思是指"右移 0 位",但实际上是把前面的空位用0填充,这里的作用是保证len为数字且为整数
reduce手写
Array.prototype.reduce = function(callbackfn, initialValue) {
// 异常处理,和 map 一样 // 处理数组类型异常
if (this === null || this === undefined) {
throw new TypeError("Cannot read property 'reduce' of null or undefined");
}
// 处理回调类型异常
if (Object.prototype.toString.call(callbackfn) != "[object Function]") {
throw new TypeError(callbackfn + ' is not a function')
}
let O = Object(this);
let len = O.length >>> 0;
let k = 0;
let accumulator = initialValue;
if (accumulator 以上是关于记录手写JS的主要内容,如果未能解决你的问题,请参考以下文章