前端面试题

(1)前端基础面试题

一、HTML 面试题

1、html 语义化?
  • 阅读代码时能根据标签理解你的用意,便于阅读
  • 方便浏览器读取和识别,有利于搜索引擎优化(SEO: Search Engine Optimization)
2、行级元素和块级元素
  • 行级元素:不能设置宽高(内容撑开),不能独占一行,水平排列。(span、a、i、em)
  • 块级元素:可以设置宽高,能独占一行,垂直排列。(div、p、h1-h6、ul、li)
  • 行内块级元素:既可以设置宽高,又可以水平排列。

二、CSS 面试题

1、常见选择器
  • id 选择器
  • class 类选择器
  • 标签选择器(div)
  • 后代选择器(div ul li)
  • 子代选择器(div>ul>li)
  • 分组选择器(html,body)
  • 伪类选择器(:hover)
  • 伪元素选择器(::after)
  • 属性选择器( [herf] )选择所有带有 herf 属性元素
2、css 优先级
! important 最高
style 1000
id 100
class、属性、伪类 10
标签、伪元素 1
3、清除浮动方式
  • 父元素 overflow: hidden

  • 父元素 float

  • 设置父元素的高度

  • 在浮动的后面添加新的节点,新节点上 clear: both

    
    
    
    1
    2
    3

  • 利用父元素的伪元素添加三件套(推荐使用)
.clearfix::after {
  content: "";
  display: block;
  clear: both;
}
4、定位 position
  • static 默认的
  • absolute 绝对定位(相对于最近的祖先元素定位,定位后空间释放)
  • relative 相对定位(相对于自己初始位置定位,定位后空间不释放)
  • fixed 固定定位(相对于浏览器位置定位,定位后空间释放)
  • sticky 粘性定位(相当于吸顶效果,定位后空间不释放)
5、盒子模型
  • 标准盒模型:width 属性 = content 的宽度(box-sizing: content-box)
  • 怪异盒模型:width 属性 = content + padding + border(box-sizing: border-box)
6、解决外边距合并
  • 父元素 overflow:hidden
  • 父元素浮动或定位
  • 父元素加边框
  • 子元素浮动或定位
7、BFC
  • BFC 定义

BFC(Block formatting context)直译为"块级格式化上下文"。它是一个独立的渲染区域,只有 Block-level box 参与, 它规定了内部的 Block-level Box 如何布局,并且与这个区域外部毫不相干。

  • BFC 布局规则
  1. 内部的 Box 会在垂直方向,一个接一个地放置。
  2. Box 垂直方向的距离由 margin 决定。属于同一个 BFC 的两个相邻 Box 的 margin 会发生重叠。
  3. 每个元素的 margin box 的左边,与包含块 border box 的左边相接触(对于从左往右的格式化,否则相反)。
  4. BFC 的区域不会与 float box 重叠。
  5. BFC 就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
  6. 计算 BFC 的高度时,浮动元素也参与计算。
  • 那些情况会生成 BFC ?

    • 根元素 html
    • float 的值不是 none。
    • position 的值不是 static 或者 relative
    • display 的值是 inline-block、table-cell、table-caption、flex、inline-flex
    • overflow 的值不是 visible
8、重排、重绘和回流(reflow)
  • 重排:DOM 的变化影响元素的几何属性(比如宽高),浏览器会重新计算元素的几何属性。(如:改变窗口大小、改变文字大小、内容的改变、浏览器窗口的变化、style 属性的 改变...)
  • 重绘:元素被改变了外观,但没有改变布局(或宽高)的情况。(如:改变背景色、visiblity、outline...)
  • 回流:当浏览器发现某个部分发生了变化影响了布局,需倒回去重新渲染,这个回退的过程称回流。
9、display 属性

​ inline、block、inline-block、table、table-cell、flex...

10、显示和隐藏
  • display: none | block(不占空间,不能触发事件)
  • opacity: 0 | 1(占空间,能触发事件)
  • visibility: hidden | visible(占空间,不能触发事件)

三、JavaScript 面试题

