前端面试题 二

44 阅读4分钟

一、 css选择器有哪些,它们的优先级顺序是怎样的

!important > 内联 > ID选择器 > 类选择器 > 标签选择器

  • id选择器: #app
  • 类选择器: .app
  • 标签选择器: div|p
  • 伪类选择器: 主要用于区分元素的不同状态或行为 :root | :link | :visited
  • 伪元素选择器: 主要用于指定某些元素的特定部分 ::before | ::after
  • 属性选择器: 选取带有指定属性的元素 [attribute] | [attribute=value]

二、 css行内元素和块元素有什么区别

  • 块元素:
    • 有自己的宽高,可自定义width和height; 高度、行高、margin、padding都可以控制
    • 独自占据一行(除float外)
    • 可容纳块级元素和行内元素,可作为容器使用
  • 行内元素:
    • 无法设置宽高,可与其他行内元素位于同一行,行内元素内一般不可包含块级元素
    • 高宽无效,对margin和padding设置仅水平方向有效,垂直方向(即上下)无效
    • 设置行高有效,等同于给父级元素设置行高
    • 元素的宽度就是它包含的文字或图片的宽度,不可改变

三、react受控组件和非受控组件有什么区别

  • 受控组件:就是受我们控制的组件,组件的状态全程响应外部数据

    受控组件一般需要初始状态和一个状态更新事件函数

  • 非受控组件:就是不受我们控制的组件,一般情况是在初始化的时候接受外部数据,然后自己在内部存储其自身状态

    当需要时,可以使用ref查询DOM并查找其当前值

    大部分时候推荐使用受控组件来实现表单,因为在受控组件中,表单数据由React组件负责处理; 如果选择非受控组件的话,控制能力较弱,表单数据就由DOM本身处理,但更加方便快捷。

四、react合成事件和普通js事件有什么区别

  • 合成事件的目的就是为了消除不同浏览器在事件对象上面的一个差异。
  • React基于浏览器的事件机制自身实现了一套事件机制,包括事件注册、事件的合成、事件冒泡、事件派发等,在React中这套事件机制被称之为合成事件。
  • 合成事件是React模拟原生DOM事件所有能力的一个事件对象,即浏览器原生事件的跨浏览器包装器
  • 根据W3C规范来定义合成事件,兼容所有浏览器,拥有与浏览器原生事件相同的接口

区别:

  • 事件名称命名方式不同
  • 事件处理函数书写不同 执行顺序:
  • React所有事件都挂载在document对象上
  • 当真实DOM元素触发事件,会冒泡到document对象后,再处理React事件
  • 所以会先执行原生事件,然后处理React事件
  • 最后真正执行document上挂载的事件

总结:

  • React上注册的事件最终会绑定在document这个DOM上,而不是React组件对应的DOM(减少内存开销就是因为所有的事件都绑定在document上,其他节点没有绑定事件)
  • React自身实现了一套事件冒泡机制,所以这也就是为什么我们event.stopPropagation()无效的原因
  • React通过对列的形式,从触发的组件向父组件回溯,然后调用他们JSX中定义的callback
  • React有一套自己的合成事件SyntheticEvent

五、js怎样new一个新对象

  1. 创建一个新的对象obj
  2. 将对象与构造函数通过原型链连接起来(新对象的原型指向构造函数的原型对象)
  3. 将构造函数中的this绑定到新建的对象obj上
  4. 根据构造函数返回的类型做判断,如果是原始值则被忽略,如果是返回对象,需要正常处理
// new 一个新对象
function myNew(FunC, ...args){
    // 创建一个新对象
    const obj = {};
    // 新对象原型指向构造函数原型对象
    obj.__proto__ = FunC.prototype;
    // 将构造函数的this指向新对象
    let result = FunC.apply(obj, args)
    // 根据返回值判断
    return result instanceof Object ? result : obj
}

function Person(name, age) {
    this.name = name;
    this.age = age;
}

Person.prototype.say = function() {
console.log(this.name);
}

let p = myNew(Person, 'huihui', 123);
console.log(p)
p.say()

六、js 作用域|变量提升

console.log(a)
function test() {
    var a = 1;
}

这段代码执行结果是什么?

会报错:Uncaught ReferenceError: a is not defined

因为a没有被定义,test函数内部的a在函数作用域内部,所以不会有变量提升

变量提升是提升到当前作用域的顶部