前言:作为查漏补缺,温故知新
HTML:
window对象的常用属性和方法:
通过直接在 Chrome 控制台中输入 console.log(window) 可以查看到其所有的被当前浏览器支持的属性及值。(自身属性以及调用的方法)
讲讲你认识的HTML5:
HTML5主要是关于图像,位置,存储,多任务等功能的增加。
- 绘画 canvas;
- 用于媒介回放的 video 和 audio 元素;
- dom操作querySelector
- 进度条progress 度量器meter
- 本地离线存储 localStorage 长期存储数据,浏览器关闭后数据不丢失;
- sessionStorage 的数据在浏览器关闭后自动删除;
- 语意化更好的内容元素,比如 article、footer、header、nav、section;
- 表单控件:calendar、date、time、email、url、search;
- <img draggable="true" /> 拖拽
- 新的技术:webworker, websocket, Geolocation;
src与href的差别:
一个是外部资源 一个是网络资源
alt与title的差别:
没有信息时显示alt信息,,title是鼠标移上去显示title信息
重排和重绘:
style会造成他们的变化, 在性能优先的前提下,性能消耗 重排 大于 重绘。颜色等改变影响重绘,,大小等改变造成重排
行内元素与块级元素与块级行内元素的区别?
- 行内元素有:a b span img input select strong(强调的语气) 无宽高设置 上下边距设置
- 块级元素有:div ul ol li dl dt dd h1 h2 h3 h4 p 默认独占一行
- 常见的行内块元素: img input link meta br hr ,鲜为人知的是:area base col command embed keygen param source track wbr
请描述一下 cookies,sessionStorage 和 localStorage 的区别 ?
- cookie 是网站为了标示用户身份而储存在用户本地终端(Client Side)上的数据(通常经过加密)。
- cookie 数据始终在同源的 http 请求中携带(即使不需要),也会在浏览器和服务器间来回传递。
- sessionStorage 和 localStorage 不会自动把数据发给服务器,仅在本地保存。
存储大小
- cookie 数据大小不能超过 4k。
- sessionStorage 和 localStorage 虽然也有存储大小的限制,但比 cookie 大得多,可以达到 5M 或更大。
有期时间
- localStorage 存储持久数据,浏览器关闭后数据不丢失除非主动删除数据;
- sessionStorage 数据在当前浏览器窗口关闭后自动删除。
- cookie 设置的 cookie 过期时间之前一直有效,即使窗口或浏览器关闭。
前端由那三层构成?
- 结构层
- 表现层
- 行为层
iframe 有那些优点和缺点?
iframe 元素会创建包含另外一个文档的内联框架(即行内框架)。
优点:
- 用来加载速度较慢的内容(如广告)
- 可以使脚本可以并行下载
- 可以实现跨子域通信
缺点:
- iframe 会阻塞主页面的 onload 事件
- 无法被一些搜索引擎索识别
- 会产生很多页面,不容易管理
Canvas和SVG的区别:
SVG:
- 最适合带有大型渲染区域的应用程序(比如谷歌地图)
Canvas:
- 最适合图像密集型的游戏,其中的许多对象会被频繁重绘
head 标签有什么作用
是文档的头部标签 用来介绍信息以及引入资源
说一下 HTML5 drag API
- dragstart:事件主体是被拖放元素,在开始拖放被拖放元素时触发。
- darg:事件主体是被拖放元素,在正在拖放被拖放元素时触发。
- dragenter:事件主体是目标元素,在被拖放元素进入某元素时触发。
- dragover:事件主体是目标元素,在被拖放在某元素内移动时触发。
- dragleave:事件主体是目标元素,在被拖放元素移出目标元素是触发。
- drop:事件主体是目标元素,在目标元素完全接受被拖放元素时触发。
- dragend:事件主体是被拖放元素,在整个拖放操作结束时触发。
CSS:
盒子模型理解:
CSS 盒子模型具有内容 (content)、填充 (padding)、边框 (border)、边界 (margin)这些属性。
我们所说的 width,height 指的是内容 (content) 的宽高。
一个盒子模型的中:
- 宽度 = width+ pdding(宽) + border(宽)。
- 高度 = height + padding(高) + border(高)。
页面导入样式时,使用 link 和 @import 有什么区别 ?
- link 属于 XHTML 标签,除了加载 CSS 外,还能用于定义 RSS(是一种描述和同步网站内容的格式,是使用最广泛的 XML 应用), 定义 rel 连接属性等作用;
- 而 @import 是 CSS 提供的,只能用于加载 CSS;
- 页面被加载的时,link 会同时被加载,而 @import 引用的 CSS 会等到页面被加载完再加载;
- import 是 CSS2.1 提出的,只在 IE5 以上才能被识别,而 link 是 XHTML 标签,无兼容问题。
- 总之,link 要优于 @import。
继承属性:
- 字体属性:字体样式大小这些
- 文本属性:文本居中 颜色这些
- 光标样式:
- 元素可见性:
水平居中:
已知宽高:
绝对定位 四方位置为0 margin为auto
绝对定位 两方五十 边距自身一半
未知宽高:
.item{ position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); /* 使用 css3 的 transform 来实现 */ }
css3 动画效果属性有哪些 ?
- animation-name:规定需要绑定到选择器的 keyframe 名称。。
- animation-duration:规定完成动画所花费的时间,以秒或毫秒计。
- animation-timing-function:规定动画的速度曲线。
- animation-delay:规定在动画开始之前的延迟。
- animation-iteration-count:规定动画应该播放的次数。
- animation-direction:规定是否应该轮流反向播放动画。
样式优先级算法如何计算?内联和 important 哪个优先级高 ?
- 优先级就近原则,样式定义最近者为准
- 载入样式以最后载入的定位为准
- 优先级为 !important > [ id > class > tag ]
- !mportant 比内联优先级高
css选择符:
- id选择器( # myid)
- 类选择器(.myclassname)
- 标签选择器(div, h1, p)
- 相邻选择器(h1 + p)
- 子选择器(ul > li)
- 后代选择器(li a)
- 通配符选择器( * )
- 属性选择器(a[rel = "external"])
- 伪类选择器(a: hover, li: nth - child)
css新增伪类介绍:
- :root 选择文档的根元素,等同于 html 元素
- :empty 选择没有子元素的元素
- :target 选取当前活动的目标元素
- :not(selector) 选择除 selector 元素以外的元素
- :enabled 选择可用的表单元素
- :disabled 选择禁用的表单元素
- :checked 选择被选中的表单元素
- :after 选择器在被选元素的内容后面插入内容
- :before 选择器在被选元素的内容前面插入内容
- :nth-child(n) 匹配父元素下指定子元素,在所有子元素中排序第 n
- :nth-last-child(n) 匹配父元素下指定子元素,在所有子元素中排序第 n,从后向前数
- :nth-child(odd) 奇数
- :nth-child(even) 偶数
- :nth-child(3n+1)
- :first-child
- :last-child
- :only-child
- :nth-of-type(n) 匹配父元素下指定子元素,在同类子元素中排序第 n
- :nth-last-of-type(n) 匹配父元素下指定子元素,在同类子元素中排序第 n,从后向前数
- :nth-of-type(odd)
- :nth-of-type(even)
- :nth-of-type(3n+1)
- :first-of-type
- :last-of-type
- :only-of-type
- ::selection 选择被用户选取的元素部分
- :first-line 选择元素中的第一行
- :first-letter 选择元素中的第一个字符
CSS3 有哪些新特性 ?
- CSS3 实现圆角(border-radius:8px)
- 阴影(box-shadow:10px)
- 对文字加特效(text-shadow)
- 线性渐变(gradient)
- 旋转、缩放、定位、倾斜
transform: rotate(9deg) scale(0.85,0.90) translate(0px,-30px) skew(-9deg,0deg);
- 增加了更多的 CSS 选择器
- 多背景 rgba
- 新增各种CSS选择器 (: not(.input):所有 class 不是“input”的节点)
- 多列布局 (multi-column layout)
- 文字渲染 (Text-decoration)
- 增加了旋转,缩放,定位,倾斜,动画,多背景
svg 与 canvas 的区别 ?
- svg 绘制出来的每一个图形的元素都是独立的 DOM 节点,能够方便的绑定事件或用来修改,而 canvas 输出的是一整幅画布;
- svg 输出的图形是矢量图形,后期可以修改参数来自由放大缩小,不会是真和锯齿。而 canvas 输出标量画布,就像一张图片一样,放大会失真或者锯齿。
文字超出隐藏:
文字宽度+文字不换行+文字超出隐藏+文字超出显示
width,overflow: hidden, white-space: nowrap (规定段落中的文本不进行换行), text-overflow: ellipsis,
::before 和 :after 中双冒号和单冒号有什么区别 ?解释一下这 2 个伪元素的作用
- 单冒号 (:) 用于 CSS3 伪类,双冒号 (::) 用于 CSS3 伪元素。
- ::before 就是以一个子元素的存在,定义在元素主体内容之前的一个伪元素。并不存在于 dom 之中,只存在在页面之中。
阐述一下CSS Sprites
将一个页面涉及到的所有图片都包含到一张大图中去,然后利用 CSS 的 background-image,background-repeat,background-position 的组合进行背景定位。
利用 CSS Sprites 能很好地减少网页的 http 请求,从而大大的提高页面的性能; CSS Sprites 能减少图片的字节。
隐藏元素的方法有哪些
- display: none:渲染树不会包含该渲染对象,因此该元素不会在页面中占据位置,也不会响应绑定的监听事件。
- visibility: hidden:元素在页面中仍占据空间,但是不会响应绑定的监听事件。
- opacity: 0:将元素的透明度设置为 0,以此来实现元素的隐藏。元素在页面中仍然占据空间,并且能够响应元素绑定的监听事件。
- position: absolute:通过使用绝对定位将元素移除可视区域内,以此来实现元素的隐藏。
- z-index: 负值:来使其他元素遮盖住该元素,以此来实现隐藏。
- clip/clip-path :使用元素裁剪的方法来实现元素的隐藏,这种方法下,元素仍在页面中占据位置,但是不会响应绑定的监听事件。
- transform: scale(0,0):将元素缩放为 0,来实现元素的隐藏。这种方法下,元素仍在页面中占据位置,但是不会响应绑定的监听事件。
JavaScript:
数据类型:
这些数据可以分为原始数据类型和引用数据类型:
- 栈:原始数据类型(Undefined、Null、Boolean、Number、String) 栈中数据的存取方式为先进后出。
- 堆:引用数据类型(对象、数组和函数)
引用数据类型在栈中存储了指针,该指针指向堆中该实体的起始地址。当解释器寻找引用值时,会首先检索其在栈中的地址,取得地址后从堆中获得实体
判断数据类型:
1:typeof
console.log(typeof null); // object
其中数组、对象、null都会被判断为object,其他的就是本型
2:instanceof
instanceof
可以正确判断对象的类型,其内部运行机制是判断在其原型链中能否找到该类型的原型。console.log(2 instanceof Number); // false console.log(true instanceof Boolean); // false console.log('str' instanceof String); // false console.log([] instanceof Array); // true console.log(function(){} instanceof Function); // true console.log({} instanceof Object); // true
可以看到,
instanceof
只能正确判断引用数据类型,而不能判断基本数据类型。instanceof
运算符可以用来测试一个对象在其原型链中是否存在一个构造函数的prototype
属性。
3:constructor
constructor
有两个作用,一是判断数据的类型,二是对象实例通过constrcutor
对象访问它的构造函数。需要注意,如果创建一个对象来改变它的原型,constructor
就不能用来判断数据类型了:console.log((2).constructor === Number); // true console.log((true).constructor === Boolean); // true console.log(('str').constructor === String); // true console.log(([]).constructor === Array); // true console.log((function() {}).constructor === Function); // true console.log(({}).constructor === Object); // true
function Fn(){}; Fn.prototype = new Array(); var f = new Fn(); console.log(f.constructor===Fn); // false console.log(f.constructor===Array); // true
4:Object.prototype.toString.call()
Object.prototype.toString.call()
使用 Object 对象的原型方法 toString 来判断数据类型:var a = Object.prototype.toString; console.log(a.call(2)); console.log(a.call(true)); console.log(a.call('str')); console.log(a.call([])); console.log(a.call(function(){})); console.log(a.call({})); console.log(a.call(undefined)); console.log(a.call(null));
null和undefined区别
- undefined 代表的含义是未定义,null 代表的含义是空对象。
- 一般变量声明了但还没有定义的时候会返回 undefined,
- null主要用于赋值给一些可能会返回对象的变量,作为初始化
当使用双等号对两种类型的值进行比较时会返回 true,使用三个等号时会返回 false。
== 操作符的强制类型转换规则?
对于
==
来说,如果对比双方的类型不一样,就会进行类型转换。1:先判断与null和undefine的比较 返回布尔值
2:字符串转换为number值计算
1 == '1' ↓ 1 == 1 '1' == true ↓ '1' == 1 ↓ 1 == 1
隐式类型转换:
对于==操作符
操作符两边的值都尽量转成number:
3 == true // false, 3 转为number为3,true转为number为1
'0' == false //true, '0'转为number为0,false转为number为0
'0' == 0 // '0'转为number为0
+
操作符+
至少一个
string
类型变量时,两边的变量都会被隐式转换为字符串;其他情况下两边的变量都会被转换为数字。
如何判断一个对象是空对象
使用ES6新增的方法Object.keys()来判断 数组的长度
const对象的属性可以修改吗
const保证的并不是变量的值不能改动,而是变量指向的那个内存地址不能改动 ,而对象是引用类型 是将指针存在栈中 指针指向堆 指针保存了 指向的数据结构没变化 可以修改
new操作的过程
new操作符的实现步骤如下:
- 创建一个对象
- 将构造函数的作用域赋给新对象(也就是将对象的__proto__属性指向构造函数的prototype属性)
- 指向构造函数中的代码,构造函数中的this指向该对象(也就是为这个对象添加属性和方法)
- 返回新的对象
Proxy 可以实现什么功能?
Proxy 是 ES6 中新增的功能,它可以用来自定义对象中的操作。 代理对源对象属性的操作
let p = new Proxy(target, handler)
target
代表需要添加代理的对象,handler
用来自定义对象中的操作,比如可以用来自定义set
或者get
函数。
vue3中proxy的意义:
如果需要实现一个 Vue 中的响应式,需要在
get
中收集依赖,在set
派发更新,之所以 Vue3.0 要使用Proxy
替换原本的 API 原因在于Proxy
无需一层层递归为每个属性添加代理,一次即可完成以上操作,性能上更好,并且原本的实现有一些数据更新不能监听到,但是Proxy
可以完美监听到任何方式的数据改变,唯一缺陷就是浏览器的兼容性不好。
解构:
数组的解构
const [a, b, c] = [1, 2, 3]
const [a,,c] = [1,2,3]
对象的解构
const stu = {
name: 'Bob',
age: 24
}
const { name, age } = stu
模板字符串:
- 可以在里面写html代码
- 可以简单的计算
字符串新增的方法:
- includes:判断字符串与子串的包含关系:
- startsWith:判断字符串是否以某个/某串字符开头:
- endsWith:判断字符串是否以某个/某串字符结尾:
- 自动重复:可以使用 repeat 方法来使同一个字符串输出多次(被连续复制多次):
map和Object的区别
Map | Object | |
意外的键 | Map默认情况不包含任何键,只包含显式插入的键。 | Object 有一个原型, 原型链上的键名有可能和自己在对象上的设置的键名产生冲突。 |
键的类型 | Map的键可以是任意值,包括函数、对象或任意基本类型。 | Object 的键必须是 String 或是Symbol。 |
键的顺序 | Map 中的 key 是有序的。因此,当迭代的时候, Map 对象以插入的顺序返回键值。 | Object 的键是无序的 |
Size | Map 的键值对个数可以轻易地通过size 属性获取 | Object 的键值对个数只能手动计算 |
迭代 | Map 是 iterable 的,所以可以直接被迭代。 | 迭代Object需要以某种方式获取它的键然后才能迭代。 |
性能 | 在频繁增删键值对的场景下表现更好。 | 在频繁添加和删除键值对的场景下未作出优化。 |
Map:
map本质上就是键值对的集合,但是普通的Object中的键值对中的键只能是字符串。而ES6提供的Map数据结构类似于对象,但是它的键不限制范围,可以是任意类型,是一种更加完善的Hash结构。如果Map的键是一个原始数据类型,只要两个键严格相同,就视为是同一个键。
实际上Map是一个数组,它的每一个数据也都是一个数组,其形式如下:
const map = [
["name","张三"],
["age",18],
]
Map数据结构有以下操作方法:
- size:
map.size
返回Map结构的成员总数。- set(key,value):设置键名key对应的键值value,然后返回整个Map结构,如果key已经有值,则键值会被更新,否则就新生成该键。(因为返回的是当前Map对象,所以可以链式调用)
- get(key):该方法读取key对应的键值,如果找不到key,返回undefined。
- has(key):该方法返回一个布尔值,表示某个键是否在当前Map对象中。
- delete(key):该方法删除某个键,返回true,如果删除失败,返回false。
- clear():map.clear()清除所有成员,没有返回值。
Map结构原生提供是三个遍历器生成函数和一个遍历方法
- keys():返回键名的遍历器。
- values():返回键值的遍历器。
- entries():返回所有成员的遍历器。
- forEach():遍历Map的所有成员。
const map = new Map([
["foo",1],
["bar",2],
])
for(let key of map.keys()){
console.log(key); // foo bar
}
for(let value of map.values()){
console.log(value); // 1 2
}
for(let items of map.entries()){
console.log(items); // ["foo",1] ["bar",2]
}
map.forEach( (value,key,map) => {
console.log(key,value); // foo 1 bar 2
})
map和weakMap
总结:
- Map 数据结构。它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。
- WeakMap 结构与 Map 结构类似,也是用于生成键值对的集合。但是 WeakMap 只接受对象作为键名( null 除外),不接受其他类型的值作为键名。而且 WeakMap 的键名所指向的对象,不计入垃圾回收机制。
函数的 arguments 参数是类数组而不是数组
arguments 参数有长度但是不能使用数组的方法 需要转换为真数组
点运算符展开
array.from
原型和原型链的理解
在JavaScript中是使用构造函数来新建一个对象的,每一个构造函数的内部都有一个 prototype 属性,它的属性值是一个对象,这个对象包含了可以由该构造函数的所有实例共享的属性和方法。当使用构造函数新建一个对象后,在这个对象的内部将包含一个指针,这个指针指向构造函数的 prototype 属性对应的值,在 ES5 中这个指针被称为对象的原型。一般来说不应该能够获取到这个值的,但是现在浏览器中都实现了 __proto__ 属性来访问这个属性,但是最好不要使用这个属性,因为它不是规范中规定的。ES5 中新增了一个 Object.getPrototypeOf() 方法,可以通过这个方法来获取对象的原型。
当访问一个对象的属性时,如果这个对象内部不存在这个属性,那么它就会去它的原型对象里找这个属性,这个原型对象又会有自己的原型,于是就这样一直找下去,也就是原型链的概念。原型链的尽头一般来说都是 Object.prototype 所以这就是新建的对象为什么能够使用 toString() 等方法的原因。
照我理解
原型就是构造函数的prototype 实例化对象的指针叫proto 它指向这个原型prototype对象
原型链就是 该对象没有的属性 它会去它的原型上面找。一层层的找就形成了原型链
对象的constructor属性指向问题
个人理解:obj.constructor指向的是构造函数 如果这个构造函数修改了原型 则constructor的指向也发生了改变
至于对象的指针proto永远都是指向构造函数的prototype对象 这个不会改变
对闭包的理解
一般来说 作用域内定义的变量叫内部私有变量 外界访问不到 但我们可以通过闭包来访问
闭包是指有权访问另一个函数作用域中变量的函数 在函数里面定义的函数 可以访问到上层函数的变量
闭包两个作用:
1:访问变量
2:延长变量存储时间 避免垃圾回收机制
作用域链:
一层一层往上面找变量