1、数据类型
  • 基本数据类型(number、string、boolean、null、undefined、symbol)

  • 引用数据类型(array、object)

  • 注意 1: null 和 undefined 区别:

    • null 表示"没有对象",即该处不应该有值。典型用法是:

    (1) 作为函数的参数,表示该函数的参数不是对象。

    (2) 作为对象原型链的终点。

    console.log(Object.getPrototypeOf(Object.prototype)); // null
    console.log(document.getElementById("a")); // null 找不到唯一的dom节点也返回null
    
  • undefined 表示"缺少值",此处应该有一个值,但是还没有定义。典型用法是:

(1)变量被声明了,但没有赋值时,就等于 undefined。

var a;
console.log(a); // undefined

(2)调用函数时,应该提供的参数没有提供,该参数等于 undefined。

function fn(a) {
  console.log(a);
}
fn(); // undefined

(3)访问对象没有的属性,返回 undefined。

var obj = {};
console.log(obj.name); // undefined

(4)函数没有返回值时,默认返回 undefined。

function fun() {
  console.log("此函数没返回值");
}
console.log(fun()); // undefined

(5)数组越界,返回 undefined。

var arr = [1, 2, 3];
console.log(arr[5]); // undefined
  • 注意 2:typeof 判断各种数据类型

    // typeof 判断数据类型
    function Fn() {}
    var arr = [1, 2, 3];
    var obj = { name: "ha" };
    
    console.log(typeof "abc"); // "string"
    console.log(typeof 123); // "number"
    console.log(typeof true); // "boolean"
    console.log(typeof undefined); // "undefined"
    console.log(typeof Fn); // "function"
    console.log(typeof null); // "object"
    console.log(typeof arr); // "object"
    console.log(typeof obj); // "object"
    
  • 注意 3:判断区分数组(Array)和对象(Object)的三种方式

    var arr = [1, 2, 3];
    var obj = { name: "ha" };
    
    // 1. constructor
    console.log(arr.constructor == Array); // true
    console.log(obj.constructor == Object); // true
    
    // 2. instanceof
    console.log(arr instanceof Array); // true
    console.log(obj instanceof Object); // true
    
    // 3. isArray()
    console.log(Array.isArray(arr)); // true2、fdsf
    
2、继承
  • 继承属性:要在构造函数中,通过调用父类方法并用.call() | .apply() | .bind()方法改变 this 的指向

  • 继承方法:原型对象 = new 父类的实例化对象(但是原型对象变成父类构造函数了,需要把原型对象的 constructor 指回本类)

    function Animal(name, age) {
      this.name = name;
      this.age = age;
    }
    
    Animal.prototype.eat = function() {
      console.log(this.name + "is eatting....");
    };
    
    // 继承属性 要在构造函数中,通过调用父类方法并用.call() | .apply() | .bind()方法改变this的指向
    function Cat(name, age) {
      Animal.call(this, name, age);
    }
    
    // 继承方法 原型对象 = new 父类的实例化对象(但是原型对象变成父类构造函数了,需要把原型对象的constructor指回本类)
    Cat.prototype = new Animal();
    Cat.prototype.constructor = Cat;
    console.log(Cat.prototype.constructor); // Cat构造函数
    
    var cat = new Cat("qiqi", 5);
    console.log(cat);
    
3、 ES6 新特性
  • var、let、const 区别

    1)let 不存在变量提升

    2)let 不能重复声明

    3)let 具有块级作用域

    4)let 存在临时失效区(也称暂时性死区,即在当前作用域下不允许外部的同名的变量进入)

    5)const 用于定义常量(const 以上四条特性也符合)

    (1)let 不存在变量提升

    // var定义变量
    console.log(a); // undefined
    var a = 3;
    
    // let定义变量
    console.log(a); // 报错 Cannot access 'a' before initialization
    let a = 3;
    

(2)let 不能重复声明

// var
var a = 10;
var a = 20;
console.log(a); // 20

// let
let a = 10;
let a = 20;
console.log(a); // 报错 'a' has already been declared

(3)let 具有块级作用域

// var
{
  var a = 2;
}
console.log(a); // 2

// let
{
  let a = 2;
}
console.log(a); // 报错 a is not defined

(4)let 存在临时失效区(也称暂时性死区,即在当前作用域下不允许同名的变量进入)

