前端JavaScript常见面试题(一)

时间过得好快,2021年好像转瞬即逝,再不久,就迎来了金九银十了,不知道准备跳槽的同学们有没有准备好面试呢?

今天趁此整理一下自己之前面试过程中,收集的或者遇到的面试题。

undefined和undeclared的区别?

  • undefined:在作用域中声明还没有赋值的变量
  • undeclared:没有在作用域中声明过的变量

对于undeclared变量,浏览器会报错误,例如:ReferenceError: b is not defined

null 和 undefined 的区别?

undefinednull 都是基本数据类型,undefined代表的含义是没有定义,null代表的含义是空对象,一般变量声明没有定义会返回undefined

null在使用typeof 检测的时候会返回object,我们可以使用typeof来判断一个变量是否为undefined,也可以使用===或者!==来判断一个变量是否有值,但是不能使用==来判断。

console.log(null == undefined); //true
console.log(null === undefined); //false
console.log(typeof null); //object

isNaN 和 Number.isNaN 函数的区别?

  • isNaN:接收参数后,会尝试将这个参数转换为数值,任何不能被转换为数值的值都会返回true。
  • Number.isNaN:会首先判断是否为数字,如果是数字再继续判断是否为NaN。

Number.isNaNNaN的判断最准确。

常用正则表达式

匹配 16 进制颜色值:

const reg = /#([0-9a-fA-F]{6}|[0-9a-fA-F]{3})/g;

匹配日期,如 yyyy-mm-dd 格式:

const dateCheck = = /^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$/;

匹配 qq 号:

const qqCheck = /^[1-9][0-9]{4,10}$/g;

手机号码:

const phone = /^1[34578]\d{9}$/g;

密码强度正则(最少6位,包括至少1个大写字母,1个小写字母,1个数字,1个特殊字符)

const pPattern = /^.*(?=.{6,})(?=.*d)(?=.*[A-Z])(?=.*[a-z])(?=.*[!@#$%^&*? ]).*$/;

Email正则:

const ePattern = /^([A-Za-z0-9_-.])+@([A-Za-z0-9_-.])+.([A-Za-z]{2,4})$/;

身份证号正则:

const cardP = /^[1-9]d{5}(18|19|([23]d))d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)d{3}[0-9Xx]$/;

手写 call、apply 及 bind 函数

call 函数的实现步骤:

  • 1.判断调用对象是否为函数,即使我们是定义在函数的原型上的,但是可能出现使用 call 等方式调用的情况。
  • 2.判断传入上下文对象是否存在,如果不存在,则设置为 window 。
  • 3.处理传入的参数,截取第一个参数后的所有参数。
  • 4.将函数作为上下文对象的一个属性。
  • 5.使用上下文对象来调用这个方法,并保存返回结果。
  • 6.删除刚才新增的属性。
  • 7.返回结果。
Function.prototype.myCall = function(context) {
  // 判断调用对象
  if (typeof this !== "function") {
    console.error("type error");
  }

  // 获取参数
  let args = [...arguments].slice(1),
    result = null;

  // 判断 context 是否传入,如果未传入则设置为 window
  context = context || window;

  // 将调用函数设为对象的方法
  context.fn = this;

  // 调用函数
  result = context.fn(...args);

  // 将属性删除
  delete context.fn;

  return result;
};

apply 函数的实现步骤:

  • 1.判断调用对象是否为函数,即使我们是定义在函数的原型上的,但是可能出现使用 call 等方式调用的情况。
  • 2.判断传入上下文对象是否存在,如果不存在,则设置为 window 。
  • 3.将函数作为上下文对象的一个属性。
  • 4.判断参数值是否传入
  • 4.使用上下文对象来调用这个方法,并保存返回结果。
  • 5.删除刚才新增的属性
  • 6.返回结果
Function.prototype.myApply = function(context) {
  // 判断调用对象是否为函数
  if (typeof this !== "function") {
    throw new TypeError("Error");
  }

  let result = null;

  // 判断 context 是否存在,如果未传入则为 window
  context = context || window;

  // 将函数设为对象的方法
  context.fn = this;

  // 调用方法
  if (arguments[1]) {
    result = context.fn(...arguments[1]);
  } else {
    result = context.fn();
  }

  // 将属性删除
  delete context.fn;

  return result;
};

bind 函数的实现步骤:

  • 1.判断调用对象是否为函数,即使我们是定义在函数的原型上的,但是可能出现使用 call 等方式调用的情况。
  • 2.保存当前函数的引用,获取其余传入参数值。
  • 3.创建一个函数返回
  • 4.函数内部使用 apply 来绑定函数调用,需要判断函数作为构造函数的情况,这个时候需要传入当前函数的 this 给 apply 调用,其余情况都传入指定的上下文对象。
Function.prototype.myBind = function(context) {
  // 判断调用对象是否为函数
  if (typeof this !== "function") {
    throw new TypeError("Error");
  }

  // 获取参数
  var args = [...arguments].slice(1),
    fn = this;

  return function Fn() {
    // 根据调用方式,传入不同绑定值
    return fn.apply(
      this instanceof Fn ? this : context,
      args.concat(...arguments)
    );
  };
};

持续更新!

「点点赞赏,手留余香」

0

给作者打赏,鼓励TA抓紧创作!

微信微信 支付宝支付宝

还没有人赞赏,快来当第一个赞赏的人吧!

声明:本站所有资源及文章均来源于网络及用户分享或为本站原创,仅限用于学习和研究,任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。
码云笔记 » 前端JavaScript常见面试题(一)

发表评论

IT互联网行业相关广告投放 更专业 更精准

立即查看 联系我们