10 真实面试

目录

1 如何实现js深拷贝 

2 获取字符串 最多的字符

3 数组的 map 和 foreach 方法 

Map

forEach

区别:

4 判断数组还是对象的方法 

5 VueX 使用过吗? 说说你怎么用的 

6 js数组面试题 

7 js 字符串面试题

8 VueRouter 面试题 

9 创建对象方式有哪些 

10 this 的指向问题 

11 flex布局常用属性

12 Grid布局

dispaly:grid;

13 HTML的几种定位方式

HTML中的几种定位方式

定位模式(position)

14 js 的浅拷贝

深拷贝 :

15 ES6 解构赋值

16 HTML 面试题 

17 webSocket自动重连

webSocket 内存泄露 问题 

tomcat websocket WsFrameServer内存溢出

18 ThingJS学习笔记

19 xgplayer 

20 js继承 

21事件循环机制(宏任务、微任务)

22 let const var 的区别?什么是块级作用域?如何用?

23 ES6:export default 和 export 区别 

24  从输⼊URL到⻚⾯加载完中间发⽣了什么?

重排:

重绘:

HTML 变形(transform)、转换(transition)和动画(animation)

CSS基础 -- display属性

CSS 动画如何实现?

display:inline-block 在什么情况下会产生间隙?

CSS3:overflow属性详解

什么是选择器?有哪些选择器?

CSS中的伪类和伪元素

2、结构性伪类:css3新增选择器

 伪元素

伪类和伪元素的应用

2、清除浮动

什么是继承?CSS 中哪些属性可以继承?哪些不可以继承?

transition、transform、animate 的区别?

HTML5 引入什么新的表单属性?

 iframe 的作用

HTML5 新增哪些新特性 ?

行内元素和块级元素区别,有哪些,怎样转换?(顶呱呱)

HTML5 与 HTML4 的区别(华安永康)

form 表单上传文件时需要进行什么样的声明?

如何在一张图片上的某一个区域做到点击事件

 a 元素除了用于导航外,还可以有什么作用?

说一说类的继承

简述for in 和 for of 的区别

map()和forEach()的区别和理解

 new 操作符都做了哪些事?

call、apply、bind 的区别 ?

你了解 node 中的事件循环机制吗?node11 版本以后有什么改变

promise.all 方法的使用场景?数组中必须每一项都是 promise 对象吗?不是 promise 对象会如何处理 ?

this 的指向哪几种 ?

JS 中继承实现的几种方式

什么是事件监听

什么是 js 的闭包?有什么作用?

let const var 的区别?什么是块级作用域?如何用?

JS 的基本数据类型有哪些?基本数据类型和引用数据类型的区别

NaN 是什么的缩写

 作用域与作用域链 

原始值与引用值===基本数据类型引用数据类型

如何判断数组或对象

对象深拷贝与浅拷贝,单独问了 Object.assign

说说 instanceof 原理

ES6 新增哪些东西?

weakmap、weakset

 为什么 ES6 会新增 Promise

ES5 实现继承

  防抖和节流?

 原型和原型链?

冒泡排序冒泡排序

数组降维

var newArray = arr.flat([depth])

proxy 是实现代理,可以改变 js 底层的实现方式, 然后说了一下和 Object.defineProperty 的区别

 async 与 await 的作用

对变量进行类型判断的方式有哪些

 typeof 与 instanceof 的区别? instanceof 是如何实现?

引用类型Object: Array ,Function, Date, RegExp等

如何实现一个 new 

给定两个数组,求交集


1 如何实现js深拷贝 

1.通过JSON对象

let objClone = JSON.parse(JSON.stringify(obj));

2、递归实现

function deepClone(obj) {
	// 数据类型为引用数据类型
	if (typeof obj === 'object') {
		// 初始化返回结果
		let result = Array.isArray(obj)? []: {};
		for (let key in obj) {
			// 避免相互引用出现死循环导致爆栈
			if (obj === obj[key]) {
				continue
			}
			if (obj.hasOwnProperty(key)) {
				// 递归调用
				result[key] = deepClone(obj[key])
			}
		}
		return result;
	} else {
		// 基本数据类型,直接返回
		return obj
	}
}

3.jQuery的extend方法实现深拷贝

var newArray = $.extend(true,[],array); // true为深拷贝,false为浅拷贝

函数库lodash的_.cloneDeep方法

var obj1 = _.cloneDeep(obj)

2 获取字符串 最多的字符

let str = "lllnndghishfio";

let obj = {};

for (var item of str) {
  if (obj[item]) {
    obj[item]++;
  } else {
    obj[item] = 1;
  }
}

console.log(obj);

let max = 0;
let strMax = "";
for (let key in obj) {
  console.log("key", key);
  if (obj[key] > max) {
    max = obj[key];
    strMax = key;
  }
}
console.log(`出现最多字符串:${strMax}`);
console.log(`出现次数是:${max}`);

3 数组的 map 和 foreach 方法 

Map

定义和用法
map() 方法返回一个新数组数组中的元素为原始数组元素调用函数处理后的值。

map() 方法按照原始数组元素顺序依次处理元素。

注意: map() 不会对空数组进行检测。

注意: map() 不会改变原始数组。

forEach

定义和用法

forEach() 方法用于调用数组的每个元素,并将元素传递给回调函数。

注意: forEach() 对于空数组是不会执行回调函数的。

区别:

1、map速度比forEach快

2、map会返回一个新数组,不对原数组产生影响,foreach不会产生新数组,forEach返回undefined

3、map因为返回数组所以可以链式操作,forEach不能

4, map里可以用return(return的是什么,相当于把数组中的这一项变为什么(并不影响原来的数组,只是相当于把原数组克隆一份,把克隆的这一份的数组中的对应项改变了) ,而forEach里用return不起作用,forEach不能用break,会直接报错
 

JS中Map和ForEach的区别_咯吱1228的博客-CSDN博客_js map和foreach区别Map定义和用法map() 方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。map() 方法按照原始数组元素顺序依次处理元素。注意: map() 不会对空数组进行检测。注意: map() 不会改变原始数组。forEach定义和用法forEach() 方法用于调用数组的每个元素,并将元素传递给回调函数。注意: forEach() 对于空数组是不会执行回调函数的。forEach()和map()两个方法都是ECMA5中Array引进的新方法,用来遍历数组中的每一项,但是它https://blog.csdn.net/weixin_46034375/article/details/108514832?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522166386099216800184122872%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=166386099216800184122872&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-1-108514832-null-null.142%5Ev50%5Epc_rank_34_1,201%5Ev3%5Econtrol_2&utm_term=js%E6%95%B0%E7%BB%84%E6%96%B9%E6%B3%95map%E4%B8%8Eforeach&spm=1018.2226.3001.4187

4 判断数组还是对象的方法 

1 arr instanceof Array

2 arr.constructor === Array

3 Object.prototype.toString.call(arr) === ‘‘[object Array]’’

Array.isArray(objectName);

5 .typeof

5 VueX 使用过吗? 说说你怎么用的 

VueX是一个专门为 Vue.js 应用设计的状态管理架构,统一管理和维护各个vue组件的可变化状态(你可以理解成 vue 组件里的某些 data )。

Vuex的5个属性

state:单一状态树,用一个对象就包含了全部的应用层级状态。
getters:就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。
mutations:每个mutation都有一个字符串的事件类型 (type) 和一个回调函数 (handler)。
action:action 类似于mutation,不同在于:action 提交的是mutation,而不是直接变更状态;action可以包含任意异步操作。
modules:模块化vuex,每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块。

  Vuex 使用流程:
                下载 vuex
                在 src 下创建 store 以及 index.js
                引入 vue 和 vuex, 使用 vuex ,导出实例对象
                在 main.js 中引入,在.vue 文件中使用
 

vuex 的 State 特性是?
1 、Vuex 就是一个仓库,仓库里面放了很多对象。其中 state 就是数据源存放地,对应于与一般 Vue 对象 里面的 data。
2 、state 里面存放的数据是响应式的,Vue 组件从 store 中读取数据,若是 store 中的数据发生改变,依赖 这个数据的组件也会发生更新。
3 、它通过 mapState 把全局的 state 和 getters 映射到当前组件的 computed 计算属性中。
、 vuex 的 Getter 特性是?
1 、getters 可以对 State 进行计算操作,它就是 Store 的计算属性
2 、 虽然在组件内也可以做计算属性,但是 getters 可以在多组件之间复用
3 、 如果一个状态只在一个组件内使用,是可以不用 getters
、 vuex 的 mauation 特性是?
1、mutation是一个对象包含多个直接更新state的方法(回调函数)
2、只能包含同步的代码, 不能写异步代码
、 vuex 的 action 特性是?
1 、action 类似于 mutation ,不同在于:
2 、action 提交的是 mutation ,而不是直接变更状态。
3 、action 可以包含任意异步操作

什么情况下应该使用 Vuex?
虽然 Vuex 可以帮助我们管理共享状态,但也附带了更多的概念和框架。这需要对短期和长期效益进行权衡。
如果不打算开发大型单页应用,使用 Vuex 可能是繁琐冗余的。确实是如此——如果您的应用够简单,您最好不要使用 Vuex。一个简单的global event bus就足够您所需了。但是,如果您需要构建是一个中大型单页应用,您很可能会考虑如何更好地在组件外部管理状态,Vuex 将会成为自然而然的选择。


 

Vuex是什么?怎么使用?描述使用它实现登录功能的流程?_不必为我惋惜的博客-CSDN博客Vuex是什么?怎么使用?描述使用它实现登录功能的流程?https://blog.csdn.net/Fziha/article/details/126431153?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522166386435416782412557440%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=166386435416782412557440&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~pc_rank_34-2-126431153-null-null.142%5Ev50%5Epc_rank_34_1,201%5Ev3%5Econtrol_2&utm_term=VueX%20%E4%BD%BF%E7%94%A8%E8%BF%87%E5%90%97%EF%BC%9F%20%E8%AF%B4%E8%AF%B4%E4%BD%A0%E6%80%8E%E4%B9%88%E7%94%A8%E7%9A%84%C2%A0&spm=1018.2226.3001.4187

vue面试总结60道题!!快收藏!!!_Li Derong的博客-CSDN博客_vue面试题目录1.Vue 的核心是什么2.请简述你对 vue 的理解3.请简述 vue 的单向数据流4. Vue 常用的修饰符有哪些5.v-text 与{{}}与 v-html 区别6.v-on 可以绑定多个方法吗7.Vue 循环的 key 作用8.什么是计算属性9. Vue 单页面的优缺点10.Vuex 是什么?怎么使用?在那种场景下使用11.Vue 中路由跳转方式(声明式/编程式)12.vue 跨域的解决方式13.Vue 的生命周期请简述14.Vue 生命周https://blog.csdn.net/model__/article/details/120524151?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522166386435416782412557440%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=166386435416782412557440&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~pc_rank_34-7-120524151-null-null.142%5Ev50%5Epc_rank_34_1,201%5Ev3%5Econtrol_2&utm_term=VueX%20%E4%BD%BF%E7%94%A8%E8%BF%87%E5%90%97%EF%BC%9F%20%E8%AF%B4%E8%AF%B4%E4%BD%A0%E6%80%8E%E4%B9%88%E7%94%A8%E7%9A%84%C2%A0&spm=1018.2226.3001.4187

6 js数组面试题 

js数组 面试题_南风知我意,吹梦到西洲。的博客-CSDN博客_js数组面试题ES6 去重Array.from(new Set([1,2,3,4,5,4,3,2]))[...new Set([1,2,3,4,5,4,3,2])]//[1, 2, 3, 4, 5]排序[1,2,2,3,4,3,5,1].sort()//[1, 1, 2, 2, 3, 3, 4, 5][1,2,2,3,4,3,5,1].sort((a,b)=>b-a...https://blog.csdn.net/weixin_40802058/article/details/88689807?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522166386410216782417085920%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=166386410216782417085920&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-2-88689807-null-null.142%5Ev50%5Epc_rank_34_1,201%5Ev3%5Econtrol_2&utm_term=js%E6%95%B0%E7%BB%84%E6%8A%80%E8%83%BD%E9%9D%A2%E8%AF%95%E9%A2%98&spm=1018.2226.3001.4187

7 js 字符串面试题

js字符串类面试题_Flora_M的博客-CSDN博客文章目录一、查找字符串中出现最多的字符和个数二、实现千位分隔符三、将字符串转换成驼峰命名法四、字符串查找五、判断是否是电话号码六、验证是否是邮箱七、验证是否是身份证八、模板引擎实现一、查找字符串中出现最多的字符和个数let str = "abcabcabcbbccccc";let num = 0;let char = ''; // 使其按照一定的次序排列str = str.split('').sort().join(''); // "aaabbbbbcccccccc"// 定义正则表达https://blog.csdn.net/Flora_SM/article/details/110633448?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522166386428916782388029223%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=166386428916782388029223&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-1-110633448-null-null.142%5Ev50%5Epc_rank_34_1,201%5Ev3%5Econtrol_2&utm_term=js%20%E5%AD%97%E7%AC%A6%E4%B8%B2%E9%9D%A2%E8%AF%95%E9%A2%98&spm=1018.2226.3001.4187

8 VueRouter 面试题 

9 创建对象方式有哪些 

1.直接创建法

2 工厂模式

let person = createPerson("ec50n9", 19);

3  构造函数

let person = new Person("ec50n9", 19);

4.原型创建

创建一个学生构造函数  name,age eat公有方法
构造函数原型 == 实例化对象的原型
将共有的方法放入构造函数的原型中 

10 this 的指向问题 

this

应用场景:

  • 作为普通函数 --> window

  • 使用bind、call、apply --> 传入的对象

  • 作为对象方法被调用 --> 调用的对象

  • 在 class 方法中调用 --> 实例对象

  • 箭头函数 --> 上级作用域

11 flex布局常用属性

Flex 布局语法教程 | 菜鸟教程

1》水平(主轴上)对齐方式:

justify-content:flex-start | flex-end | center | space-between | space-around;

flex-start(默认值):左对齐

flex-end:右对齐

center: 居中

space-between:两端对齐,子元素间隔相等。

space-around:子元素两侧的间隔相等。

2》十字交叉轴上对齐方式

align-items:flex-start | flex-end | center | baseline | stretch;

flex-start:上对齐。

flex-end:下对齐。

center:交叉轴对齐。

baseline: 第一行文字的基线对齐。

stretch(默认值):如果子元素未设置高度或设为auto,将占满整个容器。

order/flex-grow/flex-shrink/flex-basis/flex/align-self

1》order属性(num)

order定义自身排列顺序。数值越小,越靠前,默认为0。-1/0/1/2/3/...

2》flex-grow属性(num)

flex-grow 定义自身放大比例,默认为0不放大。例如:1/2/1=25%:50%:25%

3》flex-shrink属性(num)

flex-shrink定义了空间不足时自身缩小比例,默认为1自动缩小,0不缩小。

4》flex-basis属性

flex-basis定义最小空间,默认值为auto,即自身的本来大小。

5》flex属性

flex属性是flex-grow, flex-shrink 和 flex-basis的简写,默认值为0 1 auto。后两个属性可选。

6》align-self属性

align-self定义自身对齐方式,可覆盖align-items属性。默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch。

3)Flex兼容性
 