// var
var a = 5;
function fn() {
  console.log(a); // undefined
  var a = 6;
}
fn();

// let
let a = 5;
function fn() {
  console.log(a); // 报错 Cannot access 'a' before initialization
  let a = 6;
}
fn();

(5)const 用于定义常量(const 以上四条特性也符合)

// const不能给基本数据类型重新赋值
const a = 5;
a = 6; // 报错 Assignment to constant variable.
console.log(a);

// const 能修改引用数据类型在堆内存中的值,但不能修改引用的内存地址
const arr = [1, 2, 3];
arr[0] = 10;
console.log(arr); // [10,2,3]

// 使用Object.freeze()冻结 使其不能修改数组或对象的值
Object.freeze(arr);
arr[1] = 20;
console.log(arr); // [10,2,3]

arr = [4, 5, 6]; // 报错 Assignment to constant variable
  • 解构赋值

    // 数组解构
    let [a, b] = [10, 5];
    console.log(a, b); // 10 5
    
    // 对象解构
    let { c, d } = { name: "tao", age: 20 };
    console.log(c, d); // tao 20
    
  • 展开运算符(...)

    // 数组用法
    let arr = [1, 2, 3, 4];
    let arr2 = [...arr];
    console.log(arr2); // [1,2,3,4]
    
    // 对象用法
    let obj = {
      name: "tao",
      age: 18
    };
    
    let obj2 = { ...obj };
    console.log(obj2); // {name: "tao", age: 18}
    
  • 箭头函数

    注意:箭头函数中的 this 指向声明时(父作用域中)的 this,而不是执行时的 this

  • Set 类

    // 利用Set类进行数组去重
    let arr = [1, 1, 2, 3, 2, 6, 4, 6];
    let class_arr = new Set(arr);
    console.log(class_arr); // Set(5) {1, 2, 3, 6, 4}
    let newArr = [...class_arr];
    console.log(newArr); // (5) [1, 2, 3, 6, 4]
    
4、JavsScript 六种情况为假值(用于 if、while 等条件判断时)

注意:空对象({ })和空数组([ ])为 true 值。

  • false(Boolean 布尔值)
  • null
  • undefined(只声明,未定义)
  • ""(String 空字符串)
  • 0 (Number 数字 0)
  • NaN (Not a Number)
5、HTTP 状态码
状态码(Code) 描述
100 Continue 继续。一般用于 post 请求,客户端发送 http 中的 header 后,服务端表示确认后返回该状态码,表示可继续发送具体参数信息
200 OK 正常
201 Created 请求成功并返回服务器创建新的资源
202 Accepted 服务器已接收到请求,但尚未处理
301 Move Permanently 请求的网页永久性移动到新的位置
302 Found 临时性重定向
303 See Other 临时性重定向,且使用 GET 请求新的 URI
304 Not Modified 上次请求过后,网页未被修改过
400 Bad Request 服务器无法理解请求的格式
401 Unauthorized 请求未授权
403 Forbidden 禁止访问
404 Not Found 找不到如何与 URI 相匹配的资源
500 Internal Server Error 最常见的服务器端错误
503 Service Unavailable 服务器端暂时无法处理请求(可能是过载或维护)
6、Ajax 异步请求
  1. 创建请求对象 XMLHttpRequest/ ActiveXObject
  2. 建立连接,设置请求方式、是否异步和 url 地址 open()
  3. 发送请求 send()
  4. 监听状态的变化 onreadystatechange()
  5. 接收返回的数据
  • 补充:
readyState 存有 XMLHttpRequest 的状态。从 0 到 4 发生变化。
- 0: 请求未初始化
- 1: 服务器连接已建立
- 2: 请求已接收
- 3: 请求处理中
- 4: 请求已完成,且响应已就绪
status 200: “OK” 404: 未找到页面
function request() {
  // 1.创建请求对象XMLHttpRequest / ActiveXObject
  let xmlHttp;
  if (window.XMLHttpRequest) {
    xmlHttp = new XMLHttpRequest();
  } else {
    xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
  }
  // 2.建立连接,设置请求方式,是否异步以及url地址
  xmlHttp.open("post", "http://localhost:8080/api", true);
  // 3.发送异步请求 get => send(null) / post => send(相应的参数)
  xmlHttp.send();
  // 4.监听状态的变化
  xmlHttp.onreadystatechange = function() {
    if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {
      // 5.接收返回的数据,进行处理
      console.log(xmlHttp.responseText);
    }
  };
}

