【2019/09/20】前端面试

348 阅读10分钟

1. 介绍下项目(后台管理系统)

2. 前端人员、个人负责内容

3. 后台技术是否有使用过,熟不熟悉

4 react是什么样的语法

  • React发明了JSX,可以方便的利用HTML语法来创建虚拟DOM

    1. 结构顶层只能有一个元素
    1. class必须写className
    1. 标签必须是闭合状态 <input type='text'/>
    1. { }
    • 可以执行JS表达式
    • 花括号内有数组默认展开
    • 如果元素属性是一个变量需要花括号 src={obj.xx}
    • 花括号中不能写for循环
    1. 受控组件与非受控组件
    • 如果在表单元素上设置一个默认值(value / checked),该元素为受控组件(即无法输入其他内容)
    • 解决方案:加default
      • <input type='text' defaultValue="hahaha"/>
      • <input type='checkbox' defaultChecked/>
    1. dangerouslySetInnerHTML 在JSX中希望显示一些内容,不希望被自动转义(即在input输入框中输入

      哈哈

      ,在页面中显示文字,不显示标签,即通过dangerouslySetInnerHTML属性来设置
    • dangerouslySetInnerHTML={{__html:item}}
     <ul>
        {
            // 渲染页面
            this.state.arr.map((item, i) => {
                return (
                    <li key={i} 
                        onClick={this.delItem.bind(this,i)}
                        dangerouslySetInnerHTML={{__html:item}}
                    ></li>
                )
            })
        }
    </ul>
    
    1. label标签
    // label内的for属性 要写成 htmlFor
    <label htmlFor="text">输入内容</label>
    <input
        id="text"
        className="input"
        type="text"
        onChange={this.inputChange.bind(this)} //为了让input框value值改变 必须要写onChange方法
        value={this.state.val}
    />
    

6. 是否有做过权限

7. 有没有自己封装过组件,其他封装的有没有用过

8. 组件里如果定义初始状态

在constructor初始化 state

9. react生命周期

在新版本中,React 官方对生命周期有了新的 变动建议:

  • 使用getDerivedStateFromProps 替换componentWillMount;
  • 使用getSnapshotBeforeUpdate替换componentWillUpdate;
  • 避免使用componentWillReceiveProps;
  • 在constructor初始化 state;
  • 在componentDidMount中进行事件监听,并在componentWillUnmount中解绑事件;
  • 在componentDidMount中进行数据的请求,而不是在componentWillMount;
  • 需要根据 props 更新 state 时,使用getDerivedStateFromProps(nextProps, prevState);
  • 可以在componentDidUpdate监听 props 或者 state 的变化

11. 首屏渲染是在哪个阶段

mount阶段 只加载一次

Constructer

ComponentWillMount

Render

ComponentDidMount

12. node用没用过

13. ES6用过哪些,字符串和数组里买呢有哪些方法是ES6的

1)let var const的区别

  • let会产生块级作用域
  • let const 不存在变量提升
  • let会形成“暂时性死区”
    • ES6明确规定,如果区块中存在 let 和 const 命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。 总之,在代码块内,使用let命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”
  • let const 不可重复声明

作用域链:函数执行形成一个私有的作用域(保护私有变量),进入到私有作用域当中,首先变量提升(声明过的变量是私有的),接下来代码执行:

  • 1.执行的时候遇到一个变量,如果这个变量是私有的,那么按照私有处理即可
  • 2.如果当前这个变量不是私有的,我们需要向他的上级作用域进行查找,上级如果也没有,则继续向上查找,一直找到window全局作用域为止,我们把这种查找机制叫做作用域链
    • 1)如果上级作用域中有这个变量,我们操作的都是上级作用域链中的变量(假如我们在当前作用域把值改了,相当于把上级作用域中的这个值给修改了)
    • 2)如果上级作用域中没有这个变量(找到window也没有),分两种情况
      • 变量 = 值 :相当于给window设置了一个属性,以后再操作window下就有了
      • alert(变量):想要输出这个变量,但是此时是没有的,所以会报错

2)变量的解构赋值

解构可以理解就是一个作用:简化你变量赋值的操作。

3)字符串扩展

针对字符串扩展这个,个人感觉模版字符串使用的频率比较高。模版字符串解放了拼接字符串带来的繁琐操作的体力劳动。

  • includes(): 返回布尔值,表示是否找到了参数字符串
  • startWith(): 返回布尔值,表示参数字符串是否在原字符串的头部
  • endWith(): 返回布尔值,表示参数字符串是否在原字符串的尾部
  • trimStart(): 返回字符串,表示消除参数字符串开头的空格
  • trimEnd(): 返回字符串,表示消除参数字符串结尾的空格

4)函数扩展

  • rest参数
    • ES6引入rest参数(形式是...变量名),用于获取多余的参数,这样就不需要使用arguments对象了。rest参数搭配的变量是一个数组(arguments是一个类数组来的),该变量将多余的参数放入数组中。

5)箭头函数

使用箭头函数注意点:

  • 函数体内的this对象,就是定义所在的对象,而不是使用时所在的对象。
  • 不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误。
  • 不可以使用arguments对象,该对象在函数体内不存在的,如果要用,可以用rest参数代替。
  • 不可以使用yield命令,因此箭头函数不能用作Generator函数。

