前端面试题【1】——JS部分

 

  • null常用来描述空值,undefined常用来表示变量没有初始化或属性/元素不存在

    null==undefined;//true
    null===undefined;//false
  • JS加载的方式

    1. 同步:JS本身运行就是同步的

    2. defer,只适用于外部脚本文件,告诉浏览器立即下载但延迟执行

    3. async,同只适用于外部脚本文件,不让页面等待脚本下载和执行,从而异步加载页面其他内容,JS加载完该脚本文件会立即执行且会在页面load事件前执行,但不能保证脚本会按顺序执行

  • JS基本数据类型:String Number Boolean null undefined Symbol(ES6新出的)Object(包括Array)

  • JS判断数据类型的方法

    1. typeof 特殊:typeof(null)==='object'//true 是JS很多年了的一个bug

    2. instanceof 基于原型链

    3. Object.prototype.toString

    4. constructor

    5. jQuery.type()

  • JS中call,bind,apply

    1. 共同点:都是用来改变this的指向

    2. call和apply不同点:两者第一个参数都是this要指向的对象,但后面传入的参数列表,call的可以是任意的,但apply的必须是数组

    3. call和bind不同点:call改了this指向后会继续执行函数,bind改过后不能执行函数,会返回一个绑定新this的函数

    4. call的应用:翻转字符串,Array.prototype.reverse.call(str.split(''))

    5. apply的应用:求极值,Math.max.apply(null,arr)

    6. 手写bind

      Funtion.prototype.bind=function(context){
          var self=this;
          return function(){
              return self.apply(context,arguments);
          }
      }
  • JS区分大小写,HTML不区分,XHTML不区分

  • 如何判断NaN,用x==NaN无法判断,NaN和任何值不相等,包括自身

    1. 可用X!=X来判断

    2. 或者用isNaN(),参数为NaN或非数字值(字符串或函数)会返回true

  • 创建对象的方法

    1. 对象直接量:var obj={}

    2. new创建:var obj=new Object();

    3. 原型创建:Object.prototype

    4. Object.create()

  • 创建对象的模式: https://blog.youkuaiyun.com/weixin_45026432/article/details/105939054

  • 继承的多种方法: https://blog.youkuaiyun.com/weixin_45026432/article/details/105944113

  • 事件触发三个阶段

    1. window往事件触发处传播,遇到注册的捕获事件会触发

    2. 传播到事件触发时会触发注册的事件

    3. 从事件触发处往window传播,遇到注册的冒泡事件会触发(相关:事件委托下面)

      (但,如果给一个body中子节点同时注册冒泡和捕获,会按注册的顺序触发)

  • 事件委托

    解决“事件处理程序过多”的问题 来源于事件冒泡

    (网上大佬的例子:快递可以一个一个人取,但由前台先统一取,然后每个人都去前台那里取会更好)

    <ul id="myLinks">
        <li id="aaa">aaa</li>
        <li id="bbb">bbb</li>
        <li id="ccc">ccc</li>
    </ul>
    <script>
        var list=document.getElementById('myLinks');
        EventUtil.addHandler(list,"click",function(event){
            event=EventUtil.getEvent(event);
            var target=EventUtil.getTarget(event);
            switch(target.id){
                case 'aaa':
                    document.title='change aaa';
                    break;
                case 'bbb':
                    document.title='change bbb';
                    break;
                case 'ccc':
                    document.title='change ccc';
                    break;
            }
        })
    </script>
  • 函数作用域& 块作用域 https://blog.youkuaiyun.com/weixin_45026432/article/details/105945317

  • 提升

    1. 包括变量和函数在内的所有声明(赋值或其他运行逻辑不会)都会在任何代码被执行前首先被处理

    2. 每个作用域都会进行提升操作

    3. 函数声明会被提升,但函数表达式不会提升,即使是具名的函数表达式,名称标识符在赋值前也无法在所在作用域中使用

      var foo=function bar(){}//foo和bar在这行代码前都无法调用
  • 闭包 https://blog.youkuaiyun.com/weixin_45026432/article/details/105946405

  • 如何找出类关系

    1. a instanceof Foo 在a的整条原型链中是否有指向Foo.prototype的对象

    2. Foo.prototype.isPrototypeOf(a) a的整条原型链中是否出现过Foo.prototype

    3. Object.getPrototypeOf(a)===Foo.prototype ES5中用

    4. a.__proto__===Foo.prototype ES6前非标准,绝大多数浏览器支持

  • 关于this https://blog.youkuaiyun.com/weixin_45026432/article/details/105947151

  • Promise

    在这之前用的是回调来实现需求,但回调会把控制权交给第三方,有可能会带来一系列控制问题和信任问题,也有可能出现不受欢迎的回调地狱

    而Promise就是为了不把继续回调控制权交给第三方,而是希望第三方给我们提供了解任务何时结束的能力,然后自己代码来决定下一步

    创建: new Promise(..)构造器,必须提供至少一个函数回调,可提供两个函数回调

    其中的状态有三个术语:resolve决议、fulfill完成、reject拒绝

    第一个回调通常用于标识Promise已完成,第二个标识被拒绝

    但!第一个回调实际上的结果可能是完成或拒绝,但第一个参数回调的行为和resolve一样,故回调的第一个名称基本都是resolve,第二个都是reject

    var promise = new Promise(function(resolve, reject) {
        if (..){
            resolve(value);
        } else {
            reject(error);
        }
    });
    ​
    promise.then(function(value) {
     // 成功
    }, function(value) {
     // 失败
    }).catch(function(error){..})

    .then和.catch

    .then([用于完成回调],[用于拒绝回调])

    默认拒绝函数只是将错误重新抛出,错误可以沿着promise链传播下去直到遇到显式定义的拒绝处理函数

    默认完成函数只是将接受到的任何传入值传给下一个promise

    .catch([拒绝回调函数]) 等价于 .then(null,..)

    一些其他API

    • Promise.all(..) 用于并行执行多个任务

      Promise.all([p1,p2]).then(function(){..})

      以数组形式同时发送多个ajax,返回的主promise在且仅在所有成员promise都完成后才会完成,若有任何一个被拒绝,则主promise立即被拒绝,并丢弃结果

    • Promise.race([..]) 只响应第一个完成的Promise,其他均拒绝且丢弃

    • Promise.none([..]) 和all情况相反,只有所有成员都被拒绝后才完成

    • Promise.first([..]) 只要完成第一个,就会忽略后续的任何拒绝和完成

    • Promise.last([..]) 只有最后完成的一个胜出

  • const let var

    const:用于创建常量,必须要有显式的初始化(undefined必须是const a = undefined),常量不是对值本身的限制,而是对赋值的那个变量的限制,故若该值是复杂值,仍可改变(const a=[1,2,3]; a.push(4);)此时的a不持有一个常量数组,持有的是一个指向数组的常量引用

    let:let允许声明一个作用域被限制在块级中的变量、语句或者表达式,且是在编译时才初始化

    var: var声明的变量只能是全局或者整个函数块的

  • 箭头函数

    • 箭头函数总是函数表达式,不存在箭头函数声明,是匿名函数表达式,故没有用于递归/事件绑定的命名引用

    • 只有在表达式短时用才有足够的好处,长时无需用

    • 只有在函数体表达式个数大于1时或函数体包含非表达式时才用{}

      var f1=()=>12;
      var f2=x=>x*2;
    • 主要设计目的是改变this的行为特性,在箭头函数中,this的绑定不是动态的,而是可预测的

      带来的优势:

      var con={
          make:function(..){
              var self=this;
              btn.addEventListener("click",function(){..},false);//在这里面需要用到this时,需要从外面绑定
          }
      }
      改:
      var con={
          make:function(..){
              btn.addEventListener("click",()=>{..},false);//此时用了箭头函数就不需要另外绑定
              //此时this会和当前函数指向相同的值
          }
      }

      带来的劣势:

      var con={
          make:(..)=>{
              //..
              this.helper();
          },
          helper:(..)=>{..};
      }
      //此时的this不会指向con,this是从包围的作用域中继承来的,故this指向全局作用域
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值