JavaScript
(他们直接存储在内存中的,占用固定的内存空间。基本数据类型的赋值是通过将值直接复制给变量来完成的。)
(它们存储的是对象在内存中的地址,而不是对象本身。引用数据类型的变量实际上存储的是对象在内存中的引用,通过引用可以访问和操作对象的属性和方法。引用数据类型的赋值是将对象的引用赋给变量。)
ypeof (缺点:typeof null的值为
Object,无法分辨是
null还是
Object) Object.prototype.toString.call(缺点:不能细分为谁谁的实例)
是指不再用的内存没有被及时释放出来,导致该段内存无法被使用就是内存泄漏,内存泄漏指我们无法在通过js访问某个对象,而垃圾回收机制却认为该对象还在被引用,因此垃圾回收机制不会释放该对象,导致该块内存永远无法释放,积少成多,系统会越来越卡以至于崩溃
就是垃圾收集器按照固定的时间间隔,周期性地寻找那些不再使用的变量,然后将其清楚或释放内存。(标记清除/引用计数)
getElementById:通过元素的ID属性获取DOM元素。
getElementsByClassName:通过元素的class属性获取DOM元素
getElementsByTagName:通过元素的标签名获取DOM元素
querySelector:通过CSS选择器获取DOM元素
querySelectorAll:通过CSS选择器获取DOM元素
优点:方便,将字符串parse后创建新对象(新地址)
缺点:如果被拷贝的对象中某个属性的值为undefined,则拷贝之后该属性会丢失,如果被拷贝的对象中有正则表达式,则拷贝之后的对象正则表达式会变成Object
router是用来操作路由的
route是用来获取路由信息的。 $route.path $route.params route.query等
call、bind、apply 都是 JavaScript 中用于改变函数执行上下文(即 this 指向)的方法。
传参 call、bind可以传递无数个参数,apply只有两个参数,第二个参数为数组
返回 call和apply方法是直接调用函数并改变函数上下文,而bind方法则是返回一个新函数,稍后调用时绑定指定的上下文。
(localStorage/sessionStorage是window的属性,cookie是document的方法)
(slice切片的意思,根据传入的起始和终止下标,获取该范围数组。splice可根据传入参数个数不同实现删除、插入操作,直接操作原数组。第1个参数为起始下标,第2个为删除个数,第3个为要增加的数据)。
Vue
vue.js是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()
来劫持各个属性的setter
,getter
,在数据变动时发布消息给订阅者,触发相应的监听回调,
v-model
是一个指令,双向绑定实际上是Vue 的编译器完成的,通过输出包含v-model
模版的组件渲染函数,实际上还是value
属性的绑定及input
事件监听,事件回调函数中会做相应变量的更新操作。v-bind:value = "message" v-on:input = "message=event.target.value" 作用在组件上,本质是一个父子组件通信的语法糖,通过 prop 和 .emit 实现, 等同于:value = "message" @input = "$emit('input', $event.target.value)"
在组件切换过程中将状态保留在内存中,防止重复渲染DOM,减少加载时间及性能消耗,提高用户体验性。
生命周期(activated组件激活时调用/deactivated组件停用时调用)
在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM
key主要用在虚拟Dom算法中,每个虚拟节点VNode有一个唯一标识Key,通过对比新旧节点的key来判断节点是否改变,用key就可以大大提高渲染效率
diff算法是指对新旧虚拟节点进行对比,并返回一个patch对象,用来存储两个节点不同的地方,最后利用patch记录的消息局部更新DOM
缺点:首次渲染大量DOM时,由于多了一层虚拟DOM的计算,会比innerHTML插入慢,优点:减少了dom操作,减少了回流与重绘
render树中一部分或全部元素需要改变尺寸、布局、或着需要隐藏而需要重新构建,这个过程叫做回流,回流必将引起重绘
//编程式
this.$router.push({
name: 'home', //注意使用 params 时一定不能使用 path
params: { username: this.username },
})
//声明式
//编程式
this.$router.push({
path: '/home',
query: { username: this.username },
})
//声明式
都是循环遍历数组中的每一项 forEach和map方法里每次执行匿名函数都支持3个参数,map方法返回一个新的数组,数组中的元素为原始数组调用函数处理后的值
v-if控制Dom是否存在,v-show控制样式
当 Vue 处理指令时,v-for 比 v-if 具有更高的优先级,这意味着 v-if 将分别重复运行于每个 v-for 循环中,带来性能方面的浪费。
使用较轻量的组件,比如echart对应有vue-chart
vue-cli开启打包压缩 和后台配合 gzip访问;
路由懒加载,分包;
打包时配置删掉log日志
资源过大可以使用cdn模式引入,不再打包到本地
缺陷:数据如果为对象直接新增属性,如果为数组通过下标操作数组项,页面无法触发更新。
对策:关于对象可以通过Vue.$set(obj,key,value),组件中通过this.$set(obj,key,value)实现新增,修改属性vue可以相应更新视图。关于数组也可以通过Vue.$set(obj,key,value),或者作者重写的那些方法来操作;
Vue.use
本身是一个函数;vuex是一个状态管理工具,集中式的管理所有组件的状态数据。统一的去管理组件,将组件的状态抽象为一个store文件,通过commit方法触发mutation里的函数来改变组件属性。
五个属性state(存储) getters(获取) mutations(同步操作 /this.$store.commit(“方法名”,数据)/mapMutations) actions(异步操作 /this.$store.dispatch(“方法名”,数据)/mapActions) modules(放多个vuex)
防止组件重用的时候导致数据相互影响;因为data会挂在组件的原型上;所有实例共有
如果不是函数,则两个实例都引用同一个对象,当其中一个实例属性改变时,另一个实例属性也随之改变
SE6
Promise
异步编程的一种解决方案。Promise
是一个构造函数,接收一个函数作为参数,返回一个 Promise 实例。let p = new Promise(function(resolve, reject){
//做一些异步操作
setTimeout(function(){
console.log('执行完成Promise');
resolve('要返回的数据可以任何数据例如接口返回数据');
}, 2000);
});
async
关键字,表明该函数内部有异步操作。调用该函数时,会立即返回一个Promise
对象,await 是个运算符,用于组成表达式,await 表达式的运算结果取决于它等的东西,如果是promise则会等待promaise 返回结果,接普通函数直接进行链式调用微任务会优先于宏任务执行。这意味着在当前任务执行结束后,所有微任务都会被立即执行,而宏任务只有在所有微任务执行完毕后才会执行。
arguments
,也没有prototype
属性,所以不能用new
关键字调用箭头函数。var
声明的变量存在变量提升,即变量可以在声明之前调用,var
允许重复声明变量var
不存在块级作用域let
和const
不存在变量提升,即它们所声明的变量一定要在声明后使用,否则报错let
和const
存在块级作用域llet
和const
在同一作用域不允许重复声明变量模板字符串,箭头函数,拓展运输符,map和set,promise和proxy,数组方法Array.from(),map()、filter(),forEach(),some()、every()---------------记得啥说啥
网络原理
TCP协议在建立过程中会进行三次握手四次挥手,三次握手确保双方同步并避免无效连接,四次挥手则正常终止连接或异常终止连接。
HTTP协议是超文本传输协议(Hyper Text Transfer Protocol),是用于从万维网服务器传输超文本到本地浏览器的传送协议。HTTP是一个基于TCP/IP通信协议来传递数据的。
HTTP协议传输的数据都是未加密的,也就是明文的,因此使用HTTP协议传输隐私信息非常不安全,为了保证这些隐私数据能加密传输,于是网景公司设计了SSL(Secure Sockets Layer)协议用于对HTTP协议传输的数据进行加密,从而就诞生了HTTPS。
JSONP跨域,CORS,nginx代理跨域,nodejs中间件代理跨域,WebSocket协议跨域
WebSocket作用是即使通信双向通信,webwork是多进程的
性能优化
异步组件:对于较大的组件,可以使用异步组件进行延迟加载,提高页面加载速度。
HTML&&CSS
标准盒模型
,总宽度 = width + border(左右) + padding(左右)+ margin(左右);高度同理。
怪异盒模型(IE盒模型)
,总宽度 = width + margin(左右);高度同理。
水平居中 text-align: center;
垂直居中 margin 实现自适应居中 通过位移 transform 实现 设置 line-height 等于 height align-items: center;
对于宽度未知的块级元素 flex 布局 dispaly:flex;justify-content: center;align-item:center
绝对定位和 transform 实现, translateX 可以移动本身元素的50%
是一个简写方式,相当于同时设置了 `flex-grow: 1`、`flex-shrink: 1`、`flex-basis: 0` 这三个属性。满足项目的自适应需求。
算法题
数组arr[1,2,3] 输出结果[1, 2, 3] [1, 3, 2] [2, 1, 3] [2, 3, 1] [3, 1, 2] [3, 2, 1]
def permute(nums):
res = []
path = []
def backtrack(path, nums):
if not nums:
res.append(path[:])
return
for i in range(len(nums)):
path.append(nums[i])
backtrack(path, nums[:i]+nums[i+1:])
path.pop()
backtrack(path, nums)
return res
arr = [1, 2, 3]
res = permute(arr)
for r in res:
print(r)
// 冒泡排序
/* 1.比较相邻的两个元素,如果前一个比后一个大,则交换位置。
2.第一轮的时候最后一个元素应该是最大的一个。
3.按照步骤一的方法进行相邻两个元素的比较,这个时候由于最后一个元素已经是最大的了,所以最后一个元素不用比较。 */
function bubbleSort(arr) {
for (var i = 0; i < arr.length; i++) {
for (var j = 0; j < arr.length; j++) {
if (arr[j] > arr[j + 1]) {
var temp = arr[j]
arr[j] = arr[j + 1]
arr[j + 1] = temp
}
}
}
}
var Arr = [3, 5, 74, 64, 64, 3, 1, 8, 3, 49, 16, 161, 9, 4]
console.log(Arr, "before");
bubbleSort(Arr)
console.log(Arr, "after");
/*
快速排序是对冒泡排序的一种改进,第一趟排序时将数据分成两部分,一部分比另一部分的所有数据都要小。
然后递归调用,在两边都实行快速排序。
*/
function quickSort(arr) {
if (arr.length <= 1) {
return arr
}
var middle = Math.floor(arr.length / 2)
var middleData = arr.splice(middle, 1)[0]
var left = []
var right = []
for (var i = 0; i < arr.length; i++) {
if (arr[i] < middleData) {
left.push(arr[i])
} else {
right.push(arr[i])
}
}
return quickSort(left).concat([middleData], quickSort(right))
}
var Arr = [3, 5, 74, 64, 64, 3, 1, 8, 3, 49, 16, 161, 9, 4]
console.log(Arr, "before");
var newArr = quickSort(Arr)
console.log(newArr, "after");