四、jQuery 面试题

1、jQuery 入口函数
  • jQuery 与 JavaScript 加载模式对比:
异同点 window.onload $(document).ready()
执行时机 必须等网页全部资源加载完毕后执行(Dom 和 图片等),才可以执行代码 只需等待网页中的 DOM 结构 加载完毕,就能执行代码
执行次数 只能执行一次,第二次执行会覆盖上一次 可以执行多次,不会覆盖上一次。(原理:jQuery 本质是一个闭包,每次执行我们都会给 ready 函数传递一个新的函数,不同函数内部的数据不会相互干扰)
  • 入口函数四种写法:
// 第一种写法
$(document).ready(function() {
  // 执行代码逻辑
});

// 第二种写法
jQuery(document).ready(function() {
  // 执行代码逻辑
});

// 第三种写法(推荐)
$(function() {
  // 执行代码逻辑
});

// 第四种写法
jQuery(function() {
  // 执行代码逻辑
});
2、jQuery 核心函数

核心函数 => $(arg) 。arg 可为函数、字符串(包括字符串选择器和字符串片段)、dom 元素对象

// 1.接收一个函数
$(function() {
  console.log("function");
});

// 2.接收一个字符串
// 2.1 传入字符串选择器
let box = $("#box");
// 2.2 传入字符串片段
let p = $("

我是p段落

"); // 3.接收一个dom //
let box = $(box);
3、jQuery 对象

通俗来说,jQuery 对象的本质是一个伪数组。

  • 属性名为 0 到 length-1
  • 有 length 属性
// 仿写伪数组
let jq = {
  0: "Daiva",
  1: "Losy",
  2: "Herry",
  length: 3
};
4、jQuery 静态方法

静态方法定义:静态方法直接用类名调用的方法;其对应是对象方法。

对象方法:用实例对象调用的方法。

function Person() {}
Person.say = function() {
  console.log("我是静态方法");
};
// 静态方法调用 => 类名.方法
Person.say();

// 对象方法需要写到原型上
Person.prototype.say = function() {
  console.log("我是对象方法");
};
// 对象方法 => 实例化对象.方法
let person = new Person();
person.say();

jQuery 的静态方法:

  1. $.holdReady(Boolean) 暂停或者恢复 jQuery.ready()事件
  2. $.each( arr, callback(index, value) ) 遍历对象或数组(相比原生 js 的 forEach 不能遍历数组)
  3. $.map(arr, callback(item, index, arr) ) 遍历对象或数组,将回调函数的返回值组成新数组并返回
  4. $.trim( str ) 去掉字符串两端空格 => 返回去除空格后的 str
  5. $.isWindow() 判断传入的对象是否是 window 对象 => 返回 true / false
  6. $.isArray() 判断传入的对象是否是数组 => 返回 true / false
  7. $.isFunction() 判断传入的对象是否是一个函数 => 返回 true / false
5、jQuery 选择器
  1. 基础选择器
  2. 层次选择器
  3. 内容过滤选择器

[图片上传失败...(image-4f73f6-1606756516165)]

6、jQuery 操作属性
  1. 属性和属性节点

    • 属性定义

      • 对象身上保存的变量就是属性

      • 只要对象身上都可以添加属性(无论是自定义对象,还是 DOM 对象)

    • 如何操作属性?

      • 获取属性:obj.key | obj[key]

      • 设置属性:obj.key = value | obj[key] = value

    • 属性节点定义

      • 在 HTML 标签中添加的属性就是属性节点

      • 在 attributes 属性中保存的所有内容都是属性节点

    • 如何操作属性节点?

      • 获取属性节点:dom 元素.getAttribute('属性名')

      • 设置属性节点:dom 元素.setAttribute('属性名', '属性值')

    属性和属性节点的区别:任何对象都有属性,属性节点只有 dom 独有。

  2. 属性节点方法

    • attr(key, value) 获取或者设置属性节点
    • removeAttr(key) 删除所有找到指定元素的属性节点
    • prop(key[, value]) 获取或者设置元素的属性值(注意:prop 方法不仅能操作属性,还能操作属性节点。一般用于 checked/selected/disabled)
    • removeProp(key) 删除所有找到指定元素的属性和属性节点

    attr 方法和 prop 方法区别:

    1)attr 方法只能操作属性节点,而 prop 方法既可以操作属性,又可以操作属性节点。

    2)如果具有 true 和 false 两个属性节点时(例如:checked/selected/disabled),官方推荐使用 prop 方法,其他使用 attr 方法。

    3)具有 true 和 false 两个属性节点时,没有设置默认值,attr 方法默认返回 undefined,prop 方法默认返回 false。

