一、css
- position
(_1)_absolute 绝对定位 ,脱离了文档流,绝对定位的元素的位置相对于最近的已定位父元素,如果元素没有已定位的父元素,那么它的位置相对于html
(2)fixed 固定定位 ,与绝对定位相似,但元素的包含块为 viewport 视口。该定位方式常用于创建在滚动屏幕时仍固定在相同位置的元素。
(3)relative 相对定位 ,相对于其正常位置进行定位,不影响其他元素的偏移。
(4)sticky 粘性定位 ,可以被认为是相对定位和固定定位的混合。元素在跨越特定阈值前为相对定位,之后为固定定位。这是一个结合了 position:relativ_e 和 position:fixed 两种定位功能于一体的特殊定位。常见的吸顶、吸底(头部返回栏,底部切换栏_等)的效果都是使用这个属性。 注意:须指定 top 、 right 、 bottom 、 left 四个阈值其中之一,才可使粘性定位生效。否则其行为与相对定位相同。 并且 top 和 bottom 同时设置时,top 生效的优先级高,left 和 right 同时设置时,left 的优先级高。设定为 position:sticky 元素的任意父节点的 overflow 属性必须是 visible,否则 position:sticky 不会生效。如果 position:sticky 元素的任意父节点定位设置为 overflow:hidden,则父容器无法进行滚动,所以 position:sticky 元素也不会有滚动然后固定的情况。如果 position:sticky 元素的任意父节点定位设置为 position:relative | absolute | fixed,则元素相对父元素进行定位,而不会相对 viewport 定位。达到设定的阀值,也就是设定了 position:sticky 的元素表现为 relative 还是 fixed是根据元素是否达到设定了的阈值决定的。
(5)static 静态定位 ,HTML 元素默认情况下的定位方式为 static(静态),静态定位的元素不受 top、bottom、left 和 right 属性的影响,它始终根据页面的正常流进行定位。
(6)inherit 值如同其他 css 属性的 inherit 值,即继承父元素的 position 值。
2. overflow
3. 盒子模型
(1)标准盒模型(W3C盒子模型)
设置的宽高是对实际内容content的宽高进行设置,内容周围的border和padding另外设置;
即元素实际占位的宽高为:
width【height】= 设置的content的宽【高】 + padding + border + margin
css设置标准模型:Box-sizing:context-box (也是浏览器默认的盒模型)
(2)IE盒子模型(怪异盒模型)
设置的宽高是对实际内容content + 内边距(padding)+边框(border)之和的width和height进行设置的;
即元素实际占位的宽高为:
width(height)= 设置的width(height)+外边距margin
css设置Ie模型:box-sizing:border-box;
https://www.jianshu.com/p/e7238f7032a7
4、BFC
二、javascript
1、js数据类型
基本类型:string、number、boolean、null 、 undefined、symbol(es6,独一无二的值)
引用类型:object、array 、function
2 、基本数据类型与引用类型在存储上有什么区别?
基本数据类型:以栈的形式存储,保存与赋值指向数据本身,用typeof来判断类型,存储空间固定。
引用类型:以堆的形式存储,保存与赋值指向对象的一个指针,用instanceof 来判断类型,存储空间不固定。
注:1、Object.prototype.toString.call()对于所有基本数据类型都能进行判断,即使是null和undefined.
2、Array.isArray() // 用于判断是否为数组
https://baijiahao.baidu.com/s?id=1706449062196213790&wfr=spider&for=pc
3、如何阻止时间冒泡?
w3c的方法是e.stopPropagation() , IE则是e.cancelBubble=true
4、如何阻止默认事件?
w3c的方法是e.preventDefault(),IE则是e.returnValue=false
5、原型,原型链?
在Javascript中一共有两种类型的值,原始值和对象值,每个对象都有一个内部属性 prototype,我们通常称之为原型,原型的值可以是一个对象,也可以是null,如果它的值是一个对象,则这个对象也一定有自己的原型,这样就形成了一条线性的链,我们称之为原型链。
总结:(1)__proto__和constructor属性是对象所独有的;
(2)prototype属性是函数所独有的,因为函数也是一种对象,所以函数也拥有__proto__和constructor属性。
例子:(1)function Foo(){} var Boo = {name: “Boo”} Foo.prototype = Boo var f = new Foo() console.log(f.__proto__ === Foo.prototype) // true console.log(f.__proto__ === Boo) // true Object.getPrototypeOf(f) === f.__proto__ // true
(2)访问一个对象的原型可以使用ES5中的Object.getPrototypeOf方法,或者ES6中的__proto__属性、
原型链的作用是用来实现继承,比如我们新建一个数组,数组的方法就是从数组的原型上继承而来的
6、call和apply
call和apply都是为了解决改变this的指向。作用都是相同的,只是传值的方式不同。
function show(title) {console.log(`${title+this.name}`);}let lisi = {name: "李四"}let wangwu = {name: "王五"}show.call(lisi, "用户")show.apply(wangwu, ["用户2: "])// 用户1: 李四// 用户2: 王五
7、new关键字都做了什么?
new关键字与构造函数一起使用以创建对象:
function Employee(name,postion,yearHired){ this.name = name; this.postion = position; this.yearHired = yearHired;}const amp = new Employee(“Marko Polo”,”Software Developer”,2017);
new关键字做了4件事:
(1)创建空对象
(2)将空对象分配给this 值
(3)将空对象的__proto__指向构造函数的prototype
(4) 如果没有使用显示return语句,则返回this
看下面事例:
function Person(){this.name = “kyle”}
根据上面的描述,new Person做了:
(1)创建一个空对象:var obj = {}
(2)将空对象分配给this值:this = obj
(3)将空对象的__proto__指向构造函数的prototype: this.__proto__=Person().prototype
(4)返回this:return this
8、splice
splite(start,deleteCount,val1,val2,…)从start 位置开始删除deleteCount项,并从该位置起插入val1,val2,…arr1 = [1,2,3,4,5];result = arr1.splice(2,2,7,8,9); // a: [1,2,7,8,9,5] b:[3,4]result = arr1.splice(0,1); // 同shift
9、join(sepaprator):数组拼接成字符串
将数组的元素拼接成一个字符串,以sepaprator 为分隔符,省略的话则默认用逗号分隔符
arr1 = [1,2,3,4,5]result=arr1.join(“|”); // a: [1,2,3,4,5] b:”1|2|3|4|5”
10、slice(start,end)数组截取
slice(start,end):返回从原数组中指定开始下标到结束下标之间的项组成的新数组,但不包括结束位置的项
arr1=[1,2,3,4,5]result = arr1.slice(2,5); // [3,4,5]result = arr1.slice(2); // [3,4,5] 在只有一个参数的情况下,slice()方法返回从该参数指定位置开
始到当前数组末尾的所有项result=arr1.slice(0); // 返回自身
11、reverse: 将数组反序
arr=[1,2,3,4,5]result=arr1.reverse(); // [5,4,3,2,1]
12、concat: 数组合并
// 返回一个新数组,是将参数添加到原数组中构成arr1=[1,2,3,4,5]result=arr1.concat(6,7); // a: [1,2,3,4,5; b: [1,2,3,4,5,6,7]13、unshift shift 从数组开头开始添加或删除push pop 从数组末尾添加或者删除
14 、如何合并两个数组?数组删除一个元素?
// 三种方法
(1)var arr1=[1,2,3]; var arr2=[4,5,6]; arr1 = arr1.concat(arr2); // arr1: [1,2,3,4,5,6](2) var arr1=[1,2,3]; var arr2=[4,5,6]; Array.prototype.push.apply(arr1,arr2); // arr1: [1,2,3,4,5,6] arr2: 不变(3)var arr1=[1,2,3]; var arr2=[4,5,6]; for(var i=0;i<arr2.length;i++){ arr1.push(arr2[i]); }// arr1: [1,2,3,4,5,6]
15、普通函数和箭头函数的区别?
(1)写法不一样。箭头函数比普通函数更加的简洁,比如,括号里面只有一个参数,括号可以省略,另外如果函数体中只有一行代码,花括号也可以省略。
(2 ) 箭头函数没有arguments, 但可以用展开运算符“ …” 解决;
function A(a){console.log(arguments)}A(2,’sdas’,’asda’);
// Arguments(3)[2,’sdas’,’asda’,callee:f, Symbol(Symbol.iterator): f ]let C = (…c) => { console.log(c) }; C(3,82,32,111); // [3,82,32,111]
(3)this 作用域不同。箭头函数不绑定this,会捕获其所在的上下文的 this值,作为自己的this值。普通函数的this指向的是谁调用该函数就指向。
var obj = { a: 10, b: ()=>{ console.log(this.a); // undefined console.log(this); // Window (postMessage: f, blur: f, focus: f, close: f }, c: function() { console.log(this.a); // 10 console.log(this); // {a: 10, b: f, c: f} }}
(4)箭头函数没有原型属性,不能作为构造函数,不能使用new
(5)普通函数存在变量提升的现象
// 普通函数fn1();function fn1() { console.log(“hello world”);}// 箭头函数fn2(); // 报错let fn2 = () => {console.log(“hello world”);}
(6)箭头函数不能当做Generator函数,不能使用yield关键字
16、js事件轮循
1、js 是一门单线程语言,从上往下执行的,首先,主线程读取js代码,此时是同步的环境
2、当主线程检测到异步操作,就会交给其他异步线程处理,然后继续执行主线程的的任务
3、异步任务执行完毕之后,判断异步任务的类型,异步任务可分成宏任务和微任务,像setTimeout、setInterval属于宏任务,promise.then属于微任务,不同的任务进入不同的队列,等待主线程空闲时候调用。
4、当主线程的的同步任务执行完毕之后,开始执行微任务队列里面的所有微任务,执行完微任务,就执行宏任务队列里面所有的宏任务
5、执行完成之后,主线程开始询问任务队列里面是否还有等待的任务,如果有则进入主线程继续执行 以上步骤重复执行就是事件轮询
console.log('script start');
setTimeOut(function(){
console.log('setTimeOut');
},0);
new Promise(fuction(resolve){
console.log('promise1');
resolve();
}).then(function(){
console.log('promise2');
});
console.log('script end');
流程如下:
1、打印script start,
2、遇到setTimeout放到宏任务队列里
3、打印promise1
4、将.then回调放入微任务队列里
5、打印script end
6、执行栈已清空,执行微任务队列打印promise2
7、微任务队列已清空,执行宏任务队列setTimeOut
8、所有任务队列清空
(如果还有任务的话则继续轮询 微任务 => 宏任务 => 微任务 => 宏任务…)
17、宏任务和微任务
18、promise
三、vue.js
1、数据双向绑定原理
2、组件传值
(1)父到子:props;
(2)子到父:this.$emit();
(3)在父组件中this.$refs.子组建ref[name]
(4)可以使用Eventbus时间总线进行父子组件之间的传值:
// 首先创建一个单独的eventBus.js文件import Vue from ‘vue’export default new Vue()// 创建两个组件A、B,在两个组件中引入eventBus.js并赋值给bus在A组件中触发自定义的事件:bus.$emit(“share”,msg)在B组件中绑定事件以及传过来的参数msg: bus.$on(“share”, val=>{console.log(val); // val就是msg})
(5)深层组件传值:祖先组件provide 注入,后代组件inject接收。
祖先组件:export default{ provide() { return { uploadId: this } } }后代组件: export default { inject: [‘uploadId’] }
3、vue 生命周期
(1)beforeCreate (创建前)
(2)created(创建后)
(3)beforeMount(载入前)
(4)mounted(载入后)
(5)beforeUpdate(更新前)
(6)updated(更新后)
(7)beforeDestroy(销毁前)
(8)destroyed(销毁后)
4、父子组件生命周期执行顺序
(1)挂载阶段
父beforeCreate -> 父created -> 父beforeMount -> 子beforeCreate -> 子created -> 子beforeMount -> 子mounted -> 父mounted
(2)更新阶段
执行顺序:
父beforeUpdate -> 子beforeUpdate -> 子updated -> 父updated
(3)销毁阶段
执行顺序:
父beforeDestroy -> 子beforeDestroy -> 子destroyed -> 父destroyed
5、 vue怎么监听数组的变化的
6、vue2.0 和vue3.0有什么区别?
7、路由的原理
8、vuex 数据存储和响应原理
四、webpack
1 、webpack的优化:打包速度、打包体积、分包
2、webpack的打包原理
五、http协议、浏览器
1、http2.0
2 、页面输入地址到页面展示的过程
3、浏览器缓存
六、算法
1、diff算法
diff算法就是进行虚拟节点对比,并返回一个patch对象,用来存储两个节点不同的地方,最后用patch记录的消息去局部更新Dom。
diff算法的步骤:用 JavaScript 对象结构表示 DOM 树的结构;然后用这个树构建一个真正的 DOM 树,插到文档当中,当状态变更的时候,重新构造一棵新的对象树。然后用新的树和旧的树进行比较(diff),记录两棵树差异 把第二棵树所记录的差异应用到第一棵树所构建的真正的DOM树上(patch),视图就更新了。