6)promise对象

  • 假如你需要用ajax进行多次请求,而且,每次请求都依赖上一次请求返回的数据来作为参数,然后继续发出请求,可能会有更多的嵌套,如此一层一层的执行,无疑是消耗了更多的等待时间,而且多个请求之间如果有先后关系的话,就会出现回调地狱,ES6想了办法整治这种情况,这时候Promise 诞生了
  • Promise 对象是全局对象,你也可以理解为一个类,创建Promise实例的时候,要有那个new关键字。Promise构造函数接受一个函数作为参数,其中有两个参数:resolve 和reject,两个函数均为方法。resolve方法用于处理异步操作成功后业务(即从 pending 变为 resolved)。reject方法用于操作异步操作失败后的业务(即从 pending 变为 rejected)。在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。

7)new set

产生不重复的数组

包括数组、Set 和 Map 结构、某些类似数组的对象(比如arguments对象、DOM NodeList 对象)、Generator 对象,以及字符串)

8)for of 循环

for…of循环可以使用的范围:

9)class

  • class的写法,能让对象原型的功能更加清晰,更加符合面向对象语言的特点
  • constructor是类的默认方法,就算不定义,也会有一个空的constructor。
  • class内部默认就是严格模式。不存在变量提升
  • 正常情况下,this的指向都是类的实例
  • class继承

 //ES6 class继承
class A {
    constructor() {
        console.log(arguments); //Tom 子类的实例把参数传递给子类的构造函数,
        this.name = arguments;
        this.x = 100;
    }
    getX() {
        console.log(this.x);
    }
}
class B extends A{//类似与实现了原型继承
    constructor(){
        super(...arguments)
        //super类似于call继承,在这里相当于把父类的constructor执行,并且让方法中的this是B的实例,super当中传递的实参都是给A的
        this.y = 200;
        console.log(...arguments)
    }
    getY (){
        console.log(this.y);
    }
}
let f = new B('Tom','Jerry');
console.dir(f);

15. ES6以下会产生块级作用域吗

不会

16. 闭包是什么?闭包是为了解决什么问题

函数套函数,子函数使用父函数的参数或者变量

并且子函数被外界所引用,此时父级形成闭包环境

父级的参数或者变量不被浏览器垃圾回收机制回收.

闭包的作用

  • 实现公有变量
  • 可以做缓存(存储结构)
  • 可以实现封装,属性私有化
  • 模块化开发,防止污染全局变量

闭包的缺点及解决

内存泄漏:占用的内存没有及时释放。内存泄露积累多了就容易导致内存溢出。

常见的内存泄露:

  • 意外的全局变量
  • 没有及时清理的计时器或回调函数
  • 闭包

18. map和filter的区别

  • map:循环数组,它的返回值为新的数组
  • filter
    • 数组的过滤,过滤条件成立的这个值
    • 参数: function(item,i,all){ return 成立的布尔值 }
    • filter方法返回值 为过滤后的新数组

19. js绑定事件有哪几种方式

  • 内联
  • 使用.onclick的方式

以上两种方式都是存在一个弊端的,就是一个元素只能添加一个事件。第一种就不用说了,写在行内就一个属性。

  • 使用事件监听addEventListener的方式
    • 三个参数:
      • 事件类型,不需要添加上on
      • 事件函数
      • 是否捕获(布尔值),默认是false,即不捕获,那就是冒泡。

20. 事件委托在哪个阶段,事件委托的原理,事件触发是在哪个阶段?

1) 事件的传播机制:(事件流/事件模型机制)

  • 冒泡传播:

触发当前元素的某一个事件(比如点击事件)行为,不仅当前元素事件行为触发,而且其祖先元素的相关事件行为也会被依次触发,这种机制就是事件的传播机制

  • 这种传播分成三个阶段。
    • 第一阶段:从window对象传导到目标节点(上层传到底层),称为“捕获阶段”(capture phase)。
    • 第二阶段:在目标节点上触发,称为“目标阶段”(target phase)。
    • 第三阶段:从目标节点传导回window对象(从底层传回上层),称为“冒泡阶段”(bubbling phase)。

这三个阶段的传播模型,使得同一个事件会在多个节点上触发

2) DOM0级事件与DOM2级事件绑定方式

  • xxx.onxxx = function(){};

    • DOM0级事件绑定方式,只有冒泡阶段。如果事件绑定的是目标元素,就按照目标事件的先后顺序依次绑定
  • xxx.addEventListener('xxx',function(){},false);

    第三个参数:

    • 为false:是控制绑定的方法在事件传播的冒泡阶段(或者目标阶段)执行;
    • 为true:代表让当前方法在事件传播的捕获阶段触发执行(这种捕获阶段

21. 页面的数据存储有哪几种方式(cookie、session)

常见的本地存储:

  • 1). cookie (cookie 是http协议的一部分)
  • 2). localStorage 本地存储(HTML5新增的,浏览器技术)
  • 3). sessionStorage 会话存储(HTML5新增,浏览器技术)
  • localStorage: 本地永久存储(除用户或者我们手动删除)
  • localStorage 是挂载在window上的对象

关于cookie与本地存储的区别:

  • 1). cookie在浏览器和服务器间来回传递。而sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存。
  • 2). cookie数据还有路径(path)的概念,可以限制cookie只属于某个路径下。存储大小限制也不同,cookie数据不能超过4k,同时因为每次http请求都会携带cookie,所以cookie只适合保存很小的数据,如会话标识。sessionStorage和localStorage 虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大。
  • 3). 数据有效期不同,sessionStorage:仅在当前浏览器窗口关闭前有效,自然也就不可能持久保持;localStorage:始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据;cookie只在设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭。
  • 4). 作用域不同,sessionStorage不在不同的浏览器窗口中共享,即使是同一个页面;localStorage 在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的。Web Storage 支持事件通知机制,可以将数据更新的通知发送给监听者。Web Storage 的 api 接口使用更方便。