//Webkit内核的浏览器,必须加上-webkit前缀。
.box{
  display: -webkit-flex; /* Safari */
  display: flex;
}

Flex布局属性总结_林宇风的博客-CSDN博客_flex布局均分1)Flex布局父容器属性flex-direction / flex-wrap / flex-flow / justify-content / align-items / align-content1》水平(主轴上)对齐方式:justify-content:flex-start | flex-end | center | space-between | space-arouhttps://blog.csdn.net/u012620506/article/details/52369653

12 Grid布局

css grid 属性 | 菜鸟教程

dispaly:grid;

Flex布局是轴线布局,只能指定"项目"针对轴线的位置,可以看作是一维布局,Grid 布局则是将容器划分成“行"和“列”,产生单元格,然后指定"项目所在”的单元格,可以看作是二维布局,Grid布局远比 Flex布局强大。(不过存在兼容性问题,使用之前应看具体需求)

grid-template-columns/grid-template-rows属性

1.grid-template-columns属性设置列宽, grid-template-rows属性设置行高

2.grid-row-gap :行间隙   grid-column-gap:列间隙    grid-gap :行,列间隙

3.网格模板

            grid-template-areas: 'header header header'

     /* 第一行header独占一行,因为有三列,所以要写3个header */

4 . justify-content   项目在容器里面的水平位置   

 align-ittems 项目在容器里面的竖直位置 

start   :对齐起始边框

end    :对齐结束边框

center : 居中

space-around , space-between , stretch和flex布局一样

5.跨行 跨列

grid-column-start :左边框所在的垂直网格线

grid-column-end :右边框所在的垂直网格线

grid-row-start :上边框所在的水平网格线

grid-row-end :下边框所在的水平网格线
 

Grid 属性列表
Grid Container 的全部属性

  • display
  • grid-template-columns
  • grid-template-rows
  • grid-template-areas
  • grid-template
  • grid-column-gap
  • grid-row-gap
  • grid-gap
  • justify-items
  • align-items
  • justify-content
  • align-content
  • grid-auto-columns
  • grid-auto-rows
  • grid-auto-flow
  • grid

Grid Items 的全部属性

  • grid-column-start
  • grid-column-end
  • grid-row-start
  • grid-row-end
  • grid-column
  • grid-row
  • grid-area
  • justify-self
  • align-self

(超详细)强大的grid布局_默默花上开的博客-CSDN博客_grid布局grid布局1.什么是grid布局?Flex布局是轴线布局,只能指定"项目"针对轴线的位置,可以看作是一维布局,Grid 布局则是将容器划分成“行"和“列”,产生单元格,然后指定"项目所在”的单元格,可以看作是二维布局,Grid布局远比 Flex布局强大。(不过存在兼容性问题,使用之前应看具体需求)2.布局方式----常用三种1.传统布局方式利用position属性 + display属性 + float属性布局, 兼容性最好, 但是效率低, 麻烦!2.flex布局有自己的一套属性, 效率高https://blog.csdn.net/leilei__66/article/details/122360901?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522166409971716782248533348%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=166409971716782248533348&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-122360901-null-null.142%5Ev50%5Epc_rank_34_1,201%5Ev3%5Econtrol_2&utm_term=grid%E5%B8%83%E5%B1%80&spm=1018.2226.3001.4187

css函数大全_丶oasis的博客-CSDN博客_css函数一、属性函数attr() 返回所选元素的属性值二、背景图片函数:linear-gradient():将线性突变设置为背景图像。定义至多两种色彩(从上到下)radial-gradient():将径向突变设置为背景图像。定义至多两种色彩(从核心到边缘)conic-gradient():锥形突变repeating-linear-gradient():反复线性突变repeating-radial-gradient():反复径向突变repeating-conic-gradient():反复锥形突变ihttps://blog.csdn.net/qq_41739983/article/details/124866522?ops_request_misc=&request_id=&biz_id=102&utm_term=css%E4%B8%ADrepeat%E5%87%BD%E6%95%B0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-3-124866522.142%5Ev50%5Epc_rank_34_1,201%5Ev3%5Econtrol_2&spm=1018.2226.3001.4187

13 HTML的几种定位方式

HTML中的几种定位方式

  1. 相对定位
  2. 绝对定位
  3. 固定定位
  4. 静态定位

定位模式(position)

选择器{position:属性值;}

1.静态定位:
设置方式为position: static;静态定位的盒子是标准流状态,用于取消定位。静态定位的盒子处于网页的最底层,并且top、left、bottom、right属性都不起作用。


2.相对定位:
设置方式为position: relative;相对定位的盒子没有脱离标准流,在页面中占据位置,盒子的层级高于标准流和浮动的盒子,top、left、bottom、right属性都会起作用。

设置了top、left、bottom、right属性后,相对定位的盒子是相对自己在标准流中的位置进行偏移,但是盒子在页面中占据的位置是不会改变的。

两个相对定位的盒子,默认的情况下第二个盒子层级比第一个盒子层级高,即第二个盒子可以覆盖第一个盒子,如果想让第一个盒子覆盖第二个盒子,可以通过设置z-index属性实现。
 

3.绝对定位:
设置方式为position: absolute;绝对定位的盒子脱离了标准流,在页面中不占位置,盒子的层级高于标准流和浮动的盒子,top、left、bottom、right属性都会起作用。

设置了top、left、bottom、right属性后,绝对定位的盒子是相对设置了定位属性(静态定位不算)的最近的父级盒子的位置进行偏移,如果没有设置了定位的父级盒子,则是相对于body标签进行偏移。