7、jQuery 操作 Class
  1. 操作 Class

    • addClass(className[, className2]) 添加类。给元素添加一个或多个类(多个类名之间用空格隔开)

    • removeClass(className[, className2]) 删除类。给元素删除一个或多个类

    • toggleClass(className) 切换类。添加或删除一个类(存在则删除,不存在则添加)

  2. 操作 Css 样式

    • css() 获取或设置元素的 css 样式

      • 获取 css(key)

      • 设置 css(key, value)

    • width() 获取或设置元素的宽度

      • 获取 width()
      • 设置 width(value)
    • height() 获取或设置元素的高度

      • 获取 height()

      • 设置 height(value)

  3. 操作文本

    • html() 获取或设置元素的 HTML

      • 获取 html()

      • 设置 html('domstr')

    • text() 获取或设置元素的文本内容

      • 获取 text()
      • 设置 text('string')
    • val() 获取或设置元素的 value 属性值

      • 获取 val()
      • 设置 val('string')
  4. 操作元素的位置

    • offset() 获取或设置元素相对窗口的偏移量

      • 获取 offset().left | right...
      • 设置 offset({ left: 10, top: 10})
    • position() 获取相对于它最近具有相对位置的父级元素(position: absolute | relative)

      • 获取 position().left | right...

      • 设置 position({ left: 10, top: 10})

  5. 操作 Scroll 方法

    • scrollTop() 获取或设置元素相对滚动条顶部的偏移量

      • 获取 scrollTop()

      • 设置 scrollTop(100)

    • scrollLeft() 获取或设置元素滚动条的水平位置(最左侧为 0)

      • 获取 scrollLeft()
      • 设置 scrollLeft(100)
8、jQuery 事件
  1. 事件绑定

    • 事件绑定方式:
      • eventName(function) ( 比如 click(function))(推荐)
      • on(eventName, function)
  2. 事件解绑

    • off(eventName, function)
      • off()不传参数,会移除元素的所有事件
      • off()传入一个参数,会移除元素指定类型的事件。比如:off('click')
      • off()传入两个参数,会移除元素指定类型的指定事件。比如:off('click',funcName)
  3. 事件坐标

    • 获取事件坐标的三种方式:

      • event.offsetX / event.offsetY 相对于事件元素左上角的坐标位置
      • event.pageX/ event.pageY 相对于页面左上角的坐标位置
      • event.clientX / event.clientY 相对于视口(浏览器)左上角的坐标位置
    • event.page 和 event.client 区别:

      • 网页是可以滚动的,而视口是固定的

      • 获取可视区域用 event.page

      • 获取距离浏览器左上角坐标的用 event.client

  4. 事件冒泡

    • 定义:事件冒泡是从目标元素逐级向上传递到根节点的过程。
    • 阻止事件冒泡:event.stopPropagation()方法
  5. 事件委托(也称事件代理)

    • 定义:事件委托通俗地说就是请其他人帮我们干事情,干完的结果会反馈回来的过程。
    • 事件委托的优点:
      • 减少 dom 监听的数量
      • 自动给新增元素添加事件(默认新增的元素没有绑定事件,而事件委托可以做到)
  6. 事件默认行为

    • 定义:网页中某些元素存在默认的行为。比如 a 标签、提交表单
    • 阻止默认行为:event.preventDefault()方法
  7. 自定义事件

  8. 移入移出事件

    • hover(function) 监听移入移出,其原理是 mouseenter 和 mouseleave
    • mouseenter(function) / mouseleave(function)(移动到子元素不会触发事件)
    • mouseover(function) / mouseout (移动到子元素也会触发事件)
