自省JS-3

instanceof 实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
* obj是否在targetObj的原型链上
*/
function myInstanceOf(obj, targetObj) {
let objProto = obj.__proto__, //instanceof 左边的值
targetProto = targetObj.prototype; //instanceof 右边的值


while (true) {
if (objProto === null) return false;
if (targetProto === null) return false;
if (objProto === targetProto) return true;
//如果未发现相等,则像上级寻找原型,一直到顶级原型链,返回null为止
objProto = objProto.__proto__;
}
}

Array.isArray实现

1
2
3
Array.myIsArray = function(o) {
return Object.prototype.toString.call(o) === "[object Array]";
}

防抖

n 秒内函数只会执行一次,如果 n 秒内高频事件再次被触发,则重新计算时间

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/**
* 防抖
* @param {function}} fn
* @param {number} wait
*/
function debounce(fn, wait = 1000) {
let timeOutId;
return function () {
//修复调用防抖函数时的this指向问题
let context = this;
if (timeOutId) {
clearTimeout(timeOutId);
}

timeOutId = setTimeout(() => {
fn.apply(context, arguments);
}, wait);
};
}

节流

n 秒内只会执行一次

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
* 节流
* @param {Function} fn
* @param {Number} wait
*/
function throttle(fn, wait) {
let timeOutId = null;

return function () {
let context = this;
//如果节流时间间隔已过,则执行
if (!timeOutId) {
timeOutId = setTimeout(() => {
fn.apply(context, arguments);
//执行结束后,重置时间间隔判断
timeOutId = null;
}, wait);
}
};
}

__proto__prototype

  • __proto__是对象有的属性,指向构造该对象的构造函数原型
  • prototype是函数的属性,这个属性是个指针,指向原型对象,原型对象中有个属性constructor,指向原构造函数

数组扁平化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function flatArr(arr) {
return arr.join(",").split(",");
}

function flatArrReduce(arr,result = []) {
arr.forEach(item => {
if(Array.isArray(item)) {
flatArrReduce(item,result);
}else {
result.push(item);
}
})
return result;
}

获取远程图片宽高

需要在浏览器中执行 Image是DOM对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function imgSize(url) {
return new Promise((resolve, reject) => {
let img = new Image();
img.src = url;
img.onload = function () {
const imgInfo = {
width: img.naturalWidth,
height: img.naturalHeight
}
resolve(imgInfo);
}
}).then(res => {
console.log(res);
})
}

变量提升和函数提升

  • 变量提升提升的是标识符,也就是变量的声明,赋值操作并没有提升
  • 函数声明是整体提升
1
2
3
4
5
6
7
console.log(a); //undefined 此时变量a被提升 所以是undefined,已定义,未赋值
var a = 1;
console.log(a); //1
fun(); // func 函数声明整体提升
function fun() {
console.log(fun);
}