绝对定位的盒子可以通过设置z-index属性改变层级。

  • absolute 依据最近一层的定位元素定位.
  • 定位元素  absolute relatice fixed  
  • 没有找到定位元素 会找到body


4.固定定位:
设置方式为position: fixed;固定定位的盒子脱离了标准流,在页面中不占位置,盒子的层级高于标准流和浮动的盒子,top、left、bottom、right属性都会起作用。

设置了top、left、bottom、right属性后,固定定位的盒子是相对浏览器串口进行偏移。不管浏览器滚动条如何滚动,固定定位的盒子永远显示在浏览器窗口,不会出现滚动条往下滚动后就看不到固定定位的盒子的情况。因此固定定位的盒子常用于做底部导航栏和顶部导航栏。

固定定位的盒子可以通过设置z-index属性改变层级。

固定定位的盒子默认的宽高由其内容决定。
 

HTML的几种定位方式_Loss of my heart的博客-CSDN博客_html定位的几种方式HTML中的几种定位方式相对定位绝对定位固定定位定位详解定位也是用来布局的,它由两部分组成:定位=定位模式 + 边偏移边偏移边偏移属性示例描述toptop:80px顶端偏移量,定义元素相对于其父元素上边线的距离bottombottom:80px底部偏移量,定义元素相对于其父元素下边线的距离leftleft:80px左侧偏移量,定义元素相对于其父元素左边线的距离rightright:80px右侧偏移量,定义元素相对于其父元素右边线的https://blog.csdn.net/LmissL/article/details/108651972?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522166410039016782248542353%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=166410039016782248542353&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~pc_rank_34-1-108651972-null-null.142%5Ev50%5Epc_rank_34_1,201%5Ev3%5Econtrol_2&utm_term=html%20%E9%83%BD%E6%9C%89%E5%93%AA%E4%BA%9B%E5%AE%9A%E4%BD%8D%E6%96%B9%E5%BC%8F&spm=1018.2226.3001.4187

14 js 的浅拷贝

基本的数据类型  赋值即可 

一个新的对象直接拷贝已存在的对象的对象属性的引用,即浅拷贝。

浅拷贝只拷贝已存在对象的对象属性的引用,其余非对象属性是占用新的内存空间,并非与原对象共享。

方法一:object.assign
这个是es6的方法,可用于js对象合并,但是也可以用来浅拷贝
语法:Object.assign(a,…b)

let a = {};
let b = {c:{ d:1 }};
Object.assign(a,b);
console.log(a); // { c: { d: 10 } };
b.c.d = 10;

这里要注意的是Object.assign第一个参数必须是个空对象 

数组  

二、Array.prototype.slice()属于浅拷贝。

var arr = [2, 4, 6, { y: 10 }]
var newArr = arr.slice()
newArr[3].x = 20
newArr[3].y = 30
console.log(arr)     // [2, 5, 6, { y: 30, x: 20 }]
console.log(newArr)  // [2, 5, 6, { y: 30, x: 20 }]

浅拷贝只拷贝已存在对象的对象属性的引用: 

var obj = { x: 1, y: 2, z: { num: 10 } }
var newObj = {}
Object.assign(newObj, obj)
newObj.z.num = 20
console.log(obj)  // { x: 1, y: 2, z: { num: 20 } }
console.log(newObj)  // { x: 1, y: 2, z: { num: 20 } }


三、解构赋值

简单对象 

var obj1 = {a: 1, b: 2}
var obj2 = {...obj1}
 
obj2.a = 4
console.log(obj1, obj2)

在这里插入图片描述

 复杂对象 就是浅拷贝 

但是如果解构的是那种一维数组且里面的数据是简单类型,和那种对象里面是简单类型的是深拷贝。其他情况都是浅拷贝。

var obj1 = [{
    name: '臧三',
    childs: ['小明', '小芳']
}]
var obj2 = [...obj1]
 
obj2[0].childs = []
console.log(obj1, obj2)

 在这里插入图片描述

js中的解构赋值使用总结_接着奏乐接着舞。的博客-CSDN博客_js解构是深拷贝吗

js浅拷贝实现_木蓝茶陌*_*的博客-CSDN博客_js浅拷贝

深拷贝 :

1 jQuery.extend(deep,obj, object)

jQuery.extend() 函数用于将一个或多个对象的内容合并到目标对象。

$.extend( [deep ], target, object1 [, objectN ] )

deep 可选,Boolean类型 指示是否深度合并对象,默认为false。如果该值为true

target Object类型 目标对象

object1 可选。 Object类型 第一个被合并的对象。

2、JSON.parse(JSON.stringify(待拷贝对象))

3   自定义深拷贝函数。

function deepClone(o1, o2) {
    for (let k in o2) {
        if (typeof o2[k] === 'object') {
            o1[k] = {};
            deepClone(o1[k], o2[k]);
        } else {
            o1[k] = o2[k];
        }
    }
}

4 函数库 lodash,提供 cloneDeep 实现

1.下载相关库

npm i --save lodash

2.在相关文件中引入

import _ from "lodash"

3.调用 _.cloneDeep() 方法实现深拷贝

<script>
import _ from "lodash"
var objects = [{ 'a': 1 }, { 'b': 2 }];
var deep = _.cloneDeep(objects);
console.log(deep[0] === objects[0]); //false
</script>

15 ES6 解构赋值

解构赋值是一种快速为变量赋值的简洁语法,本质上仍然是为变量赋值,分为数组解构、对象解构两大类型。

分为数组解构和对象解构

数组解构是将数组的单元值快速批量赋值给一系列变量的简洁语法,如下代码所示:

js中的解构赋值使用总结_接着奏乐接着舞。的博客-CSDN博客_js解构是深拷贝吗本文前半部分介绍解构赋值在实际工作中的各种使用方法,后半部分介绍在使用过程中容易产生的疑问和解答。如果你对此很陌生,可先直接浏览本文最后部分,那里详细的介绍了什么是解构赋值,和最基础的用法。https://blog.csdn.net/wanghaoyingand/article/details/119361644?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522166410293916782395332591%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=166410293916782395332591&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~pc_rank_34-2-119361644-null-null.142%5Ev50%5Epc_rank_34_1,201%5Ev3%5Econtrol_2&utm_term=%E8%A7%A3%E6%9E%84%E8%B5%8B%E5%80%BC%E6%98%AF%E4%B8%8D%E6%98%AF%E6%B5%85%E6%8B%B7%E8%B4%9D&spm=1018.2226.3001.4187

16 HTML 面试题 

 HTML 面试题汇总_筱..的博客-CSDN博客_html面试题HTML 面试题汇总https://blog.csdn.net/qq_45808923/article/details/124647115?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522166412187816782391898752%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=166412187816782391898752&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~baidu_landing_v2~default-3-124647115-null-null.142%5Ev50%5Epc_rank_34_1,201%5Ev3%5Econtrol_2&utm_term=html%20%E9%9D%A2%E8%AF%95%E9%A2%98&spm=1018.2226.3001.4187

 【2022前端面试】HTML面试题汇总(加紧收藏)_归子莫的博客-CSDN博客_html面试没办法,逃不过。看了很多面经和总结,时过一年,再次更新本文,优化了排版。让题目一目了然。总结的更加系统化。https://blog.csdn.net/qq_45163122/article/details/108750774?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522166412187816782391882042%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=166412187816782391882042&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~pc_rank_34-4-108750774-null-null.142%5Ev50%5Epc_rank_34_1,201%5Ev3%5Econtrol_2&utm_term=html%20%E9%9D%A2%E8%AF%95%E9%A2%98&spm=1018.2226.3001.4187

17 webSocket自动重连

<template>
  <div>
    <button @click="sendDevName('xxxxxxxx')">发送</button>
    {{data}}
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  data () {
    return {
      data: null
    }
  },
  // html加载完成后执行initWebSocket()进行websocket初始化
  mounted () {
    this.initWebSocket()
  },
  // 离开该层时执行,划重点了!!!
  destroyed: function () {
    // 离开路由之后断开websocket连接
    this.websock.close()
  },
  methods: {
    // 初始化websocket
    initWebSocket () {
      const path = 'ws://xxx.xxx.xxx.xxx:端口号/xxxxx'// 后台给的websocket的ip地址
      this.websock = new WebSocket(path)
      this.websock.onmessage = this.websocketOnMessage
      this.websock.onopen = this.websocketOnOpen
      this.websock.onerror = this.websocketOnError
      this.websock.onclose = this.websocketClose
    },
    // 连接建立成功的信号
    websocketOnOpen () {
      console.log('初始化成功')// 连接成功后就可以在这里写一些回调函数了
    },
    // 连接建立失败重连
    websocketOnError () {
      // 如果报错的话,在这里就可以重新初始化websocket,这就是断线重连
      this.initWebSocket()
    },
    // 数据接收
    websocketOnMessage (e) {
      console.log(e)// e这个变量就是后台传回的数据,在这个函数里面可以进行处理传回的值
      this.data = e// 这边我绑定了一个data,data会在网页上显示后端传来的东西
    },
    // 数据发送
    websocketSend (Data) {
      this.websock.send(Data)// Data变量就是你想对后台说些啥,根据后端给你的接口文档传值进行交互
    },
    // 关闭的信号
    websocketClose () {
      console.log('断开连接')
    },
    // 传参给后端,这里对websocketSend又进行了一层封装,用不到的可以删除
    sendDevName (chooseDevice) {
      console.log(chooseDevice)
      this.websocketSend(chooseDevice)
    }
  }
}
</script>

前端点击发送按钮触发websocketSend (Data)函数后端就会收到前端发的消息,根据前端传过来的消息再发送前端所需要的信息,前端一旦监听到有东西发过来就会触发websocketOnMessage (e)这个函数 

普及一下websocket的状态

websocket的两个属性:readyState和bufferedAmount。
根据readyState属性可以判断webSocket的连接状态,该属性的值可以是下面几种:
0 :对应常量CONNECTING (numeric value 0),
正在建立连接连接,还没有完成。The connection has not yet been established.
1 :对应常量OPEN (numeric value 1),
连接成功建立,可以进行通信。The WebSocket connection is established and communication is possible.
2 :对应常量CLOSING (numeric value 2)
连接正在进行关闭握手,即将关闭。The connection is going through the closing handshake.
3 : 对应常量CLOSED (numeric value 3)
连接已经关闭或者根本没有建立。The connection has been closed or could not be opened.
例:
var socket = new WebSocket(url);
if(socket.readyState!=1){
alert(“未连接。”);
return;
}
根据bufferedAmount可以知道有多少字节的数据等待发送,若websocket已经调用了close方法则该属性将一直增长。
 

vue实现websocket断线重连_痴心的萝卜的博客-CSDN博客_vue websocket 断线重连vue实现websocket断线重连下面是自己写的demo和注释,为了以后再用websocket,看起来方便一点=-=<template> <div> <button @click="sendDevName('xxxxxxxx')">发送</button> {{data}} </div></templa...https://blog.csdn.net/qq_36826618/article/details/102509325?spm=1001.2101.3001.6650.3&utm_medium=distribute.pc_relevant.none-task-blog-2~default~CTRLIST~Rate-3-102509325-blog-87690056.t5_download_0_7w&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2~default~CTRLIST~Rate-3-102509325-blog-87690056.t5_download_0_7w&utm_relevant_index=6ReconnectingWebSocket

一个小的JavaScript库,它装饰WebSocket API以提供WebSocket连接,如果连接断开,它将自动重新连接。

webSocket自动重连_奥特蛋_mm的博客-CSDN博客_websocket自动重连ReconnectingWebSocket一个小的JavaScript库,它装饰WebSocket API以提供WebSocket连接,如果连接断开,它将自动重新连接。1.安装我安装时因为当前项目里一些包没有升级,导致无法直接自动安装,故用了 url 安装npm install https://github.com/joewalnes/reconnecting-websocket2.使用...https://blog.csdn.net/weixin_43254676/article/details/90599550?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522166418168116782427415680%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=166418168116782427415680&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-1-90599550-null-null.nonecase&utm_term=websocket&spm=1018.2226.3001.4450

webSocket 内存泄露 问题 

tomcat websocket WsFrameServer内存溢出

设置messageBufferText和messageBufferBinary的地方就是ServletServerContainerFactoryBean,最后发现在spring的配置文件中配置了这2个值:

tomcat websocket WsFrameServer内存溢出_愤怒的苹果ext的博客-CSDN博客_websocket 内存溢出

TOMCAT websocket 多连接内存泄漏与jetty对比分析_量子物理学的博客-CSDN博客

Websocket内存泄漏_Lee_01的博客-CSDN博客_websocket内存泄露

服务端调整WebSocket缓冲区大小_踮脚敲代码的博客-CSDN博客_websocket 缓存

18 ThingJS学习笔记

1.官网链接,若有不懂的直接戳官网:thing.js官网

2.开发工具:直接使用在线开发工具

3.学习路线:先了解清楚thing.js的用途

可以做可视化页面展示
做3D效果等


4.建议:一定要浏览文档及看文档的官方示例(非常重要个人觉得) 

5.做项目的时候都是用vue语法,但是目录结构方面有很大的差别:

自我感觉到的相同点:

可以用vue的双向数据绑定及生命周期,监听及计算属性的用法都相同,js都是通用的
自我感觉到的不同点: 

更多的是使用原生js创建节点及插入元素及使用模板字符串
自我感觉会vue的话这部分上手可以,但是thing.js的语法就 完全不同,需要自己去学习和摸索
暂时想到这么多就先写这么多了,有时间在写具体功能的实现方法,不算入门,在学习的过程中进步就好 
 

1 导入 建模文件 

2 进入thisgjs控制台

3 通过 CamBuilder 可搭建并输出一个园区,该园区可在 ThingJS 场景中加载

创建 App 对象


