首页 > 技术文章 > 手写常见JS方法

bingcola 2021-08-31 15:26 原文


判断数据类型

function checkedType(target) {
    return Object.prototype.toString.call(target).slice(8, -1);
}


console.log(checkedType([])); // "Array"
console.log(checkedType({})); // "Object"
console.log(checkedType(null)); // "Null"
console.log(checkedType(undefined)); // "Undefined"

深拷贝

// 实现深度克隆---对象/数组
function deepCopy(target) {
    var result; // 初始化变量result 成为最终克隆的数据
    var targetType = checkedType(target); // 判断拷贝的数据类型
    if (targetType === 'Object') {
        result = {};
    } else if (targetType === 'Array') {
        result = [];
    } else {
        return target;
    }
    // 遍历目标数据
    for (let key in target) {
        // 获取遍历数据结构的每一项值。
        let value = target[key];
        // 判断目标结构里的每一值是否存在对象/数组
        if (checkedType(value) === 'Object' || checkedType(value) === 'Array') {
            // 继续递归遍历获取到value值
            result[key] = deepCopy(value);
        } else {
            // 获取到value值是基本的数据类型或者是函数。
            result[key] = value;
        }
    }
    return result;
}


var obj1 = {
    'name': 'zhangsan',
    'age': 18,
    'language': [1, [2, 3],
        [4, 5]
    ]
};

var obj2 = deepCopy(obj1);
obj2.name = "lisi";
obj2.language[1] = ["二", "三"];


console.log('obj1', obj1); // {name: "zhangsan", age: 18, language: [1, [2, 3], [4, 5]]}
console.log('obj2', obj2); // {name: "lisi", age: 18, language: [1, ["二", "三"], [4, 5]]}

对象是否全等

// 判断obj是否为对象或数组
function isObject(obj) {
	return (typeof obj === 'object' && obj !== null);
}

// 全相等函数
function isEqual(obj1, obj2) {
	if (!isObject(obj1) || !isObject(obj2)) {
		return obj1 === obj2
	}

	if (obj1 === obj2) {
		return true
	}

	if (Object.keys(obj1).length !== Object.keys(obj2).length) {
		return false
	}

	for (const key in obj1) {
		let res = isEqual(obj1[key], obj2[key]);
		if (!res) {
			return false
		}
	}
	return true
}


const obj1 = {
	a: 1,
	b: {
		x: 'aa',
		y: 'bb',
		z: 'cc'
	},
	c: [1, 2, 3]
}

const obj2 = {
	a: 1,
	b: {
		x: 'aa',
		y: 'bb',
		z: 'cc'
	},
	c: [1, 2, 3]
}


console.log(isEqual(obj1, obj2)); // true

防抖

function debounce(fn,delay) {
    let timer;
    return function () {
        clearTimeout(timer);
        timer = setTimeout(() => {
            fn.apply(this,arguments);
        },delay);
    }
}

节流

function throttle(fn, delay) {
	let flag = true;
	return function () {
		if (!flag) { return; }
		flag = false;
		setTimeout(() => {
			fn.apply(this, arguments);
			flag = true;
		}, delay);
	}
}

数组拍平

function flat(arr) {
	const isDeep = arr.some(item => Array.isArray(item));

	if (!isDeep) {
		return arr
	}
	const res = [].concat(...arr);
	// 等价于
	//const res = Array.prototype.concat.apply([], arr);
	
	return flat(res);

}


var arr = [[1, 2], 3, [4, 5, [6, 7, [8, 9, [10, 11]]]]]; // 多维数组

console.log(flat(arr)); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]

数组去重

let arr = [1, 2, 2, 3, 'x', 4, 3, 2, 1, 'x'];

// 方法一:利用filter
function unique1(arr) {
	return arr.filter((item, index, self) => {
		return self.indexOf(item) == index
	})
}

// 方法二:利用Set
function unique2(arr) {
	return [...new Set(arr)];
	// 或
	//return Array.from(new Set(arr));
}

// 方法三:利用for循环
function unique3 (arr) {
  let result = []; 
  for (var i = 0; i < arr.length; i++) {
    if (result.indexOf(arr[i]) == -1) result.push(arr[i]);
  }
  return result;
}

new函数

function _new(func, ...args) {
    // 1. 创建空对象
    let obj = {};
    // 2. 空对象的_proto_指向了构造函数的prototype成员对象
    obj.__proto__ = func.prototype; // 1、2步合并就相当于 let obj = Object.create(func.prototype)
    // 3. 使用apply调用构造器函数,属性和方法被添加到 this 引用的对象中
    let result = func.apply(obj, args);
	// 4. 确保 new 出来的是个对象
    return typeof result === 'object' ? result : obj;
}


function Person(name, age) {
  this.name = name;
  this.age = age;
}

let obj = _new(Person, 'xia', 20);

console.log(obj); //{name: 'xia', age: 20}

ajax

// 1.创建XMLHttpRequest对象
var ajax = new XMLHttpRequest();

// 2.绑定监听事件
ajax.onreadystatechange = function () {   
	// 当异步请求状态变为4时,并且返回的状态码为200,接收响应成功
	if (ajax.readyState == 4 && ajax.status == 200) {
	    // 如果能够进到这里,说明数据完美的回来了,并且请求的页面是存在的    
	    console.log(ajax.responseText); // 输入相应的内容    
    }
}

// 3.调用open方法传入三个参数:请求方式(GET/POST)、url、同步异步(true/false);
ajax.open('get','getStar.php?starName='+name);

// 4.发送请求
ajax.send();

推荐阅读