(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
123
- 利用父元素的伪元素添加三件套(推荐使用)
.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 布局规则
- 内部的 Box 会在垂直方向,一个接一个地放置。
- Box 垂直方向的距离由 margin 决定。属于同一个 BFC 的两个相邻 Box 的 margin 会发生重叠。
- 每个元素的 margin box 的左边,与包含块 border box 的左边相接触(对于从左往右的格式化,否则相反)。
- BFC 的区域不会与 float box 重叠。
- BFC 就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
- 计算 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 异步请求
- 创建请求对象 XMLHttpRequest/ ActiveXObject
- 建立连接,设置请求方式、是否异步和 url 地址 open()
- 发送请求 send()
- 监听状态的变化 onreadystatechange()
- 接收返回的数据
- 补充:
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 的静态方法:
- $.holdReady(Boolean) 暂停或者恢复 jQuery.ready()事件
- $.each( arr, callback(index, value) ) 遍历对象或数组(相比原生 js 的 forEach 不能遍历数组)
- $.map(arr, callback(item, index, arr) ) 遍历对象或数组,将回调函数的返回值组成新数组并返回
- $.trim( str ) 去掉字符串两端空格 => 返回去除空格后的 str
- $.isWindow() 判断传入的对象是否是 window 对象 => 返回 true / false
- $.isArray() 判断传入的对象是否是数组 => 返回 true / false
- $.isFunction() 判断传入的对象是否是一个函数 => 返回 true / false
5、jQuery 选择器
- 基础选择器
- 层次选择器
- 内容过滤选择器
[图片上传失败...(image-4f73f6-1606756516165)]
6、jQuery 操作属性
-
属性和属性节点
-
属性定义
对象身上保存的变量就是属性
只要对象身上都可以添加属性(无论是自定义对象,还是 DOM 对象)
-
如何操作属性?
获取属性:obj.key | obj[key]
设置属性:obj.key = value | obj[key] = value
-
属性节点定义
在 HTML 标签中添加的属性就是属性节点
在 attributes 属性中保存的所有内容都是属性节点
-
如何操作属性节点?
获取属性节点:dom 元素.getAttribute('属性名')
设置属性节点:dom 元素.setAttribute('属性名', '属性值')
属性和属性节点的区别:任何对象都有属性,属性节点只有 dom 独有。
-
-
属性节点方法
- 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
-
操作 Class
addClass(className[, className2]) 添加类。给元素添加一个或多个类(多个类名之间用空格隔开)
removeClass(className[, className2]) 删除类。给元素删除一个或多个类
toggleClass(className) 切换类。添加或删除一个类(存在则删除,不存在则添加)
-
操作 Css 样式
-
css() 获取或设置元素的 css 样式
获取 css(key)
设置 css(key, value)
-
width() 获取或设置元素的宽度
- 获取 width()
- 设置 width(value)
-
height() 获取或设置元素的高度
获取 height()
设置 height(value)
-
-
操作文本
-
html() 获取或设置元素的 HTML
获取 html()
设置 html('domstr')
-
text() 获取或设置元素的文本内容
- 获取 text()
- 设置 text('string')
-
val() 获取或设置元素的 value 属性值
- 获取 val()
- 设置 val('string')
-
-
操作元素的位置
-
offset() 获取或设置元素相对窗口的偏移量
- 获取 offset().left | right...
- 设置 offset({ left: 10, top: 10})
-
position() 获取相对于它最近具有相对位置的父级元素(position: absolute | relative)
获取 position().left | right...
设置 position({ left: 10, top: 10})
-
-
操作 Scroll 方法
-
scrollTop() 获取或设置元素相对滚动条顶部的偏移量
获取 scrollTop()
设置 scrollTop(100)
-
scrollLeft() 获取或设置元素滚动条的水平位置(最左侧为 0)
- 获取 scrollLeft()
- 设置 scrollLeft(100)
-
8、jQuery 事件
-
事件绑定
- 事件绑定方式:
- eventName(function) ( 比如 click(function))(推荐)
- on(eventName, function)
- 事件绑定方式:
-
事件解绑
- off(eventName, function)
- off()不传参数,会移除元素的所有事件
- off()传入一个参数,会移除元素指定类型的事件。比如:off('click')
- off()传入两个参数,会移除元素指定类型的指定事件。比如:off('click',funcName)
- off(eventName, function)
-
事件坐标
-
获取事件坐标的三种方式:
- event.offsetX / event.offsetY 相对于事件元素左上角的坐标位置
- event.pageX/ event.pageY 相对于页面左上角的坐标位置
- event.clientX / event.clientY 相对于视口(浏览器)左上角的坐标位置
-
event.page 和 event.client 区别:
网页是可以滚动的,而视口是固定的
获取可视区域用 event.page
获取距离浏览器左上角坐标的用 event.client
-
-
事件冒泡
- 定义:事件冒泡是从目标元素逐级向上传递到根节点的过程。
- 阻止事件冒泡:event.stopPropagation()方法
-
事件委托(也称事件代理)
- 定义:事件委托通俗地说就是请其他人帮我们干事情,干完的结果会反馈回来的过程。
- 事件委托的优点:
- 减少 dom 监听的数量
- 自动给新增元素添加事件(默认新增的元素没有绑定事件,而事件委托可以做到)
-
事件默认行为
- 定义:网页中某些元素存在默认的行为。比如 a 标签、提交表单
- 阻止默认行为:event.preventDefault()方法
自定义事件
-
移入移出事件
- hover(function) 监听移入移出,其原理是 mouseenter 和 mouseleave
- mouseenter(function) / mouseleave(function)(移动到子元素不会触发事件)
- mouseover(function) / mouseout (移动到子元素也会触发事件)
9、jQuery 动画效果
-
显示和隐藏
- show(time, fn) 显示动画。其原理是块级调用 display: block; 行内调用 display: inline
- hide(time, fn) 隐藏动画。
- toggle 切换动画。(显示 -> 隐藏,隐藏 -> 显示)
-
淡入淡出动画
- fadeIn(time, fn) 淡入动画。
- fadeOut(time, fn) 淡出动画。
- fadeToggle(time, fn) 切换动画。(显示 -> 淡出,不显示 -> 淡入)
-
展开和收起动画
- slideDown(time, fn) 展开动画。
- slideUp(time, fn) 收起动画。
- sildeToggle(time, fn) 切换动画。(展开 -> 收起,收起 -> 展开)
-
自定义动画
- animate(object, time, type, fn)
- object 参数:接收一个对象,可以在对象修改属性
- time 参数:指定动画时长
- type 参数:指定动画类型。默认 swing
- fn 参数:动画执行完毕后的回调函数
- animate(object, time, type, fn)
-
动画队列
- 链式多个动画 ( 例如:$('div').slideDown(1000).slideUp(200).show(2000) )
- 注意:
- 动画队列方法 queue()后面不能直接添加 queue()方法,想继续添加动画,需要在上一个 queue()方法中使用 next()方法。
- 动画队列中紧跟一个非动画方法则会被立即执行。
-
动画相关方法
- 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 文档处理
- 添加节点
- 内部插入
- 在后面插入元素
- append() 在指定元素上插入一个元素,并在最后面(父添子,在最后)
- appendTo() 把元素插入指定元素,并在最后面(子插父,在最后)
- 在前面插入元素
- prepend() 在指定元素上插入一个元素,并在最后面(父添子,在最前)
- prependTo() 把元素插入指定元素,并在最后面(子插父,在最前)
- 在后面插入元素
- 外部插入
- 在后面插入元素
- after()
- insertAfter()
- 在前面插入元素
- before()
- insertBefore()
- 在后面插入元素
- 内部插入
- 删除节点
- empty() 删除指定元素的内容和子元素(指定元素自身不删除)
- remove() 删除指定元素(元素上的 事件会移除)
- detach() 删除指定元素(元素上的 事件会保留)
- 替换节点
- replaceWith() 将匹配元素替换成指定元素。
- replaceAll() 用匹配的元素替换所有 selector 匹配到的元素 (比如:$li.replaceAll('div'))
- 复制节点
- clone() / clone(false) 浅复制一个节点 (不会复制节点的事件)
- clone(true) 深复制一个节点(会复制节点的事件)
- 包裹节点
- wrap() 将指定元素用其他标签包裹起来
- wrapAll() 将所有匹配的元素用一个元素包裹起来
- wrapInner() 将每一个匹配的元素的子内容(包括文本节点),用其他标签包裹起来
- 遍历节点
- 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、几大经典布局方案
-
左右固定,中间自适应
-
圣杯布局
圣杯布局 圣杯布局 centerleftright
-
-
双飞翼布局
双飞翼布局 双飞翼布局 centerleftright -
使用 (存在兼容性和性能差的缺点,不建议使用)
Document leftcenterright
-
使用 flex(存在兼容性的问题)
Document leftcenterright