var app = new THING.App();
var obj = app.create({
    type: "Campus",
    url: "models/storehouse/",
    complete: function() {
    console.log("Campus created: " + this.id);
    }

App 提供的功能
App 作为 ThingJS 库的功能入口,提供了如下功能:

负责 3D 的初始化,如上述例子所见;
园区的加载;
提供了通过 create 创建物体、创建基本形状等;

提供了 query 搜索功能;

一些全局对象访问入口,如 root ,如 camera ;

通过 level 提供场景层级的控制;

提供了全局事件绑定功能;

时间:

通过 deltaTime 获取距离上一帧的流逝时间(毫秒);

通过 elapsedTime 获取从启动到现在的流逝时间(毫秒)。

效果控制:
 

场景和层级

ThingJS 场景中加载了园区后,场景中自动创建了 campus,building,floor,room 和一些在 CamBuilder 中添加的物体对象。这些对象不是独立散落在场景中的,他们会相互关联,形成一棵树的结构,从而构建了场景的层级。

ThingJS 提供了两套层级体系:父子树、分类对象属性树。
 

ThingJS学习笔记_飞雪冬玉花的博客-CSDN博客_thingjs1.现在模摸搭上建模这个需要专业人员操作切记需要操作的物品或者建筑一定要设置属性,要不然无法操作2,建模完毕后要对模型进行2次开发需要到ThingJS控制台上操作3.进入thisgjs控制台1.控制台会自动生成代码//加载场景代码var app = new THING.App({ // 场景地址 "url": "/api/scene/08c...https://blog.csdn.net/qq_34971162/article/details/105563226

19 xgplayer 

基于 vue 项目使用

// 先下载
npm install xgplayer           //  mp4格式
npm install xgplayer-hls.js    // hls格式
npm install xgplayer-flv.js    // flv格式
 
在页面中引入 
// hls格式
import hlsjsPlayer from 'xgplayer-hls.js'
// mp4格式
import Player from 'xgplayer'
// flv 格式
import flvJsPlayer from 'xgplayer-flv.js'
 

xgplayer详细教程,使用方法,渲染多个,去除黑边_陈十一i的博客-CSDN博客_xgplayer

vue xgplayer 引入_vue中使用video插件vue-video-player_weixin_39553272的博客-CSDN博客

vue集成 xgplayer西瓜播放器的组件封装。画面卡停重连。

vue集成 xgplayer西瓜播放器的组件封装。画面卡停重连。_多思考多学习的博客-CSDN博客_xgplayer

flv.js解决直播流延迟、断流重连以及画面卡死

flv.js解决直播流延迟、断流重连以及画面卡死_阿强iiii的博客-CSDN博客_flv 延迟

20 js继承 

原型链继承
重点:让新实例的原型等于父类的实例。
特点:实例可继承的属性有:实例的构造函数的属性,父类构造函数属性,父类原型的属性。(新实例不会继承父类实例的属性!)
缺点:
1、新实例无法向父类构造函数传参。
2、继承单一。
3、所有新实例都会共享父类实例的属性。(原型上的属性是共享的,一个实例修改了原型属性,另一个实例的原型属性也会被修改!)
借用构造函数继承
重点:用 call( ) 和 apply( ) 将父类构造函数引入子类函数(在子类函数中做了父类函数的自执行(复制))
特点:
   - 1、只继承了父类构造函数的属性,没有继承父类原型的属性。
2、解决了原型链继承缺点1、2、3。
3、可以继承多个构造函数属性(call多个)。
4、在子实例中可向父实例传参。
缺点:
   - 1、只能继承父类构造函数的属性。
2、无法实现构造函数的复用。(每次用每次都要重新调用)
3、每个新实例都有父类构造函数的副本,臃肿。
组合模式(又被称之为伪经典模式)
重点:结合了两种模式的优点,传参和复用
特点:
   - 1、可以继承父类原型上的属性,可以传参,可复用。
   - 2、每个新实例引入的构造函数属性是私有的。
缺点:调用了两次父类构造函数(耗内存),子类的构造函数会代替原型上的那个父类构造函数。
寄生组合式继承(圣杯模式)
重点:修复了组合继承的问题


 

JavaScript 面试题汇总_筱..的博客-CSDN博客JavaScript 面试题汇总https://blog.csdn.net/qq_45808923/article/details/124647125

21事件循环机制(宏任务、微任务)

22 let const var 的区别?什么是块级作用域?如何用?

  1. var 定义的变量,没有块的概念,可以跨块访问, 不能跨函数访问,有变量提升。
  2. let 定义的变量,只能在块作用域里访问,不能跨块访问,也不能跨函数访问,无变量提升,不可以重复声明。
  3. const 用来定义常量,使用时必须初始化(即必须赋值),只能在块作用域里访问,而且不能修改,无变量提升,不可以重复声明。

最初在 JS 中作用域有:全局作用域、函数作用域。没有块作用域的概念。

ES6 中新增了块级作用域。块作用域由 { } 包括,if 语句和 for 语句里面的 { } 也属于块作用域。

在以前没有块作用域的时候,在 if 或者 for 循环中声明的变量会泄露成全局变量,其次就是 { } 中的内层变量可能会覆盖外层变量。块级作用域的出现解决了这些问题。
 

23 ES6:export default 和 export 区别 

1.export与export default均可用于导出常量、函数、文件、模块等
2.你可以在其它文件或模块中通过import+(常量 | 函数 | 文件 | 模块)名的方式,将其导入,以便能够对其进行使用
3.在一个文件或模块中,export、import可以有多个,export default仅有一个
4.通过export方式导出,在导入时要加{ },export default则不需要
 

ES6:浅谈export default 和 export 区别_happy-angel的博客-CSDN博客

24  从输⼊URL到⻚⾯加载完中间发⽣了什么?

1 首先浏览器主进程接管,开了一个下载线程。
2 然后进行HTTP请求(DNS查询、IP寻址等等),中间会有三次捂手,等待响应,开始下载响应报文。
3 将下载完的内容转交给Renderer进程管理。
4 Renderer进程开始解析css rule tree和dom tree,这两个过程是并行的
5 解析绘制过程中,当浏览器遇到link标签或者script、img等标签,浏览器会去下载这些内容,遇到时候缓存的使用缓存,不适用缓存的重新下载资源。
6 css rule tree和dom tree生成完了之后,开始合成render tree,这个时候浏览器会进行layout,开始计算每一个节点的位置,然后进行绘制。
7 绘制结束后,关闭TCP连接,过程有四次挥手


下面说下渲染进程的过程


1. 浏览器通过网络请求后获取html数据,通过tcp传给渲染器进程
2. dom - 主线程将html解析构造DOM树
3. style - 样式计算
4. layoutTree - dom+style 根据dom树和样式生成layoutTree
5. paint -绘制 通过遍历 Layout Tree生成绘制顺序表
6. laryer - 布局 然后根据主进程将layoutTree 和绘制信息表传给合成器线程
7. 合成器线程 - 将得到的信息分图层分成更小的图块
8. 栅格线程 - 将更小的图块进行栅格化raster,返还给合成器线程draw quads图块信息 存储在GPU中
9. frame 合成器将栅格线程返回的图块合成帧交给浏览器进程
10. 浏览器进程 收到一帧的图像后传给GPU进行渲染



重排:


当改变dom的属性时,会重新进行样式计算,会重新布局和绘制


重绘:


当改变颜色时,只会发生样式计算和绘制(layer)
requestAnimationFrame()
会将主线程的任务分散到每一帧的间隔,从而不影响动画的流程
Fiber
react利用浏览器的空闲时间做优化

浏览器是个多进程结构,
1. 浏览器进程:控制除标签页外的用户界面,包括地址,书签,后退,前进按钮等,以及负责与浏览器其他进程负责协调工作2.
2. 缓存进程
3. 网络进程 发起网络请求
4. 渲染器进程 渲染Tab 有可能会为每个标签页是一个渲染进程
5. GPU进程 渲染
6. 插件进程 内置插件

HTML 变形(transform)、转换(transition)和动画(animation)

HTML 变形(transform)、转换(transition)和动画(animation)_熟悉的新风景的博客-CSDN博客_html transform
Transform
会直接运行合成器线程,所以不会感染主线程的渲染
在移动端使用3d转换可以优化性能(如果设备有3d加速引擎 GPU 可以提高性能 , 2d转换是无法调用GPU,2G是靠的CPU)

CSS基础 -- display属性

CSS基础 -- display属性_weixin_41387874的博客-CSDN博客_css中display属性

CSS 动画如何实现?

参考答案:

即 animation 属性,对元素某个或多个属性的变化进行控制,可以设置多个关键帧。属性包含了动画的名称、完成时间(以毫秒计算)、周期、间隔、播放次数、是否反复播放、不播放时应用的样式、动画暂停或运行。

它不需要触发任何事件就可以随着时间变化来改变元素的样式。

使用 CSS 做动画:

@keyframes 规定动画。
animation 所有动画属性的简写属性。
animation-name 规定 @keyframes 动画的名称。
animation-duration 规定动画完成一个周期所花费的秒或毫秒。默认是 0。
animation-timing-function 规定动画的速度曲线。默认是 ease。
animation-fill-mode 规定当动画不播放时(当动画完成时,或当动画有一个延迟未开始播放时),要应用到元素的样式。
animation-delay 规定动画何时开始。默认是 0。
animation-iteration-count 规定动画被播放的次数。默认是 1。
animation-direction 规定动画是否在下一周期逆向地播放。默认是 normal。
animation-play-state 规定动画是否正在运行或暂停。默认是 running。
 

display:inline-block 在什么情况下会产生间隙?

空隙产生的原因

元素被当成行内元素排版的时候,元素之间的空白符(空格、回车换行等)都会被浏览器处理,根据 white-space 的处理方式(默认是 normal,合并多余空白),原来 HTML 代码中的回车换行被转成一个空白符,在字体不为 0 的情况下,空白符占据一定宽度,所以 inline-block 的元素之间就出现了空隙。

这些元素之间的间距会随着字体的大小而变化,例如:当行内元素 font-size:16px 时,间距为8px。

解决空隙的办法

  1. 办法一:解决元素之间的空白符
<!-- 将前一个标签结束符和后一个标签开始符写在同一行 -->
<div class="parent">
  <div class="child">child1
  </div><div class="child">child2
  </div>
</div>
<!-- 将所有子元素写在同一行 -->
<div class="parent">
  <div class="child">child1</div><div class="child">child2</div>
</div>

缺点:代码的可读性变差。

方法二:为父元素中设置 font-size: 0,在子元素上重置正确的 font-size

<div class="parent" style="font-size: 0px">  <div class="child" style="font-size: 16px">child1</div>  <div class="child" style="font-size: 16px">child2</div></div>



缺点:inline-block 元素必须设定字体,不然行内元素中的字体不会显示。 增加了代码量。

方法三:为 inline-block 元素添加样式 float:left
缺点:float布局会有高度塌陷问题

方法四:设置子元素margin值为负数
 

.parent .child + .child {
  margin-left: -2px
}


缺点:元素之间间距的大小与上下文字体大小相关;并且同一大小的字体,元素之间的间距在不同浏览器下是不一样的。

如:font-size:16px时,Chrome下元素之间的间距为 8px,而 Firefox 下元素之间的间距为 4px。所以不同浏览器下 margin-right 的负值是不一样的,因此这个方法不通用。

注意:当 marigin-right 使用相对单位 em 来表示时,Chrome 下可以正常去除间距,而 Firefox 下元素之间有重叠。

方法五:最优解在这,设置父元素,display:table 和 word-spacing

.parent{
  display: table;
  word-spacing:-1em; /*兼容其他浏览器,题主还未验证*/
}


CSS3:overflow属性详解

Overflow属心常见的有四个:visible,hidden,auto和scroll;

visible为overflow 的默认值,为超出显示;

hidden为超出隐藏;

auto为自动,即超出会出现滚动条, 不超出就没有滚动条;

scroll为内容会被修剪,但是浏览器会显示滚动条以便查看其余的内容。

第一种用法:解决margin-top的传递问题

margin-top的传递问题:子元素的margin-top会把父元素一起带下来,给父元素加overflow:hidden即可解决

第二种用法:清除浮动带来的影响  --- 父元素高度塌陷

万能清除法

overflow:hidden

clear:both

第三种用法:显隐动画  --- 超出隐藏

第四种用法:单行文本超出省略
 

.sl{
 
    white-space:nowrap;/*不换行*/
 
    overflow:hidden;/*超出隐藏*/
    
    text-overflow:ellipsis;/*超出省略*/
 
    width:;
 
}


CSS3:overflow属性详解_小谭鸡米花的博客-CSDN博客_overflow属性

什么是选择器?有哪些选择器?

参考答案:

选择器决定将样式应用在哪个或哪些元素身上。

元素选择器:例如 div{…} p{…}
id 选择器: 例如 #box{…}
类选择器: 例如 .box{…}
属性选择器:[href=“#”]{…}
通配:*{…}
组合(并集)选择器:div,p,a,.main{…}
交集选择器:input[type=“text”]{…}
后代选择器:header nav{…}
子级选择器: ul>li{…}
伪类选择器:
:nth-child(num){…}
:nth-child(odd){…}
:nth-child(even){…}
:nth-of-type{…}
:first-child{…}
:last-child{…}
only-child{…}
a:link{…}
a:visited{…}
:hover{…}
a:active{…}
伪元素选择器:
::before{…}
::after{…}
::first-letter{…}
::first-line{…}
 

CSS中的伪类和伪元素

1、伪类
概念:为处于某个状态的已有元素添加对应的样式,这个状态是根据用户行为而动态改变的。

它可以用于

设置鼠标悬停在元素上时的样式
为已访问和未访问链接设置不同的样式
设置元素获得焦点时的样式
2、伪元素
概念:创建一些不在文档树中的元素,并为其添加样式。(就是选取某些元素前面或后面这种普通选择器无法完成的工作,虽然用户可以看到这些文本,但是这些文本实际上不在文档树中。)

它可以用于

设置元素的首字母、首行的样式
在元素的内容之前或之后插入内容
 

伪类和伪元素的引入是因为在文档树里有些信息无法被充分描述

比如CSS没有“段落的第一行”、“文章首字母”之类的选择器,而这在一些出版场景里又是必须的,因此引入。

CSS 引入伪类和伪元素的概念是为了实现基于文档树之外的信息的格式化。

1、状态伪类:基于元素当前状态进行选择的
元素的样式会根据其状态呈现不同的样式,当元素处于某状态时会呈现该样式,而进入另一状态后,该样式也会失去。

常见的状态伪类

 :link 应用于未被访问过的链接;    

 :hover 应用于鼠标悬停到的元素;

 :active 应用于被激活的元素;

 :visited 应用于被访问过的链接,与:link互斥。

 :focus 应用于拥有键盘输入焦点的元素。

CSS中的伪类和伪元素(详细)_LyiRo_的博客-CSDN博客_css伪类和伪元素

2、结构性伪类:css3新增选择器

利用dom树进行元素过滤,通过文档结构的互相关系来匹配元素,能够减少class和id属性的定义,使文档结构更简洁

常见的结构性伪类

  :first-child 选择某个元素的第一个子元素;  
  :last-child 选择某个元素的最后一个子元素;
  :nth-child(n) 匹配属于其父元素的第 n个子元素,不论元素的类型;
  :nth-last-child() 从这个元素的最后一个子元素开始算,选匹配属于其父元素的第 n个子元素,不论元素的类型;
  :nth-of-type() 规定属于其父元素的第n个 指定 元素;
  :nth-last-of-type() 从元素的最后一个开始计算,规定属于其父元素的指定 元素;
  :first-of-type 选择一个上级元素下的第一个同类子元素;
  :last-of-type 选择一个上级元素的最后一个同类子元素;
  :only-child 选择它的父元素的唯一一个子元素;
  :only-of-type 选择一个元素是它的上级元素的唯一一个相同类型的子元素;
 :checked匹配被选中的input元素,这个input元素包括radio和checkbox。
 :empty 选择的元素里面没有任何内容。
  :disabled匹配禁用的表单元素。
  :enabled匹配没有设置disabled属性的表单元素。
  :valid匹配条件验证正确的表单元素。
  :in-range选择具有指定范围内的值的 <input> 元素。
  :optional选择不带 "required" 属性的 <input> 元素。
  :focus选择获得焦点的 <input> 元素。
 

 伪元素

所有的伪元素

选择器    例子    例子描述
::after    p::after    在每个 <p> 元素之后插入内容。
::before    p::before    在每个 <p> 元素之前插入内容。
::first-letter    p::first-letter    选择每个 <p> 元素的首字母。
::first-line    p::first-line    选择每个 <p> 元素的首行。
::selection    p::selection    选择用户选择的元素部分。


注意:

 CSS3 规范中有一部分要求,为了区分伪类和伪元素,伪元素使用两个冒号 (::), 伪类使用一个冒号 (:)

对于 CSS2 中已经有的伪元素,例如 :before,单冒号和双冒号的写法 ,::before 作用是一样的,所以,如果网站只需要兼容 webkit、firefox、opera 等浏览器,伪元素建议采用双冒号的写法,如果是要兼容 IE 浏览器,建议用 CSS2 的单冒号写法。

CSS中的伪类和伪元素(详细)_LyiRo_的博客-CSDN博客_css伪类和伪元素

网页基础之CSS_LyiRo_的博客-CSDN博客

伪类和伪元素的应用

1、画分割线

2、清除浮动

什么是继承?CSS 中哪些属性可以继承?哪些不可以继承?

参考答案:

继承,指元素可以自动获得祖先元素的某些 CSS 属性。通常来说文本类的属性具有继承性。
文本类的样式可以继承:例如 color、 font-size、 line-height、 font-family、 font-weight、 font-weight、 text-decoration、 letter-spacing、text-align 等等
display、 margin、 padding、 border、 background、 position、 float 等则不会被继承
 

transition、transform、animate 的区别?

HTML5 有哪些新特性、移除了那些元素?

HTML5 现在已经不是 SGML 的⼦集,主要是关于图像,位置,存储,多任务等功能的增加
绘画 canvas
⽤于媒介回放的 video 和 audio 元素
本地离线存储 localStorage ⻓期存储数据,浏览器关闭后数据不丢失
sessionStorage 的数据在浏览器关闭后⾃动删除
语意化更好的内容元素,⽐如 article 、 footer 、 header 、 nav 、 section
表单控件, calendar 、 date 、 time 、 email 、 url 、 search
新的技术 webworker 、 websocket 、 Geolocation
移除的元素:

纯表现的元素: basefont 、 big 、 center 、 font 、 s 、 strike 、 tt 、 u
对可⽤性产⽣负⾯影响的元素: frame 、 frameset 、 noframes
⽀持 HTML5 新标签:

IE8/IE7/IE6 ⽀持通过 document.createElement ⽅法产⽣的标签
可以利⽤这⼀特性让这些浏览器⽀持 HTML5 新标签
浏览器⽀持新标签后,还需要添加标签默认的样式
当然也可以直接使⽤成熟的框架、⽐如 html5shim

HTML5 引入什么新的表单属性?

autocomplete

novalidate

新属性:

autocomplete

autofocus

form

formaction

formenctype

formmethod

formnovalidate

formtarget

height and width

list

min and max

multiple

pattern (regexp)

placeholder

required

step

form 新属性:

autocomplete:属性规定表单是否应该启用自动完成功能。autocomplete 属性适用于 <form>,以及下面的 <input>类型:
text, search, url, telephone, email, password, date,pickers, range 以及 color。语法是 <form autocomplete=“on|off”>

novalidate:如果使用该属性,则提交表单时不进行内容的验证。novalidate 属性适用于:<form>,以及以下类型的 <input> 标签:text, search, url, telephone, email, password, date pickers, range 以及 color。语法:novalidate=“novalidate”
input 新属性:

autocomplete:同上

autofocus:规定输入字段在页面加载时是否获得焦点,加载完成后,光标马上定位在该 input

form:form 属性的值必须是其所属表单的 id。如需引用一个以上的表单,请使用空格分隔的列表。

formaction:属性覆盖 form 元素的 action 属性,比如两个提交按钮的时候,一个是正常提交,一个是管理员提交。该属性适用于 type=“submit” 以及 type=“image”。语法是 formaction=“#”

formenctype:formenctype 属性覆盖 form 元素的 enctype 属性。该属性与 type=“submit” 和 type=“image” 配合使用。属性规定在发送到服务器之前应该如何对表单数据进行编码。

formmethod:覆盖表单的 method 属性。适用于 type=“submit” 和 type=“image”

formnovalidate:formnovalidate 属性覆盖 form 元素的 novalidate 属性。如果使用该属性,则提交表单时按钮不会执行验证过程。

formtarget:覆盖表单的 target 属性。适用于 type=“submit” 和 type=“image”, 该属性规定在何处打开 action URL。

height 和 width:height 和 width 属性规定用于 image 类型的 <input> 标签的图像高度和宽度。

list:引用包含输入字段的预定义选项的 datalist 。

min 和 max:min 属性与 max 属性配合使用,可创建合法值范围,两个要一对用。语法是选择 0-10 数字,例如:<input type=“number” name=“points” min=“0” max=“10” />

multiple:如果使用该属性,则允许一个以上的值,比如上传文件的时候,设置这个属性后可以一次选择几个图片;multiple 属性适用于以下类型的 <input>标签:email 和 file。

pattern (regexp):描述了一个正则表达式用于验证 <input> 元素的值,pattern 属性适用于以下 <input> 类型:text, search, url, telephone, email 以及 password。

placeholder:提供可描述输入字段预期值的提示信息 (hint)。该提示会在输入字段为空时显示,并会在字段获得焦点时消失。

required:规定必需在提交之前填写输入字段。 如果使用该属性,则字段是必填(或必选)的。

step:为输入域规定合法的数字间隔。 如果 step=“3”,则合法的数是 -3、0、3、6 等。step 属性可以与 max 和 min 属性创建一个区域值。
 

 iframe 的作用

iframe 也称作嵌入式框架,嵌入式框架和框架网页类似,它可以把一个网页的框架和内容嵌入在现有的网页中。

优点

重载页面时不需要重载整个页面,只需要重载页面中的一个框架页(减少了数据的传输,增加了网页下载速度)
方便制作导航栏
缺点

会产生很多页面,不容易管理
浏览器的后退按钮无效
无法被一些搜索引擎索引到
多数小型的移动设备(PDA 手机)无法完全显示框架
由于上面诸多缺点,因此不符合标准网页设计的理念,已经被标准网页设计抛弃
目前框架的所有优点完全可以使用 Ajax 实现,因此已经没有必要使用 iframe 框架了。


HTML5 新增哪些新特性 ?

HTML5 新增特性有:

  1. 拖拽释放
  2. 语义化更好的内容标签
  3. 视频、音频
  4. 画布
  5. 地理
  6. 本地离线存储
  7. 表单控件

行内元素和块级元素区别,有哪些,怎样转换?(顶呱呱)

块级元素:

总是在新行上开始;
高度,行高以及外边距和内边距都可控制;
宽度缺省是它的容器的 100%,除非设定一个宽度。
它可以容纳内联元素和其他块元素
行内元素:

和其他元素都在一行上;
高,行高及外边距和内边距不可改变;
宽度就是它的文字或图片的宽度,不可改变
内联元素只能容纳文本或者其他内联元素
对行内元素,需要注意如下:

设置宽度 width 无效。
设置高度 height 无效,可以通过 line-height 来设置。
设置 margin 只有左右 margin 有效,上下无效。
设置 padding 只有左右 padding 有效,上下则无效。注意元素范围是增大了,但是对元素周围的内容是没影响的。
通过 display 属性对行内元素和块级元素进行切换(主要看第 2、3、4 个值):
 

HTML5 与 HTML4 的区别(华安永康)

参考答案:

1、语法简化

HTML、XHTML 的 DOCTYPE、html、meta、script 等标签,在 HTML5 中有大幅度的简化。

2、统一网页内嵌多媒体语法

以前,在网页中播放多媒体时,需要使用插件的方式来完成。有了 HTML5 之后,使用<video>或<audio>标签播放视频和音频,不需要在安装其他的什么来播放了。

3、新增了语义标签

为了增加网页的可读性,HTML5 增加了 <header>、<footer>、<section>、<article>、<nav>、<hgroup>、<aside>、<figure> 语义标签。

4、HTML5 废除了一些旧标签

废除的大部分是网页美化方面的标签,例如:<big>、<u>、<font>、<basefont>、<center>、<s>、<tt>。对 <frame>框架,不能使用。

5、全新的表单设计

表单是网页设计者最常用的功能,HTML5 对表单做了很大的更改,不但新增了几项新的标签,对原来的 <form> 标签也增加了许多属性。

6、新增了 <canvas> 标签,可以绘制图形

HTML5 新增了具有绘图功能的 <canvas>

7、新增许多新的 API

例如:querySelector、querySelectorAll、拖拽相关 Api

form 表单上传文件时需要进行什么样的声明?

enctype="multipart/form-data"
 

如何在一张图片上的某一个区域做到点击事件

1、插入图片,并设置好图像的有关参数,且在 <img> 标记中设置参数 usemap=“#Map”,以表示对图像地图(Map)的引用;
2、用 <map> 标记设定图像地图的作用区域,并取名为:Map;
3、分别用 <area> 标记针对相应位置划分出多个矩形作用区域,并设定好其链接参数 href。
 

 a 元素除了用于导航外,还可以有什么作用?

href 属性中的 url 可以是浏览器支持的任何协议,所以 a 可以用于手机拨号 <a href=‘tel:10086’>10086、发送短信 <a href=“sms:10086?body=test”> 等。

当然,a 元素最常见的两个应用就是做锚点和下载文件。

锚点可以在点击时快速定位到一个页面的某一个位置,而下载的原理在于 a 标签所对应的资源浏览器无法解析,于是浏览器会选择将其下载下来。
 

说一说类的继承

  • 原型链继承
  • 借用构造函数继承
  • 组合模式继承
  • 共享原型继承
  • 原型式继承
  • 寄生式继承
  • 寄生组合式继承
  • ES6中class的继承(新)

很长一段时间,JS 继承使用的都是组合继承。这种继承也被称之为伪经典继承,该继承方式综合了原型链和盗用构造函数的方式,将两者的优点集中了起来。

// 基类
var Person = function (name, age) {
    this.name = name;
    this.age = age;
}
Person.prototype.test = "this is a test";
Person.prototype.testFunc = function () {
    console.log('this is a testFunc');
}

// 子类
var Student = function (name, age, gender, score) {
    Person.apply(this, [name, age]); // 盗用构造函数
    this.gender = gender;
    this.score = score;
}
Student.prototype = new Person(); // 改变 Student 构造函数的原型对象
Student.prototype.testStuFunc = function () {
    console.log('this is a testStuFunc');
}

// 测试
var zhangsan = new Student("张三", 18, "男", 100);
console.log(zhangsan.name); // 张三
console.log(zhangsan.age); // 18
console.log(zhangsan.gender); // 男
console.log(zhangsan.score); // 100
console.log(zhangsan.test); // this is a test
zhangsan.testFunc(); // this is a testFunc
zhangsan.testStuFunc(); // this is a testStuFunc

组合继承弥补了之前原型链和盗用构造函数这两种方式各自的不足,是 JavaScript 中使用最多的继承方式。

组合继承最大的问题就是效率问题。最主要就是父类的构造函数始终会被调用两次:一次是在创建子类原型时调用,另一次是在子类构造函数中调用。

圣杯模式的继承解决了这一问题,其基本思路就是不通过调用父类构造函数来给子类原型赋值,而是取得父类原型的一个副本,然后将返回的新对象赋值给子类原型。

// target 是子类,origin 是基类
// target ---> Student, origin ---> Person
function inherit(target, origin) {
    function F() { }; // 没有任何多余的属性

    // origin.prototype === Person.prototype, origin.prototype.constructor === Person 构造函数
    F.prototype = origin.prototype;

    // 假设 new F() 出来的对象叫小 f
    // 那么这个 f 的原型对象 === F.prototype === Person.prototype
    // 那么 f.constructor === Person.prototype.constructor === Person 的构造函数
    target.prototype = new F();

    // 而 f 这个对象又是 target 对象的原型对象
    // 这意味着 target.prototype.constructor === f.constructor
    // 所以 target 的 constructor 会指向 Person 构造函数

    // 我们要让子类的 constructor 重新指向自己
    // 若不修改则会发现 constructor 指向的是父类的构造函数
    target.prototype.constructor = target;
}


// 基类
var Person = function (name, age) {
    this.name = name;
    this.age = age;
}
Person.prototype.test = "this is a test";
Person.prototype.testFunc = function () {
    console.log('this is a testFunc');
}


// 子类
var Student = function (name, age, gender, score) {
    Person.apply(this, [name, age]);
    this.gender = gender;
    this.score = score;
}
inherit(Student, Person); // 使用圣杯模式实现继承
// 在子类上面添加方法
Student.prototype.testStuFunc = function () {
    console.log('this is a testStuFunc');
}

// 测试
var zhangsan = new Student("张三", 18, "男", 100);

console.log(zhangsan.name); // 张三
console.log(zhangsan.age); // 18
console.log(zhangsan.gender); // 男
console.log(zhangsan.score); // 100
console.log(zhangsan.test); // this is a test
zhangsan.testFunc(); // this is a testFunc
zhangsan.testStuFunc(); // this is a testStuFunc

  • 原型链继承
  • 借用构造函数继承
  • 组合模式继承
  • 共享原型继承
  • 原型式继承
  • 寄生式继承
  • ES6中class的继承(新)

ES6——class继承

原理:ES5的继承,实质是先创造的子类的实例对象this,然后再将父类的方法添加到this上面(Parent.apply(this))。
ES6的继承机制完全不同,实质就是先将父类实例对象上的方法和属性,加到this上面(所以必须调用super()方法),然后再用子类的构造函数修改this。
需要注意的是:class关键字只是原型的语法糖,js继承依然是基于原型实现的。
 

class Parent{
  constructor(name) {
    this.name = name;
    this.hobbies = ["sing", "dance", "rap"];
  }
  getHobbies() {
    return this.hobbies;
  }
  static getCurrent() {
    console.log(this);
  }
}

class Child extends Parent {
  constructor(name) {
    super(name);
  }
}

var c1 = new Child('c1');
var c2 = new Child('c2');

console.log(c1 instanceof Child); // true
console.log(c1 instanceof Parent); // true

class继承的优点

语法简单易懂,操作更加方便

class继承的缺点

不是每个浏览器都支持class关键字

javascript中继承的几种方式_微醉~的博客-CSDN博客_javascript的继承方式

简述for in 和 for of 的区别

总之,for...in 循环主要是为了遍历对象而生,不适用于遍历数组

for...of 循环可以用来遍历数组、类数组对象,字符串、Set、Map 以及 Generator 对象

1、for...in 循环:只能获得对象的键名,不能获得键值

      for...of 循环:允许遍历获得键值

2、对于普通对象,没有部署原生的 iterator 接口,直接使用 for...of 会报错

3、for...in 循环不仅遍历数字键名,还会遍历手动添加的其它键,甚至包括原型链上的键。for...of 则不会这样

4、forEach 循环无法中途跳出,break 命令或 return 命令都不能奏效

for...of 循环可以与break、continue 和 return 配合使用,跳出循环

5、无论是 for...in 还是 for...of 都不能遍历出 Symbol 类型的值,遍历 Symbol 类型的值需要用 Object.getOwnPropertySymbols() 方法

map()和forEach()的区别和理解

forEach和map的区别_南方有小桥的博客-CSDN博客_foreach和map

相同点
都是循环数组中的每一项

都支持3个参数,参数分别是item(当前每一项)、index(索引值)、arr(原数组)

匿名函数中的this都是指向window

只能遍历数组

不同点
forEach没有返回值,map有返回值

也就是说,forEach()会修改原来的数组。而map()方法会得到一个新的数组并返回。

示例1:

let newList = this.numList.map(value => value * value).filter(value => value>10);
    return newList;


map可以返回新的数组,并且还可以和filter,reduce等结合使用

示例2:

let newList = this.numList.forEach(value => value * value);
    return newList;
forEach会报undefined

总结
1. forEach适合于你并不打算改变数据的时候,而只是想用数据做一些事情 – 比如存入数据库或则打印出来。

2. map()适用于你要改变数据值的时候。不仅仅在于它更快,而且返回一个新的数组。这样的优点在于你可以使用复合(composition)(map(), filter(), reduce()等组合使用)。

 new 操作符都做了哪些事?

new 运算符创建一个用户定义的对象类型的实例或具有构造函数的内置对象的实例。

new 关键字会进行如下的操作:
步骤 1:创建一个空的简单 JavaScript 对象,即 { } ;
步骤 2:链接该对象到另一个对象(即设置该对象的原型对象);
步骤 3:将步骤 1 新创建的对象作为 this 的上下文;
步骤 4:如果该函数没有返回对象,则返回 this。
 

call、apply、bind 的区别 ?

call 和 apply 的功能相同,区别在于传参的方式不一样:

fn.call(obj, arg1, arg2, …) 调用一个函数, 具有一个指定的 this 值和分别地提供的参数(参数的列表)。
fn.apply(obj, [argsArray]) 调用一个函数,具有一个指定的 this 值,以及作为一个数组(或类数组对象)提供的参数。
bind 和 call/apply 有一个很重要的区别,一个函数被 call/apply 的时候,会直接调用,但是 bind 会创建一个新函数。当这个新函数被调用时,bind( ) 的第一个参数将作为它运行时的 this,之后的一序列参数将会在传递的实参前传入作为它的参数。
 

你了解 node 中的事件循环机制吗?node11 版本以后有什么改变

因此,Node.js 的单线程仅仅是指 JavaScript 运行在单线程中,而并非 Node.js 是单线程。

Node.JS 的事件循环分为 6 个阶段:

timers 阶段:这个阶段执行 timer( setTimeout、setInterval )的回调
I/O callbacks 阶段:处理一些上一轮循环中的少数未执行的 I/O 回调
idle、prepare 阶段:仅 Node.js 内部使用
poll 阶段:获取新的 I/O 事件, 适当的条件下 Node.js 将阻塞在这里
check 阶段:执行 setImmediate( ) 的回调
close callbacks 阶段:执行 socket 的 close 事件回调
事件循环的执行顺序为:

外部输入数据 –-> 轮询阶段( poll )-–> 检查阶段( check )-–> 关闭事件回调阶段( close callback )–-> 定时器检测阶段( timer )–-> I/O 事件回调阶段( I/O callbacks )-–>闲置阶段( idle、prepare )–->轮询阶段(按照该顺序反复运行)…

浏览器和 Node.js 环境下,微任务任务队列的执行时机不同

Node.js 端,微任务在事件循环的各个阶段之间执行
浏览器端,微任务在事件循环的宏任务执行完之后执行
Node.js v11.0.0 版本于 2018 年 10 月,主要有以下变化:

V8 引擎更新至版本 7.0
http、https 和 tls 模块默认使用 WHESWG URL 解析器。
隐藏子进程的控制台窗口默认改为了 true。
FreeBSD 10不再支持。
增加了多线程 Worker Threads
 

promise.all 方法的使用场景?数组中必须每一项都是 promise 对象吗?不是 promise 对象会如何处理 ?

promise.all(promiseArray) 方法是 promise 对象上的静态方法,该方法的作用是将多个 promise 对象实例包装,生成并返回一个新的 promise 实例。

此方法在集合多个 promise 的返回结果时很有用。

返回值将会按照参数内的 promise 顺序排列,而不是由调用 promise 的完成顺序决定。

promise.all 的特点

接收一个Promise实例的数组或具有Iterator接口的对象

如果元素不是Promise对象,则使用Promise.resolve转成Promise对象

如果全部成功,状态变为resolved,返回值将组成一个数组传给回调

只有有一个失败,状态就变为 rejected,返回值将直接传递给回调 *all( )*的返回值,也是新的 promise 对象
 

this 的指向哪几种 ?

JS 中继承实现的几种方式

JS 的继承随着语言的发展,从最早的对象冒充到现在的圣杯模式,涌现出了很多不同的继承方式。每一种新的继承方式都是对前一种继承方式不足的一种补充。

原型链继承
重点:让新实例的原型等于父类的实例。
特点:实例可继承的属性有:实例的构造函数的属性,父类构造函数属性,父类原型的属性。(新实例不会继承父类实例的属性!)
缺点:
1、新实例无法向父类构造函数传参。
2、继承单一。
3、所有新实例都会共享父类实例的属性。(原型上的属性是共享的,一个实例修改了原型属性,另一个实例的原型属性也会被修改!)
借用构造函数继承
重点:用 call( ) 和 apply( ) 将父类构造函数引入子类函数(在子类函数中做了父类函数的自执行(复制))
特点:
   - 1、只继承了父类构造函数的属性,没有继承父类原型的属性。
2、解决了原型链继承缺点1、2、3。
3、可以继承多个构造函数属性(call多个)。
4、在子实例中可向父实例传参。
缺点:
   - 1、只能继承父类构造函数的属性。
2、无法实现构造函数的复用。(每次用每次都要重新调用)
3、每个新实例都有父类构造函数的副本,臃肿。
组合模式(又被称之为伪经典模式)
重点:结合了两种模式的优点,传参和复用
特点:
   - 1、可以继承父类原型上的属性,可以传参,可复用。
   - 2、每个新实例引入的构造函数属性是私有的。
缺点:调用了两次父类构造函数(耗内存),子类的构造函数会代替原型上的那个父类构造函数。
寄生组合式继承(圣杯模式)
重点:修复了组合继承的问题
 

什么是事件监听

在绑定事件的时候,我们需要对应的书写一个事件处理程序,来应对事件发生时的具体行为。

这个事件处理程序我们也称之为事件监听器。

当事件绑定好后,程序就会对事件进行监听,当用户触发事件时,就会执行对应的事件处理程序。

关于事件监听,W3C 规范中定义了 3 个事件阶段,依次是捕获阶段、目标阶段、冒泡阶段。

捕获阶段:在事件对象到达事件目标之前,事件对象必须从 window 经过目标的祖先节点传播到事件目标。 这个阶段被我们称之为捕获阶段。在这个阶段注册的事件监听器在事件到达其目标前必须先处理事件。

目标 阶段:事件对象到达其事件目标。 这个阶段被我们称为目标阶段。一旦事件对象到达事件目标,该阶段的事件监听器就要对它进行处理。如果一个事件对象类型被标志为不能冒泡。那么对应的事件对象在到达此阶段时就会终止传播。

冒泡 阶段:事件对象以一个与捕获阶段相反的方向从事件目标传播经过其祖先节点传播到 window。这个阶段被称之为冒泡阶段。在此阶段注册的事件监听器会对相应的冒泡事件进行处理。
 

什么是 js 的闭包?有什么作用?

  1. 匿名自执行函数
  2. 结果缓存
  3. 封装
  4. 实现类和继承

let const var 的区别?什么是块级作用域?如何用?

var 定义的变量,没有块的概念,可以跨块访问, 不能跨函数访问,有变量提升。
let 定义的变量,只能在块作用域里访问,不能跨块访问,也不能跨函数访问,无变量提升,不可以重复声明。
const 用来定义常量,使用时必须初始化(即必须赋值),只能在块作用域里访问,而且不能修改,无变量提升,不可以重复声明。
最初在 JS 中作用域有:全局作用域、函数作用域。没有块作用域的概念。

ES6 中新增了块级作用域。块作用域由 { } 包括,if 语句和 for 语句里面的 { } 也属于块作用域。

在以前没有块作用域的时候,在 if 或者 for 循环中声明的变量会泄露成全局变量,其次就是 { } 中的内层变量可能会覆盖外层变量。块级作用域的出现解决了这些问题。
 

JS 的基本数据类型有哪些?基本数据类型和引用数据类型的区别

基本数据类型,一共有 6 种:

string,symbol,number,boolean,undefined,null

引用数据类型,就只有 1 种:

object

 

的。

也就是说,数字是数字,字符是字符,布尔值是 true 或 falsenull 和 undefined 就是 null 和 undefined。这些值本身很简单,不能够再进行拆分。由于原始值的数据大小是固定的,所以原始值的数据是存储于内存中的栈区里面的。

  1. 访问方式

    • 原始值:访问到的是值
    • 引用值:访问到的是引用地址
  2. 比较方式

    • 原始值:比较的是值
    • 引用值:比较的是地址
  3. 动态属性

    • 原始值:无法添加动态属性
    • 引用值:可以添加动态属性
  4. 变量赋值

    • 原始值:赋值的是值
    • 引用值:赋值的是地址

NaN 是什么的缩写

NaN 的全称为 Not a Number,表示非数,或者说不是一个数。虽然 NaN 表示非数,但是它却属于 number 类型。

NaN 有两个特点:

  1. 任何涉及 NaN 的操作都会返回 NaN
  2. NaN 和任何值都不相等,包括它自己本身

 作用域与作用域链 

原始值与引用值===基本数据类型引用数据类型

如何判断数组或对象

对象深拷贝与浅拷贝,单独问了 Object.assign

说说 instanceof 原理

instanceof 用于检测对象 A 是不是 B 的实例,而检测是基于原型链进行查找的,也就是说 B 的 prototype 有没有在对象 A 的__proto__ 原型链上,如果有就返回 true,否则返回 false

ES6 新增哪些东西?

箭头函数
字符串模板
支持模块化(import、export)
类(class、constructor、extends)
let、const 关键字
新增一些数组、字符串等内置构造函数方法,例如 Array.from、Array.of 、Math.sign、Math.trunc 等
新增一些语法,例如扩展操作符、解构、函数默认参数等
新增一种基本数据类型 Symbol
新增元编程相关,例如 proxy、Reflect
Set 和 Map 数据结构
Promise
Generator 生成器
 

weakmap、weakset

 为什么 ES6 会新增 Promise

在 ES6 以前,解决异步的方法是回调函数。但是回调函数有一个最大的问题就是回调地狱(callback hell),当我们的回调函数嵌套的层数过多时,就会导致代码横向发展。

Promise 的出现就是为了解决回调地狱的问题。

ES5 实现继承

  1. 借用构造函数实现继承
    function Parent1(){
        this.name = "parent1"
    }
    function Child1(){
        Parent1.call(this);
        this.type = "child1";
    }
    

  2. 借用原型链实现继
    function Parent2(){
        this.name = "parent2";
        this.play = [1,2,3];
    }
    function Child2(){
        this.type = "child2";
    }
    Child2.prototype = new Parent2();
    

  3. 组合式继承
    function Parent3(){
        this.name = "parent3";
        this.play = [1,2,3];
    }
    function Child3(){
        Parent3.call(this);
        this.type = "child3";
    }
    Child3.prototype = Object.create(Parent3.prototype);
    Child3.prototype.constructor = Child3;
    

  防抖和节流?

我们在平时开发的时候,会有很多场景会频繁触发事件,比如说搜索框实时发请求,onmousemove、resize、onscroll 等,有些时候,我们并不能或者不想频繁触发事件,这时候就应该用到函数防抖和函数节流。

函数防抖(debounce),指的是短时间内多次触发同一事件,只执行最后一次,或者只执行最开始的一次,中间的不执行。

函数节流(throttle),指连续触发事件但是在 n 秒中只执行一次函数。即 2n 秒内执行 2 次… 。节流如字面意思,会稀释函数的执行频率。


 原型和原型链?

冒泡排序冒泡排序

冒泡排序的核心思想是:

  1. 比较相邻的两个元素,如果前一个比后一个大或者小(取决于排序的顺序是小到大还是大到小),则交换位置。
  2. 比较完第一轮的时候,最后一个元素是最大或最小的元素。
  3. 这时候最后一个元素已经是最大或最小的了,所以下一次冒泡的时候最后一个元素不需要参与比较。
function bSort(arr) {
    var len = arr.length;
    // 外层 for 循环控制冒泡的次数
    for (var i = 0; i < len - 1; i++) {
        for (var j = 0; j < len - 1 - i; j++) {
            // 内层 for 循环控制每一次冒泡需要比较的次数
            // 因为之后每一次冒泡的两两比较次数会越来越少,所以 -i
            if (arr[j] > arr[j + 1]) {
                var temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
        }
    }
    return arr;
}

//举个数组
myArr = [20, -1, 27, -7, 35];
//使用函数
console.log(bSort(myArr)); // [ -7, -1, 20, 27, 35 ]

数组降维

var newArray = arr.flat([depth])


proxy 是实现代理,可以改变 js 底层的实现方式, 然后说了一下和 Object.defineProperty 的区别

参考答案:

两者的区别总结如下:

代理原理:Object.defineProperty的原理是通过将数据属性转变为存取器属性的方式实现的属性读写代理。而Proxy则是因为这个内置的Proxy对象内部有一套监听机制,在传入handler对象作为参数构造代理对象后,一旦代理对象的某个操作触发,就会进入handler中对应注册的处理函数,此时我们就可以有选择的使用Reflect将操作转发被代理对象上。
代理局限性:Object.defineProperty始终还是局限于属性层面的读写代理,对于对象层面以及属性的其它操作代理它都无法实现。鉴于此,由于数组对象push、pop等方法的存在,它对于数组元素的读写代理实现的并不完全。而使用Proxy则可以很方便的监视数组操作。
自我代理:Object.defineProperty方式可以代理到自身(代理之后使用对象本身即可),也可以代理到别的对象身上(代理之后需要使用代理对象)。Proxy方式只能代理到Proxy实例对象上。这一点在其它说法中是Proxy对象不需要侵入对象就可以实现代理,实际上Object.defineProperty方式也可以不侵入。
 

 async 与 await 的作用

async 是一个修饰符,async 定义的函数会默认的返回一个 Promise 对象 resolve 的值,因此对 async 函数可以直接进行 then 操作,返回的值即为 then 方法的传入函数。

await 关键字只能放在 async 函数内部, await 关键字的作用就是获取 Promise 中返回的内容, 获取的是 Promise 函数中 resolve 或者 reject 的值
 

对变量进行类型判断的方式有哪些

typeof
typeof 是一个操作符,其右侧跟一个一元表达式,并返回这个表达式的数据类型。返回的结果用该类型的字符串(全小写字母)形式表示,包括以下 7 种:number、boolean、symbol、string、object、undefined、function 等。

instanceof
instanceof 是用来判断 A 是否为 B 的实例,表达式为:A instanceof B,如果 A 是 B 的实例,则返回 true,否则返回 false。 在这里需要特别注意的是:instanceof 检测的是原型。

constructor
当一个函数 F 被定义时,JS 引擎会为 F 添加 prototype 原型,然后再在 prototype 上添加一个 constructor 属性,并让其指向 F 的引用。

toString
toString( ) 是 Object 的原型方法,调用该方法,默认返回当前对象的 [[Class]] 。这是一个内部属性,其格式为 [object Xxx] ,其中 Xxx 就是对象的类型。

对于 Object 对象,直接调用 toString( ) 就能返回 [object Object] 。而对于其他对象,则需要通过 call / apply 来调用才能返回正确的类型信息。

 typeof 与 instanceof 的区别? instanceof 是如何实现?

typeof
typeof 是一个操作符,其右侧跟一个一元表达式,并返回这个表达式的数据类型。返回的结果用该类型的字符串(全小写字母)形式表示,包括以下 7 种:number、boolean、symbol、string、object、undefined、function 等。

instanceof
instanceof 是用来判断 A 是否为 B 的实例,表达式为:A instanceof B,如果 A 是 B 的实例,则返回 true,否则返回 false。 在这里需要特别注意的是:instanceof 检测的是原型。
 

  • 引用类型Object: Array ,Function, Date, RegExp

如何实现一个 new 

  • 创建一个空对象 。

  • 由 this 变量引用该对象 。

  • 该对象继承该函数的原型(更改原型链的指向) 。

  • 把属性和方法加入到 this 引用的对象中。

  • 新创建的对象由 this 引用 ,最后隐式地返回 this

  • let Parent = function (name, age) {
    this.name = name;
    this.age = age;
    };
    Parent.prototype.sayName = function () {
    console.log(this.name);
    };

    给定两个数组,求交集

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值