自省JS系列-3

273 阅读2分钟

前端自省系列😆有些是掘友的一些专栏文章的摘录,如果有不对的地方,请大家指出

instanceof 实现

/**
 * 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实现

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

防抖

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

/**
 * 防抖
 * @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 秒内只会执行一次

/**
 * 节流
 * @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,指向原构造函数

数组扁平化

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对象

 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);
        })
    }

变量提升和函数提升

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