9、jQuery 动画效果
  1. 显示和隐藏

    • show(time, fn) 显示动画。其原理是块级调用 display: block; 行内调用 display: inline
    • hide(time, fn) 隐藏动画。
    • toggle 切换动画。(显示 -> 隐藏,隐藏 -> 显示)
  2. 淡入淡出动画

    • fadeIn(time, fn) 淡入动画。
    • fadeOut(time, fn) 淡出动画。
    • fadeToggle(time, fn) 切换动画。(显示 -> 淡出,不显示 -> 淡入)
  3. 展开和收起动画

    • slideDown(time, fn) 展开动画。
    • slideUp(time, fn) 收起动画。
    • sildeToggle(time, fn) 切换动画。(展开 -> 收起,收起 -> 展开)
  4. 自定义动画

    • animate(object, time, type, fn)
      • object 参数:接收一个对象,可以在对象修改属性
      • time 参数:指定动画时长
      • type 参数:指定动画类型。默认 swing
      • fn 参数:动画执行完毕后的回调函数
  5. 动画队列

    • 链式多个动画 ( 例如:$('div').slideDown(1000).slideUp(200).show(2000) )
    • 注意:
      • 动画队列方法 queue()后面不能直接添加 queue()方法,想继续添加动画,需要在上一个 queue()方法中使用 next()方法。
      • 动画队列中紧跟一个非动画方法则会被立即执行。
  6. 动画相关方法

    • delay(time) 设置动画延迟时间
    • stop() 停止指定元素正在执行的动画
    // 停止当前动画, 继续执行后续动画
    $("div").stop();
    $("div").stop(false);
    $("div").stop(false, false);
    
    // 停止当前和后续所有的动画
    $("div").stop(true);
    $("div").stop(true, false);
    
    // 立即完成当前的, 继续执行后续动画
    $("div").stop(false, true);
    
    // 立即完成当前的, 并且停止后续所有的
    $("div").stop(true, true);
    
10、jQuery 文档处理
  1. 添加节点
    • 内部插入
      • 后面插入元素
        • append() 在指定元素上插入一个元素,并在最后面(父添子,在最后)
        • appendTo() 把元素插入指定元素,并在最后面(子插父,在最后)
      • 前面插入元素
        • prepend() 在指定元素上插入一个元素,并在最后面(父添子,在最前)
        • prependTo() 把元素插入指定元素,并在最后面(子插父,在最前)
    • 外部插入
      • 后面插入元素
        • after()
        • insertAfter()
      • 前面插入元素
        • before()
        • insertBefore()
  2. 删除节点
    • empty() 删除指定元素的内容和子元素(指定元素自身不删除)
    • remove() 删除指定元素(元素上的 事件会移除)
    • detach() 删除指定元素(元素上的 事件会保留)
  3. 替换节点
    • replaceWith() 将匹配元素替换成指定元素。
    • replaceAll() 用匹配的元素替换所有 selector 匹配到的元素 (比如:$li.replaceAll('div'))
  4. 复制节点
    • clone() / clone(false) 浅复制一个节点 (不会复制节点的事件)
    • clone(true) 深复制一个节点(会复制节点的事件)
  5. 包裹节点
    • wrap() 将指定元素用其他标签包裹起来
    • wrapAll() 将所有匹配的元素用一个元素包裹起来
    • wrapInner() 将每一个匹配的元素的子内容(包括文本节点),用其他标签包裹起来
  6. 遍历节点
    • children() 返回指定元素的子元素数组对象(只考虑子元素)
    • next() 同辈紧邻后面一个元素
    • nextAll() 同辈紧邻后面所有元素
    • prev() 同辈紧邻前面一个元素
    • prevAll() 同辈紧邻前面所有元素
    • siblings() 所有兄弟元素
    • find(selector) 查找指定元素的后代元素
    • filter() 指定选择器的 xx 元素,符合条件的同级元素
    • has() 符合条件的后代元素,不包含自身
    • parents() 获取所有祖先元素
    • closest() 用来取得最近的匹配元素,包括自身
    • parentsUntil() 截止到 xx 位置的祖先节点。

五、Vue 面试题

1、常用指令
  • v-if、v-show、v-on、v-for、v-model、v-bind...
2、v-if 和 v-show 区别
  • v-show 是通过修改 css 的 display 属性实现显示和隐藏
  • v-if 是销毁 dom 或重新创建 dom 实现显示和隐藏
3、双向数据绑定原理
  • 利用 Object.defineProperty()方法重新定义了对象,用里面的 get()获取属性值和用 set()设置属性值来实现。
4、Proxy 相比 Object.defineProperty 优势(为什么 Vue3.0 将用原生 Proxy 替换 Object.defineProperty?)
  • Object.defineProperty 劣势:

    • Object.defineProperty 无法监控数组下标的变化,通过数组下标给数组设置值,不能实时响应。
    • Object.defineProperty 只能劫持对象的属性,但如果属性值也是对象则不能进行深度遍历。(Vue2.x 是通过递归 + 遍历 data 对象实现监控的)
  • Proxy 优势:

    • Proxy 可以直接监听数组的变化。
    • Proxy 可以直接监听对象而非属性。
    • Proxy 返回的是一个新对象,我们可以只操作新的对象达到目的,而 Object.defineProperty 只能遍历对象属性直接修改。
    • Proxy 有多达 13 种拦截方法,不限于 apply、ownKeys、deleteProperty、has 等等。
5、Vue.js 的两个核心
  • 数据驱动和组件化思想。
6、Vue 组件中 data 为什么必须是函数
  • 在 new Vue()中,data 可以是对象,但是在 component 中 data 只能是函数,不能是对象。这跟 JavaScript 的特性相关,==两个实例都引用同一个原型对象,当一个实例属性发生改变时,另一个实例的属性也随之改变,只有两个实例都拥有自己的作用域时,才不会相互干扰。(函数是拥有自己的作用域)==

    示例如下:

// data是对象形式
function C() {}
C.prototype.data = {
  name: "Herry"
};
var c1 = new C();
var c2 = new C();
c1.data.name = "c1";
console.log(c1.data.name); // c1
console.log(c2.data.name); // c1

// data是函数
function C() {
  this.data = this.data();
}
C.prototype.data = function() {
  return {
    name: "Herry"
  };
};
var c1 = new C();
var c2 = new C();
c1.data.name = "c1";
console.log(c1.data.name); // c1
console.log(c2.data.name); // Herry
7、Vue 中 key 值的作用
  • key 是用来给每个节点做唯一的标识,diff 算法就可以正确识别并找到准确的位置操作节点。总的来说,key 主要是为了更高效地更新虚拟 Dom。
8、什么是 Vue 的计算属性
  • 计算属性的定义为当其依赖的属性的值发生变化时,计算属性会重新计算,反之,则使用缓存中的属性值。计算属性是响应式的,是依赖某一个数据实现的,只有它依赖的数据发生改变,它才会更新。

(2)前端大厂面试题

一、CSS 面试题

1、盒子水平居中的五大方案
  • 定位(3 种)

    
    
  • display : flex

    
    
  • display : table-cell

    
    
  • JavaScript

2、关于盒子模型
  • 标准盒子模型 content-box
  • IE 盒子模型(也称怪异盒子模型) border-box
  • Flex 盒模型
3、几大经典布局方案
  • 左右固定,中间自适应

    • 圣杯布局

      
      
        
          
          
          
          圣杯布局
          
        
        
          

      圣杯布局

      center
      left
      right
  • 双飞翼布局

    
    
      
        
        
        
        双飞翼布局
        
      
      
        

    双飞翼布局

    center
    left
    right
  • 使用 (存在兼容性和性能差的缺点,不建议使用)

    
    
      
        
        
        
        Document
        
      
    
      
        
    left
    center
    right
  • 使用 flex(存在兼容性的问题)

    
    
      
        
        
        
        Document
    
        
      
      
        
    left
    center
    right

你可能感兴趣的:(前端面试题)