You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
typeof a == "string" //true
typeof a == String //false
typeof null; //Object
typeof undefined; //undefined
判断已知对象类型的方法instanceof 后面加数据类型,且大小写不能写错
c instanceof Array //注意A要大写
根据对象的constructor判断
c.constructor === Array
//注意:constructor在类继承时会出错
eg: function A(){} function B(){}
A.prototype = new B(); //A继承于B
var aObj = new A();
aObj.constructor === B //true
aObj.constructor === A //false
//而instanceof方法不会出现该问题,对象直接继承和间接继承都会输出true
//要解决这个问题通常是让对象的constructor手动指向自己,但同时指向父类的时候就不会报true了
//首先定义一个父类functionAnimal(name){this.name=name||'Tom';this.showName=function(){returnthis.name;}}//原型方法Animal.prototype.eat=function(food){returnfood;}//(1)原型链继承:将父类的实例作为子类的原型。 不能实现多继承(继承多个父类),创建子类时,无法向父类构造函数传参functionCat(){}Cat.prototype=newAnimal();Cat.prototype.name='cat';varcat=newCat();console.log(catinstanceofAnimal);//trueconsole.log(catinstanceofCat);//true//(2)构造继承:复制父类的实例属性给子类,没用到原型,就是利用call或者apply把父类中通过this指定的属性和方法复制(借用)到子类创建的实例中。//可以实现多继承,call多个父类对象,创建子类实例时,可以向父类传递参数,实例不是父类的,只是子类的,只能继承父类的实例属性和方法,不能继承原型属性和方法functionDog(name){//继承了父类Animal.call(this);}vardog=newDog();console.log(dog.eat('fish'));//报错 dog.eat is not a functionconsole.log(doginstanceofAnimal);// falseconsole.log(doginstanceofDog);// true//(3)实例继承:为父类实例添加新的特性,作为子类实例返回。实例是父类的实例,不是子类的实例,不支持多继承functionPig(name){varsmall=newAnimal();small.name=name||'Tom';returnsmall;}varpig=newPig();console.log(piginstanceofAnimal);//trueconsole.log(piginstanceofPig);//false
HTML & CSS
一,css常用布局
可以用left等定位//默认值,在正常的流中,忽略left,right,top,bottom,z-index//继承父元素的position属性】,然后通过(left,top,right,bottom)来调整位置
二,BFC(用来块级格式化上下文)
是一个环境,html元素在这个环境中按照一定规则进行布局,一个环境中的元素不会影响到其它环境中的布局。
满足下列css声明之一的元素会生成BFC:
BFC的布局规则:
BFC的应用
的外边距不一样时,以最大的外边距为准
使用BFC来防止外边距折叠,当兄弟元素属于不同的BFC时,他们之间将不会有外边距折叠
2.使用BFC解决浮动问题:给父元素设置overflow:hidden可以清除子元素的浮动,触发了BFC,使内部的元素不会影响到外面的布局,BFC把浮动的子元素高度当做自己内部的高度去处理溢出,从外面看起来就是清除了浮动。
3.创建自适应两栏布局,并解决侵占浮动的问题
上面情况就已经创建自适应两栏布局,如果把slide1换成图片,slide2换成文字,这时候文字会围绕着图片,如果不想要这种效果,可以为文字添加样式overflow:hidden;
三,关于居中
四,css中的单位
的文本尺寸为 16px\*0.2\*2 4. rem:相对单位,不止对字体大小有用,r就代表root,是基于根元素进行设置,大多数情况根元素为 html ``` html{font-size:14px}
//28px ``` 可以通过修改根元素的大小来适配不同分辨率的设备 5. vh:基于窗口高度大小的单位,1vh = viewport高度的1/100,例如浏览器的高是900px,1vh=9px 6. vw:基于窗口宽度大小的单位,1vw = viewport宽度的1/100 7. vmin:取决于宽度和高度的最小值,例如:浏览器:1100(宽)\*750(高),1vmin = 7.5px 1vmax=11px 8. vmax:取决于宽度和高度的最大值,这两个单位可以让你非常灵活的利用可视窗口的大小 9. ex:小写字母x的高度 10. ch:数字0的宽度,ex,ch都依赖于font-size,同时还依赖于字体的font-family,这种单位大多数用于排版的微调,例如:上标,下标等五,CSS3动画和JS动画的优劣(推荐用css3动画来代替js动画)
js动画会占用主线程,而主线程中还有很多需要执行的js脚本,可能会导致线程阻塞,造成丢帧;
js动画代码的复杂度要高于css3动画
js动画效果比css3丰富,且对动画的开始,暂停,回放等执行能力强,没有兼容性的问题
CSS3存在兼容性的问题,且对动画的控制能力弱,不能绑定事件,对于复杂的动画,代码冗长,比较笨重
可以利用硬件来加速(通过GPU来提高动画性能)
浏览器可以对动画做优化(元素不可见时部动画,减少对FPS的影响)
对于帧速表现不好的低版本浏览器,css3可以做到自然降级,而js则需要编写额外的代码
css 3D动画在js中是无法实现的
css 2D矩阵动画(指transform,缩放,变形,x,y轴等)效率高于js利用margin,left,top模拟的矩阵动画
css3其他常规动画属性的效率(height,width,opacity等)低于js模拟的动画
六,纯css画基本图形
七,移动端1px问题(物理像素和设备像素是不等同的)
2.linear-gradient 线性渐变,上半部分为白色,下半部分为黑色,可以使用伪元素,避免去添加一个无意义的空元素(-webkit-min-device-pixel-ratio: 2)
3.box-shadow 将纵坐标的shadow设置为0.5px即可(-webkit-min-device-pixel-ratio: 2)
4.viewport 通过meta视口标签根据不同的dpr对不同的页面进行缩放,dpr=2,页面缩放到一半,dpr=3,页面缩放到三分之一
JS
一,JS的数据类型 详解
基本数据类型:null, undefined, boolean, number, string
复杂数据类型:object
新增数据类型:Symbol, BigInt
大多数数据类型都是Object类型的实例,创建Object实例的方式:(1)new操作符(2)使用对象字面量表示
三大引用类型(是一种数据结构,用于将数据和功能组织到一起,也被称为对象定义):Object , Array, Function
数组的每一项可以用来保存任何类型的数据,数组的大小是可以动态调整的
①基本数据类型的值不可改变; -------------- ① 引用类型的值是可变的
②基本数据类型不可添加属性和方法; -------------- ② 引用类型可以添加属性和方法
③基本数据类型的赋值是简单赋值; -------------- ③引用类型的赋值是对象引用,两个变量指向同一个对象,任何的操作都会互相影响
④基本数据类型的比较是值的比较; -------------- ④ 引用类型的比较是引用的比较,比较两个对象保存在栈区的指向堆内存的地址是否相同
⑤基本数据类型存放在栈区,栈区包括了变量的标识符和变量的值; -----------⑤引用类型是同时保存在栈区和堆区中的
二,js判断数据类型的方法
三,js封装,继承,多态
实例题
四,this指向问题
this的指向在函数定义的时候是确定不了的,只有在函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是调用它的对象
对于构造函数里的this,new关键字是可以改变this的指向。a是Fn创建的一个实例,此时,仅仅是创建,并没有执行,但调用函数Fn的
是对象a,所以this指向的就是a
特殊的,当this遇到return时,如果返回值是一个对象,那么this指向的就是返回的那个对象,如果返回值不是一个对象,那么this还是
还是指向函数的实例
我们可以通过call,apply,bind等方法自行改变this的指向
五,前端跨域问题
浏览器有同源策略,本域的js不能操作其他域的页面对象
1. 单向跨域:(一般用于获取数据)
(1)使用JSONP跨域
通过script标签引入的js是不受同源策略的限制的,因为script标签引入的文件内容是不能够被客户端的js获取到的,不会影响到被引用文件的安全但是通过ajax加载的文件内容是能够被客户端的js获取到的,所以
ajax必须遵守同源策略(注意:所谓的域跟js的存放服务器没有关系)我们可以通过script标签引入一个js,php,或者jsp等的文件,次文件返回一个js函数的调用
并且把参数传进去,这样在本域中就可以获取到其他域的数据
JSONP的缺点:只支持get请求;如果给其他域传参,可以在url地址后面挂参数
<script src="http://www.google.com/getUsers.php?flag=do&time=1"></script>
(2)window.name
是全局变量,是当前窗口的名字;每个iframe都有包裹它的window,而这个window是top window的子窗口。window.name的神奇之处在于name值在不同的页面(甚至不同域名)加载后依旧存在(如果没修改,则值不会变化)并且可以支持非常长的name值(2MB)
(3)服务器代理
(4)CORS(Cross-origin resource sharing)跨域资源共享
它允许浏览器向跨源浏览器发出XMLHttpRequest请求,从而克服Ajax只能同源使用的限制。CORS需要浏览器和服务器同时支持,IE10以及其他所有浏览器都支持该功能
同时满足以下两大条件:
2.双向跨域
(1)document.domain(两个iframe之间)
(2)location.hash(两个iframe之间)
(3)HTML5的postMessage(两个iframe之间或两个页面之间)
六,js内存泄漏和垃圾回收机制
标记清除:垃圾收集器在运行的时候会给存储在内存中的所有变量都加上标记,然后,它会去掉环境中的变量的标记和被环境中的变量引用的变量的标记,此后,如果变量再被标记则表示此变量准备被删除。 2008年为止,IE,Firefox,opera,chrome,Safari的javascript都用使用了该方式;
引用计数:跟踪记录每个值被引用的次数,当声明一个变量并将一个引用类型的值(function,Array,object)赋给该变量时,这个值的引用次数就是1,如果这个值再被赋值给另一个变量,则引用次数加1。相反,如果一个变量脱离了该值的引用,则该值引用次数减1,当次数为0时,就会等待垃圾收集器的回收。
这个方式存在一个较大的问题就是循环引用,就是A对象包含一个指向B对象的指针,B对象也包含一个指向A的引用,这就会造成大量的内存得不到回收(内存泄漏)
因为它们的引用次数永远不可能为0.早期的IE版本(ie4-ie6)采用引用计数,闭包导致泄漏的一个原因就是这个算法的缺陷
IE中有一部分对象并不是原生js对象,例如,DOM,BOM中的对象是以COM对象的形式实现的,而COM对象的垃圾回收机制采用的是引用计数。因此,虽然IE的js引擎采用的是标记清除策略,但是访问COM对象依然是基于引用计数的。在IE中设计COM对象就会存在循环引用的问题
七,js闭包
首先要理解作用域,当f1函数里面嵌套着函数f2,f2可以访问到全局变量以及f1内部的局部变量,但是,我们无法从外部来访问到f1的局部变量,
我们可以通过把内部的函数f2返回,这样就可以访问内部局部变量,这就是闭包。
为什么需要变量->因为局部变量无法共享和长久保存,而全局变量可能造成变量污染,用闭包来长久的保存变量又不会造成全局污染
特点:(1)占用更多内存;(2)不容易被释放;
如何使用闭包:
总之:内层函数对象被全局的变量引用,所以内层函数调用结束之后依然无法被内存回收,虽然占用了更多的内存空间,但这样可以持久的保存内部局部变量
八,DOM事件的绑定,DOM事件中target和currentTarget的区别
target:触发事件的某个具体的对象,只会出现在事件流的目标阶段
currentTarget: 绑定事件的对象,恒等于this,可能出现在事件流的任意阶段
通常情况下,target和currentTarget是一致的,但有一种情况必须区分,在父子嵌套的关系中,父元素绑定了事件,单击子元素,根据事件流,在不阻止事件流的前提下会传递至父元素,导致父元素的事件处理函数执行,
这时候,currentTarget指向的是父元素,因为它是绑定事件的对象,而target指向了子元素,因为他是触发事件的具体对象。
九,原生js ajax请求
(1)创建ajax对象(2)连接到服务器 (3)发送请求 (4)接收返回值
十,原型链,对象,构造函数之间的联系
十二,http状态码
200和304的区别
十三,设计模式
十四,Session,localStorage,cookie,SessionStorage
十五,浏览器缓存
十六,深拷贝实现原理
1.浅拷贝就是遍历对象属性
2.深拷贝可以分解成,浅拷贝+递归
用系统自带的JSON来做深拷贝
JSON.parse(JSON.stringify(source)
内部做了循环检测,但是内部用递归的方式,会有溢出问题;不能复制对象中的函数;原型链里的属性无法拷贝;十七,关于setTimeOut,Promise执行顺序
像settimeout、ajax等异步操作的回调,会进入”js事件单线程任务队列“中,而且只有主线程中没有执行任何同步代码的前提下,才会执行异步回调。
而settimeout(fn, 0)表示立即执行,也就是用来改变任务的执行顺序,要求浏览器”尽可能快“的进行回调。
Promise构造函数里的代码是同步执行的。then方法指向的回调将在当前脚本所有同步任务执行完后执行。
then比setTimeOut执行早的原因有两个:
macrotasks: setTimeout, setInterval, setImmediate, I/O, UI rendering
microtasks: process.nextTick, Promise, MutationObserver
一个事件循环中只有一个macrotask任务,可以有一个或多个microtask任务。
十八, js链式调用原理
jQ链式调用原理,jQuery节点在调用api后都会返回节点自身
十九
总结:从输入URL到页面展示,这中间发生了什么
进行DNS解析,获取服务器ip地址,端口(端口是通过dns解析获取的吗?这里有个疑问)
利用ip地址和服务器建立tcp连接
构建请求头信息
发送请求头信息
服务器响应后,网络进程接收响应头和响应信息,并解析响应内容
检查状态码,如果是301/302,则需要重定向,从Location自动中读取地址,重新进行第4步 (301/302跳转也会读取本地缓存吗?这里有个疑问),如果是200,则继续处理请求。
200响应处理:检查响应类型Content-Type,如果是字节流类型,则将该请求提交给下载管理器,该导航流程结束,不再进行后续的渲染,如果是html则通知浏览器进程准备渲染进程准备进行渲染。
准备渲染进程
浏览器进程检查当前url是否和之前打开的渲染进程根域名是否相同,如果相同,则复用原来的进程,如果不同,则开启新的渲染进程
渲染进程准备好后,浏览器向渲染进程发起“提交文档”的消息,渲染进程接收到消息和网络进程建立传输数据的“管道”
渲染进程接收完数据后,向浏览器发送“确认提交”
浏览器进程接收到确认消息后更新浏览器界面状态:安全、地址栏url、前进后退的历史状态、更新web页面
框架(Vue,React)
一,实现原理(virtual dom和diff算法)
VUE的Vdom是树状结构,其节点是Vnode,Vnode和浏览器中的Node是一一对应的,通过Vnode的elm属性可以访问到对应的Node
Vnode是纯粹的JS对象,操作它很高效,但是Vdom的变更最终会转换成DOM操作,为了实现高效的DOM操作,一套高效的虚拟DOM diff算法非常重要。
Vue的diff算法是仅在同级的Vnode之间做diff,递归的进行同级diff,最终实现整个DOM树的更新。
Diff算法:(1)简单的diff算法:逐个遍历newVdom的节点,找到它在oldVdom中的位置,如果找到了就移动对应的DOM元素,如果没找到就说明是新增的节点,则创建一个新的节点插入
,遍历之后如果oldVdom中还有没处理过的节点,则说明这些节点在newVdom中被删除了,删除他们即可。
(2)Vue中的Diff实现:对oldVdom和newVdom的起始和终点分别对应两个指针,Vue不断的对Vnode进行处理,处理过的节点vue会在oldVdom和newVdom中同时将它们标记为已处理
直到起点跟终点相遇。vue首先会将一些不需要做移动的DOM快速处理,缩小后续的操作范围。对于同类节点(例如两个div)Vue会直接复用DOM,不需要移动DOM.
整个diff分为两个部分:
[a]. 第一部分是循环,循环内部是一个分支逻辑,每次循环只会进入其中一个分支,每次循环会处理一个节点,处理过之后节点被标记,vue的做法是将节点标记为undefined
[b]. 循环结束后,可能newVdom或者oldVdom中还有未处理的节点,如果是newVdom中有未处理节点,则这些节点是新增节点,做新增处理。如果是oldVdom中有这类节点,则这些是需要删除的节点,相应在DOM树中删除之
整个过程是逐步找到Vdom的差异,然后将差异反应到DOM树上(patch),并且Vue的patch是即时的,并不是打包所有修改最后一起操作DOM,这点与React不同,React是将更新放入队列后集中处理。
现代浏览器对这样的DOM操作做了优化,并无差别。
二,MVC,MVVM
响应用户操作,网络请求以及与Model交互等。因此这就使得Controller编辑复杂,难以维护。thinkPHP就是基于MVC设计的。
MVC的缺点:
View的数据变化会同步到Model中,而Model数据的变化也会立即反应到View上,而他们之间的同步工作是自动的,不需要手动去操作DOM
三,setState是异步的
#####(1)同步更新,效率会很低;
#####(2)保持内部一致性(state,props,refs),props只有组件重新渲染之后才会更新;
四,受控组件和非受控组件(主要是针对表单操作)
构建工具
一,webpack
入口文件怎么配置,多个入口怎么分割
loader配置,原理
webpack的原理和机制
Babel插件(transform-runtime,stage-2)的作用
webpack.optimize.UglifyJsPlugin这个插件压缩速度很慢,有没有什么办法提升速度
loader: 将某些类型的模块编译转换成其他类型模块
plugin:plugin是一个扩展器,它丰富了webpack本身,针对是loader结束后,webpack打包的整个过程,它并不直接操作文件,而是基于事件机制工作,会监听webpack打包过程中的某些节点,执行广泛的任务
二,gulp
三,git
git flow
排序算法
ES6,ES7,ES8
一,babel把ES6转成ES5或者ES3的原理是什么
二,ES6箭头函数this问题
三,ES6拓展运算符
四,数组去重(最简洁)
五,let const原理(堆,栈)
V8内存分配和垃圾回收机制
CI / CD
CSS Modules
前端模块 Commonjs ES6 Module
CommonJS 模块输出的是一个值的拷贝,ES6 模块输出的是值的引用。
CommonJS 模块是运行时加载,ES6 模块是编译时输出接口。
CommonJs 是单个值导出,ES6 Module可以导出多个
CommonJs 是动态语法可以写在判断里,ES6 Module 静态语法只能写在顶层
CommonJs 的 this 是当前模块,ES6 Module的 this 是 undefined
微信小程序
一,微信小程序性能优化
小程序打开过程: (1)资源准备(代码包下载)-> (2)业务代码的注入以及落地页首次渲染 -> (3)落地页数据请求时的loading
提升体验最直接的方法就是控制包的大小:
(1)上传代码时要压缩 (在开发者工具上勾选)
(2)清理无用的代码和资源文件
(3)减少图片的数量和大小,除icon外都上传到服务器
采用分包机制,将用户访问率高的页面放在主包里,将访问率低的页面放入子包里,按需加载;因为代码包有一个下载的过程,所以子包不宜过大。也可以在可能访问子包的页面进行子包预加载,可根据用户的网络类型控制,网络好才预加载。
首屏加载优化:
(1)异步请求可以在页面onload就加载
(2)对变动频率低的异步数据可以利用storage缓存数据进行初步渲染,然后再进行异步数据的更新,优化性能 在无网环境也可以使用
(3)列表页->详情页 可以把一些关键字带过来,或者用骨架屏站位
####二,小程序渲染原理
双线程下的界面渲染,小程序的逻辑层和渲染层是分开的两个线程。在渲染层,宿主环境会把WXML转化成对应的JS对象,在逻辑层发生数据变更的时候,我们需要通过宿主环境提供的setData方法把数据从逻辑层传递到渲染层,再经过对比前后差异,把差异应用在原来的Dom树上,渲染出正确的UI界面。
1, 避免频繁调用setData,每次调用都是进程间的通信
2, 数据通信的性能与数据量正相关,因而如果有一些数据字段不在界面中展示且数据结构比较复杂或包含长字符串,则不应使用setData来设置这些数据;
3, 与界面渲染无关的数据最好不要设置在data中,可以考虑设置在page对象的其他字段下
冷启动:首次打开 或小程序已被微信主动销毁后再次打开
热启动:已打开过小程序,在一定时间内再次打开
小程序js代码无法操作DOM对象,也无法直接操作wxml上的容器或组件,js代码和webview没有运行在同一个进程
三,为什么小程序运行快
每次小程序进入,除了当前页面,Native会额外的预先加载一个WebView, 等打开页面时 用默认数据直接渲染,等请求数据回来时 再局部更新
四,OpenID, UnionID
(1) OpenID = 用户微信号 & 公众平台AppId (两个数据加密得到)
注意:对于同一个商城有公众号和小程序,他们的OpenID是不同的,那他们的微信号分别进入两个环境,要怎么识别是同一个用户呢?
(2) UnionID : 用户 再不同应用中的唯一标识
UnionID = 用户微信号 & 开放平台AppId (两个数据加密得到)
前提是各个公众平台需要先绑定同一个开放平台才能从各个平台中获取到同一个 UnionID
移动端适配方案
一,rem适配
读取devicePixelRatio(当前显示设备的物理像素分辨率与CSS像素分辨率之)动态设置viewport
viewport标签只对移动端浏览器有效,对PC端浏览器是无效的。
postcss-pxtorem将单位转化为 rem
设置rootValue: 37.5 UI设计图稿宽度是750px , 所以需要尺寸 / 2
vw 适配
移动端1px问题
原因: dpr = 物理像素 / css像素 对于dpr=2(iphone 8) 想要实现物理像素为1px 就需要css像素为 0.5 IOS 目前支持,但是安卓机不支持
解决:(1)使用边框图片;
(2)使用阴影 border-shadow
(3)使用伪元素
(4)用js获取 dpr动态设置viewport (dpr = 3, initial-scale=0.3333333333333333)
The text was updated successfully, but these errors were encountered: