发布时间:2024-04-18 08:01
git在项目中常用命令流程
1.配置author信息
git config --global user.name “你的名字”
git config --global user.email “你的邮箱”
2.git clone 远程仓库链接
3.git stash “信息"本地保存自己的创建的代码
4.git pull 拉取远程的仓库的代码和本地分支做合并
5.解决冲突
6.git add 仓库(目录)中的所有文件添加进git管理
7.git commit 提交到本地仓库
8.git push 提交到远程仓库
概念:SPA( single-page application )仅在 Web 页面初始化时加载相应的 HTML、JavaScript 和 CSS实现页面的渲染加载。一旦页面加载完成,SPA 不会因为用户的操作而进行页面的重新加载或跳转;取而代之的是利用路由机制实现 HTML 内容的变换,UI 与用户的交互、避免页面的重新加载。
优点:
缺点:
劣势解决:
前言:SPA单页面应用:在使用ajax与服务器数据交互过程中,实现局部数据的更新时,浏览器地址栏的url链接并没有发生改变,浏览器因为不会保存更新记录(浏览器会记录地址栏的url资源链接,如果url链接发生变化,浏览器会把该url链接保存到一个特殊的数据结构中,这样当用户点击返回与前进按钮时,会快速访问已经被记录的url链接资源。)。这时候再去返回就会出现非期待性的结果
- 解决方案:设置window.location.hash(location.hash)+ 监听window.onhashchange
//在ajax与服务器进行交互时,设置window.location.hash的值:
function updateView (attr){
$.ajax({
type:...,
url:...,
data:{attr : attr},
success:function(datas){
//设置hash值
window.location.hash = "#"+attr;
//do somthing
},
error:function(status){
//do somthing
}
});
}
//attr 这个值最好是该次请求所需的参数 设置onhashchange事件监听
window.onhashchange=function(){
var attr=window.location.hash.replace("#","");
updateView (attr);
}
//但是上述这样单纯的只要用户点击第一页的视图,ajax请求成功后,会主动改变hash值,这时候又触发onhashchange,又一次更新视图,两次访问服务器。
//解决办法
//设置一个全局变量,记录hash值的改变是怎样引起的:
var innerDocClick;
$('body').on('mouseleave',function(){
innerDocClick=false;//鼠标在页面外(点击了返回按钮)
});
$('body').on('mouseover',function(){
innerDocClick=true;//鼠标在页面内(没有点击返回按钮)
});
window.onhashchange=function(){
if(!innerDocClick)//若点击了返回按钮 加条件判断去更改hash值
{
var attr=window.location.hash.replace("#","");
updateView (attr);
}
}
第二种解决方法是在页面中嵌入一个隐藏 iframe,由于浏览器可以对 DOM 树中 iframe 节点的 src 属性进行历史记录跟踪,这样通过在逻辑上建立一条“页面 URL – 页面内 iframe URL – 页面状态”的对应链,同样可以在 IE 中建立片段标识符与页面状态的联系。
搜索引擎的规律:是靠搜索关键字来让自己的网站在搜索栏的第一页内,展示在用户的最前面,能让用户第一时间看到自己的网站。
补充
高质量网站有哪些特点
1.内容受众
2.时效性强
3.设计与布局整洁干净
4.无虚假违法信息
1.window对象
常用的方法:
1.alert()
2.定时器
2.location对象
常用的方法:
location.href = “http://www.666.com”; //页面跳转到该网址
location.assign(“http://www.666.com”); //页面跳转到该网址
location.hash用于设置页面的标签值
常用的方法:
navigator.cookicEnablcd:判断是否启用cookic
navigator.userAgent:判断浏览器的名称和版本号
navigator.plugins:保存浏览器中所有插件信息的集合
<script>
function hasPlugin(name) {
name = name ? name.toLocaleLowerCase() : '';
console.log('name = ' + name);
var plugins = navigator.plugins;
for (var i = 0; i < plugins.length; i++) {
//console.log(typeof plugins[i]);
console.log(plugins[i].name);
return plugins[i].name.toLocaleLowerCase().indexOf(name) !== -1 ? true : false;
}
}
var r = hasPlugin('pdf');
console.log(r);
常用方法:
1.前进:history.forward();history.go(1);
2.后退:history.back();history.go(-1);
3.获取记录个数:history.length:
let x = 1;
let y = 2;
[x, y] = [y, x];
- 2.从函数返回多个值
//返回一个数组,用结构赋值可以非常方便的取到对应值
function example() {
return [1, 2, 3];
}
let [a, b, c] = example();
//返回一个对象,获取对应的属性值
function example() {
return {
foo: 1,
bar: 2
};
}
let { foo, bar } = example();
- 3.取 JSON 数据
解构赋值对提取 JSON 对象中的数据
let jsonData = {
id: 42,
status: "OK",
data: [867, 5309]
};
let { id, status, data: number } = jsonData;
console.log(id, status, number);
// 42, "OK", [867, 5309]
// 上面代码可以快速提取 JSON 数据的值。
let arr = [a,b,c,d] = [1,2,3,4]
//解构嵌套数组,就是模式匹配,只要等号两边的层级结构相同,就可以拿到对应位置的值
const arr = [1, [2, 3, [4, 5, 6]]];
const [a, [b, c, [d, e, f]]] = arr;
let [a, b, c] = [1, 2, 3, 4]; // 1 2 3
let [a, b, c, d] = [1, 2, 3]; // 1 2 3 undefined
let [a, [b, c, [d, e]]] = [1, [2, 3, [4, 5, 6]]]; // 1 2 3 4 5
let [a = true] = [];
a // true
注意
数组的解构是根据它的位置(模式)对应的
解构操作允许有默认值,但一定是已经声明的。
如果等号的右边不是数组(或者严格地说,不是可遍历的结构)那么将会报错
展开运算:允许一个表达式在某处展开。展开运算符在多个参数(用于函数调用)或多个元素(用于数组字面量)或者多个变量(用于解构赋值)的地方可以使用。
在ES6之前将整个数组里面的元素依次作为实参传递给函数形参的时候使用Function.prototype.apply的特性
let arr = [1,2,3]
function test(a,b,c){}
test.apply(null,args) //通过apply特性将数值的形式转换为数组对应传递进去
ES6之后展开运算符
let arr = [1,2,3]
function test(a,b,c){}
test(..arr) //将数组展开进行传递参数
a.合并数组
let arr = [1,2,3]
let arr1 = [...arr,4,5,6] //1,2,3,4,5,6
b.展开运算符可以用于数组的一些方法中(push函数)
let arr = [1,2,3]
let arr1 = [4,5,6]
arr1.push(...arr) //4,5,6,1,2,3
c.类数组对象变成数组
let a=new Set([1,2,3,4,5,2,1]) // a : Set(5) {1, 2, 3, 4, 5}
let b=[...a] // (5) [1, 2, 3, 4, 5]
let [arg1,arg2,...arg3] = [1, 2, 3, 4]
arg1 //1
arg2 //2
arg3 //['3','4']
let {x,y,...z}={x:1,y:2,a:3,b:4};
x; //1
y; //2
z; //{a:3,b:4}
let z={a:3,b:4};
let n={x:1,y:2,...z};
n; //{x:1,y:2,a:3,b:4}
let a={x:1,y:2};
let b={z:3};
let ab={...a,...b};
ab //{x:1,y:2,z:3}
剩余参数:剩余参数语法允许我们将一个不定数量的参数表示为一个数组。
function test(a,b,...args){} //...args == [4,5,6]
test(1,2,3,4,5,6)
let [arg1,arg2,...arg3] = [1, 2, 3, 4]
arg1 //1
arg2 //2
arg3 //['3','4']
扩展运算符的作用及使用场景
- 对象的扩展运算符
- (…)用于取出参数对象中的所有可遍历属性,拷 贝到当前对象之中。
- 等价于Object.assign 方法用于对象的合并,将源对象(source)的所有可 枚举属性,复制到目标对象(target)。Object.assign 方法的第一
个参数是目标对象,后面的参数都是源对象。(如果目标对象与源对 象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面 的属性)- 数组扩展运算符
- 可以将一个数组转为用逗号分隔的参数序列,且每 次只能展开一层数组
- 将数组转换为参数序列
- 复制数组,连接数组(contact)
- 将字符串转为真正的数组(任何 Iterator 接口的对象,都可以用扩展运算符转为真正的数组)
- 函数中使用扩展运算符,可以使用在形参上代替argument
1.定义:arguments是一个对应传递给函数参数的类数组对象,arguments对象是所有非箭头函数都有的一个局部变量。你可以使用arguments对象在函数中引用函数的参数。此对象包含传递给函数的每个参数,第一个参数在索引0处。
2.特性:
const args = Array.from(arguments);
const args = [...arguments];
属性callee相当于调用自身函数,可以用作匿名函数的递归:
var sum = function (n) {
if (1 == n){
return 1;
} else {
return n + arguments.callee(n - 1); //6 5 4 3 2 1 } } alert(sum(6)); 输出结果:21
}
3.作用:
a.无需明确命名参数,就可以重写函数,在函数代码中,使用特殊对象 arguments,开发者无需明确指出参数名,就能访问它们
function sayHi(message) {
alert(arguments[0]); // 此处将打印message参数的值
}
b.检测参数个数( arguments.length )
function howManyArgs() {
alert(arguments.length);
}
howManyArgs("string", 45);
howManyArgs();
howManyArgs(12); // 上面这段代码将依次显示 "2"、"0" 和 "1"。
c.针对同一个方法被多处调用,但是参数数量不确定的情况下,可以更具arguments索引进行判断。
function func1() {
console.log(arguments[0]); // 1
console.log(arguments[1]); // 2
console.log(arguments[2]); // 3
}
func1(1, 2, 3)
d.模拟函数重载
用 arguments 对象判断传递给函数的参数个数,即可模拟函数重载
当只有一个参数时,doAdd() 函数给参数加 5。如果有两个参数,则会把两个参数相加,返回它们的和。所以,doAdd(10) 输出的是 “15”,而 doAdd(40, 20) 输出的是 “60”。
function doAdd() {
if(arguments.length == 1) {
alert(arguments[0] + 5);
} else if(arguments.length == 2) {
alert(arguments[0] + arguments[1]);
}
}
doAdd(10); //输出 "15"
doAdd(40, 20); //输出 "60"
补充
异步编程出现原因
js是单线程,同一时刻只允许一个代码块执行,耗时任务时,UI渲染阻塞
详情请看链接
2.拷贝数据的方式:
(1)直接赋值给一个变量(2)Object.assign() 浅拷贝ES6新出接口相当于扩展运算符
(3)Array.prototype.slice() 浅拷贝
(4)Array.prototype.concat() 浅拷贝
(5)扩展运算符…arr 浅拷贝
(6)JSON.parse(JSON.stringify()) 深拷贝
(7)Loadsh库中的API,如:.clone()、.cloneDeep()浅拷贝深拷贝
浅拷贝(对象,数组)
特点:拷贝的时候只是拷贝了一份引用,修改拷贝以后的数据会影响原来的数据。
浅拷贝只是拷贝一层,更深层次对象级别的值拷贝引用
如何浅拷贝:1.直接赋值 2.遍历赋值 3.ES6的语法糖,object.assign(给谁,拷贝谁)只要一层就没有问题
let a = {
age: 1,
color:[1,2,3],
like:{
sing:4,
dance:5
}
}
let b = {}
Object.assign(b, a);
b.like.sing = 2;
console.log(a.like.sing) // 原本是4现在变成了2这就是浅拷贝拷贝了复杂类型的地址
深拷贝(深度克隆)
特点:拷贝的时候会生成一份新的数据,修改拷贝以后的数据不会原数据。
拷贝多层,每一层的数据都会拷贝
let a = {
age: 1,
color:[1,2,3],
like:{
sing:4,
dance:5
}
}
let b = {}
var deepCopy = function(newObj,oldObj){
for(let k in oldObj){
// k是属性名,oldObj[k]是属性值
// 进行递归判断
let item = oldObj[k]
if(item instanceof Array){
// 设置新的对象的属性名并且声明类型
newObj[k] = []
// 再次调用
deepCopy(newObj[k],item)
}else if(item instanceof Object){
newObj[k] = {}
// 再次调用
deepCopy(newObj[k],item)
}else {
newObj[k] = item
}
}
}
deepCopy(b,a)
、、、简化代码
function deepClone(obj) {
var myObj = obj instanceof Array ? [] : {}
for (let key in obj) {
myObj[key] = typeof (obj[key]) =='object'?deepClone(obj[key]): obj[key]
}
return myObj
}
补充:深拷贝其他的实现方法
JSON.parse(JSON.stringify(obj))也可以实现深拷贝,但是弊端较多,例如无法识别undefined,symbol
lodash库里面的API_.cloneDeep(value).clone()
1、props和emit
2、Ref和
p
a
r
e
n
t
/
parent/
parent/children
3、eventBus\\emit\\on 兄弟、父子组件通信
4、$attrs\\listeners 隔代通信
5、Provide\\inject 隔代组件通信
6、Vuex
7、Pubsub库
父子组件props/ e m i t / emit/ emit/parent/ref/ a t t r s 兄弟组件 attrs 兄弟组件 attrs兄弟组件parent/$root/eventbus/vuex
跨层级关系eventbus/vuex/provide+inject
数据类型区分:
1.Symbol 代表创建后独一无二且不可变的数据类型,它主要是为了 解决可能出现的全局变量冲突的问题
2. BigInt 是一种数字类型的数据,它可以表示任意精度格式的整数, 使用 BigInt 可以安全地存储和操作大整数,即使这个数已经超出了 Number 能够表示的安全整数范围。
3.为什么会有 BigInt 的提案:JavaScript 中 Number.MAX_SAFE_INTEGER 表示最⼤安全数字,计算 结果是 9007199254740991,即在这个数范围内不会出现精度丢失(⼩ 数除外)。但是⼀旦超过这个范围,js 就会出现计算不准确的情况, 这在⼤数计算的时候不得不依靠⼀些第三⽅库进⾏解决,因此官⽅提 出了 BigInt 来解决此问题。
存储位置区分
数据结构中
- 栈中数据的存取方式为先进后出。
- 堆是一个优先队列,是按优先级来进行排序的,优先级可以按照大小来规定。
操作系统中,内存被分为
- 栈区内存由编译器自动分配释放,存放函数的参数值,局部变量的 值等。其操作方式类似于数据结构中的栈
堆区内存一般由开发者分配释放,若开发者不释放,程序结束时可 能由垃圾回收机制回收
一、区别?
数组表示有序数据的集合,而对象表示无序数据的集合。如果数据的顺序很重要,就用数组,否则就用对象
数组是种有顺序的链表,对象是无顺序的键值对。
数组有length属性,对象没有
二、判断一个对象为空对象
使用 JSON 自带的.stringify 方法来判断
let obj = {}
console.log(JSON.stringify(obj) == "{}"); //true
let obj = {}
console.log(Object.keys(obj).length <= 0); //true
三、
var arr = [1,2,3,1];
var obj = {
a:“A”,
c:“C”
}
console.log(arr.constructor === Array)//true
console.log(obj.constructor === Object) //true
拓展:
1.为什么不用Object.toString?
答:虽然所有对象的原型链最顶端都是Object.prototype,但同时Object本身也是一个构造函数,继承于Function,而Array、function 等类 型作为 Object 的实例,都重写了 toString 方法。因此根据原型链上的知识,采用 obj.toString() 不能得到其对象类型,只能将 obj 转换为字符串类型;因此,在想要 得到对象的具体类型时,应该调用 Object 原型上的 toString 方法。2.num.toString()//“123”
- 把数字转换为字符串
- num.toString(2)//转换为二进制的字符串
判断构造函数的原型是否出现在对象的原型链上的任何位置
// 判断构造函数的原型是否出现在对象的原型链上的任何位置
// left对象 right构造函数
function myInstanceof (left,right){
// 1.获取对象的原型
let proto = Object.getPrototypeOf(left)
// 2.获取构造函数的prototype对象
let prototype = right.prototype
while(true){
// 对象的原型不存在则返回或者递归判断的结束条件
if(!proto) return false
// 当构造函数的原型和对象的原型相等
if(proto = prototype) return true
// 如果没有找到,就继续从原型上去找,通过Object.getPrototype方法用来获取指定对象的原型
proto = Object.getPrototypeOf(proto)
}
}
1.let a = x % n (n为几进制)
2. res += a
3. x / n
200 成功状态码
202服务器已经接收到请求数据,但尚未进行处理
204 NoContent 该状态码代表服务器接收的请求已成功处理,但在返回的响应报文中不含实体的主体部分在这里插入代码片
206 Partial Content 发送范围请求头Range抓取到资源的部分内容(大文件下载、分割多个部分同时下载等)
3XX响应结果表明浏览器需要执行某些特殊的处理以正确处理请求。
301 永久重定向(永久移动)该状态码表示请求的资源已被分配了新的URI已被分配了新的URI,以后应使用资源现在所指的URI
302 暂时重定向(临时移动)该状态码表示请求的资源已被分配了新的URI,希望用户(本次)能使用新的URI访问,但是这个的改变不是永久的。
303 该状态码表示由于请求对应的资源存在着另一个URI,应使用GET方法定向获取请求的资源。303状态码和302状态码有着相同的功能,但303状态码明确表示客户端应采用GET方法获取资源,这点与302状态码有区别
304协商缓存(请求的资源未修改)该状态码表示客户端发送附带条件的请求时,服务器允许请求访问资源,但未满足条件的情况。
304状态码返回时,不包含任何响应的主体部分
307临时重定向
400服务端无法理解(客户端语法错误)
401用户需要验证 该状态码表示发送请求需要有通过HTTP认证(BASIC认证、DIGEST认证)的认证信息
403请求已成功,但被拒绝未获得文件系统的访问授权,访问权限出现某些问题(从未授权的发送源IP地址试图访问)等列举的情况都有可能是发生403的原因
404找不到资源,请求资源不存在
500服务器内部错误 有可能是Web应用存在的bug或某些临时的故障
505服务器不支持请求的HTTP协议版本
系统开发:修改端口server.port = 80 打包
服务器准备、环境配置:云服务,阿里云—云服务器ECS—实例—创建实例—购买服务器(cpu ,内存,硬盘,操作系统镜像)—网络配置(分配公网IPV4地址,带宽,安全组中Linux端口22,window端口3389)—会有公网和私网IP,用户名和密码
在操纵系统中安装目标程序所需要的环境:用FTP工具将本地上传到服务器,建立连接—主机:公网IP,协议:SFTP/SSH 端口: 用户名: 密码:
程序部署及运行:打包–上传(FTP工具)—启动
域名绑定:字母与IP绑定,访问域名相当于访问IP地址,购买域名—域名备案(ICP)—域名解析(解析,添加记录:记录值是IP地址,域名)
state, getters, mutations, actions, modules。
1.state:vuex的基本数据,用来存储变量
在vue中使用 this.$store.state.userId
2.geeter:从基本数据(state)派生的数据,相当于state的计算属性,具有返回值的方法
在vue中使用 this.$store.getters.userIdDouble
3.mutation:提交更新数据的方法,必须是同步的(如果需要异步使用action)。每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。
commit 同步操作,写法: this.$store.commit(‘mutations方法名’,值)
4.action:和mutation的功能大致相同,不同之处在于 ==》1. Action 提交的是 mutation,而不是直接变更状态。 2. Action 可以包含任意异步操作。
dispatch:异步操作,写法: this.$store.dispatch(‘mutations方法名’,值)
5.modules:模块化vuex,可以让每一个模块拥有自己的state、mutation、action、getters,使得结构非常清晰,方便管理。
简单来说就是可以把以上的 state、mutation、action、getters 整合成一个user.js,然后放到store.js里面
生命周期:每一个vue实例从创建到销毁的过程就是vue这个实例的生命周期
生命周期过程:开始创建、初始化数据、编译模板、挂载Dom、渲染→更新→渲染、卸载等一系列过程
使用场景:可以在此时加一些 loading 效果,在 created 时进行移除。
使用场景:需要异步请求数据的方法可以在此时执行,完成数据的初始化。
使用场景: 当需要操作 dom 的时候执行,可以配合$.nextTick 使用进行单一事件对数据的更新后更新dom。
使用场景: 当数据更新需要做统一业务处理的时候使用。
- Vue 实现响应式并不是数据发生变化之后 DOM 立即变化,而是按一定的策略进行 DOM 的更新。(Vue 在更新 DOM 时是异步执行的)
- vue响应式的改变一个值以后,此时的dom并不会立即更新,如果需要在数据改变以后立即通过dom做一些操作,可以使用$nextTick获得更新后的dom。(根据异步请求获取后的数据从而渲染DOM结构,可以结合wacth监听属性配合)
- $nextTick 是在下次 DOM 更新循环结束之后执行延迟回调,在修改数据之后使用 $nextTick,则可以在回调中获取更新后的 DOM。
补充
VUE数据请求放在created还是mounted?
如果在mounted钩子函数中请求数据可能导致页面闪屏问题
其实就是加载时机问题,放在created里会比mounted触发早一点,如果在页面挂载完之前请求完成的话就不会看到闪屏了
meta标签用来描述一个HTML网页文档的属性
有四种属性:1.charset、2.name、3.content、4.http-equiv
name的参数有:
keywords(关键字)为搜索引擎提供网站的关键字
description(网站内容描述)为搜索引擎提供网站主要内容。
application-name(应用程序名称)
viewport(用于移动端页面控制)指定页面控制及缩放比例。content内容如下:
width:设置layout viewport 的宽度,为一个正整数,或字符串"width-device"
initial-scale:设置页面的初始缩放值,为一个数字,可以带小数,通常为1.0(1.0为正常大小)
minimum-scale:允许用户的最小缩放值,为一个数字,可以带小数
maximum-scale:允许用户的最大缩放值,为一个数字,可以带小数
http-equiv的参数有:refresh重定向,在规定的时间之后跳转到另一页面
<meta http-equiv="refresh" content="5;url=http://www.w3school.com.cn" />
DOCTYPE是document type (文档类型) 的缩写。声明位于文档的最前面,处于标签之前,它不是html标签。主要作用是告诉浏览器的解析器使用哪种HTML规范或者XHTML规范来解析页面。
把数据存到用户的浏览器里面
设置方便,易于读取,甚至刷新页面也不会丢失数据
只能储存字符串,可以将对象JSON.stringify()编码后存储
登录页面、用户点击登录过程,从前端拿数据和后台拿数据以及从数据库拿数据
用户点击页面登录—前端页面vue组件获取表单的值—判断是登录还是注册,处理请求—后端—返回成功或失败数据
注意:
vuex仓库存储数据—不是持久化
配置路由守卫:router.beforeEach((to,from,next)=》{}) //进行条件判断然后跳转路由
1.定位 子绝父相
.child {
top: 0px;
left: 0px;
bottom: 0px;
right: 0px;
margin: auto; }
.child {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
2.flex布局
将父盒子设置成弹性盒容器
让子元素水平居中,垂直居中
.parent {
display: flex;
justify-content: center;
align-items: center;
}
.parent {
text-align: center;
line-height: 500px;
}
.child {
display: inline-block;
vertical-align: middle; vertical-align 属性设置一个元素的垂直对齐方式。middle把此元素放置在父元素的中部。
}
CSS盒子右边固定,左边自适应
1.固定盒子浮动+ 自适应盒子width: 100%;//宽度等于百分之百
.left {
float: left;
width: 200px;
height: 400px;
background: red;
}
.right {
width: 100%;//宽度等于百分之百
height: 400px;
margin-left: 200px;
background: blue;
}
2.flex布局父容器设置 display:flex;Right部分设置 flex:1
.box{ display: flex;}
.left{width:200px;background: red;}
.right{width:%;flex:1;background: blue;}/等于左边栏宽度/
3.左右两边都绝对定位
.left{width:200px;background: red; position: absolute;left:;}
.right{width:100%;background: blue;position: absolute;left:200px;}/等于左边栏宽度/
Flex布局后,子元素的float、clear和vertical-align属性将失效
(父)容器的一些属性:
(子)项目上的属性:
MVVM分为Model、View、ViewModel三者。
补充
MVC:原生JS方法
节流:一定的间隔时间内只执行一次,如果这个单位时间内触发多次函数,只有一次生效。 滚动事件,鼠标点击事件
防抖:事件被触发n秒后再执行回调,n秒内又被触发则重新计时
懒加载也叫延迟加载
首先将页面上的图片的 src 属性设为空字符串,而图片的真实路径则设置在 data-original 属性中,当页面滚动的时候需要去监听 scroll 事件,在 scroll 事件的回调中,判断我们的懒加载的图片是否进入可视区域,如果图片在可视区内则将图片的 src 属性设置为 data-original 的值,这样就可以实现延迟加载。
将路由相关的组件,不再直接导入了,而是改写成异步组件的写法,只有当函数被调用的时候,才去加载对应的组件内容。
routes: [
{ path: '/login', component: () => import('@/views/login/index.vue') },
{ path: '/home', component: () => import('@/views/home/home.vue') }
]
预编译
作用域
变量提升
事件委派
js最大特点是单线程的,单线程意味着所有任务需要排队
同步异步任务执行机制
(1)所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。
(2)主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。
(3)一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。
(4)主线程不断重复上面的第三步。 事件循环:主线程从”任务队列”中读取事件,这个过程是循环不断的,所以整个的这种运行机制又称为Event Loop(事件循环)
1.js宏任务有:
回答:不是
补充面试题:
1.箭头函数与普通函数区别
- 箭头函数没有this,所以需要通过查找作用域链来确定this的值
- 箭头函数没有自己的arguments对象,但是可以访问外围函数的arguments对象
- 不能通过 new 关键字调用,同样也没有 new.target值和原型
2.let,const解决什么问题
解决:变量污染问题 引入块级声明:声明在指定块的作用域之外无法访问的变量
Var:定义一个变量,可以重复赋值,重复定义;有变量提升,变量可以在声明之前使用,值为undefined;在浏览器环境下声明变量会挂载到window上。
Let:定义一个变量,可以重复赋值,不可以重复定义;块级作用域,也称词法作用域,没有变量提升,存在暂时性死区;全局作用域下创建一个新的绑定,该绑定不会添加为全局对象的属性。
Const:定义一个常量,声明时必须赋值,也就是必须初始化,不可以重复赋值,不可以重复定义,常量如果是对象,对象中的值可以修改;块级作用域,也称词法作用域,没有变量提升,存在暂时性死区3.暂时性死区( temporal dead zone,简称TDZ
- ES6新增的let、const关键字声明的变量会产生块级作用域,如果变量在当前作用域中被创建之前被创建出来,由于此时还未完成语法绑定,如果我们访问或使用该变量,就会产生暂时性死区的问题,由此我们可以得知,从变量的创建到语法绑定之间这一段空间,我们就可以理解为‘暂时性死区’
其他方面也会出现暂时性死区域吗?- let/const关键字未出现之前,typeof运算符是百分之百安全的,现在也会引发暂时性死区的发生,像import关键字引入公共模块、使用new
class创建类的方式,也会引发暂时性死区,究其原因还是变量的声明先与使用
CORS:
JSONP:
可跨域标签
<img src=""> //图片
<link href=""> //css
<script src=""> //程序
配置代理服务器:
定义:最小且灵活的web应用程序框架,为web和移动应用程序提供了一组强大的功能,它的行为就像是一个中间件,可以帮助管理服务器和路由。
优点:简单、灵活、简约和可扩展;提供快速生成工具express-generator,快速开发web应用。
其他框架
Koa:是一个新的web框架,由Express幕后的原班人马打造,致力于成为web应用和API开发领域中的一个更小、更富有表现力、更健壮的基石。用async函数代替回调函数。优点:集成大量webAPI,没有绑定中间件;非常轻量;try/catch更好处理错误;代码可读性和维护性相对较高。
Hapi:基础功能相对丰富的框架,开发人员专注于业务而不是项目构建。优点:提供了缓存、身份验证和输入验证;提供众多企业插件。
原文链接:详情
来源:解决内存的泄露,垃圾回收机制会定期(周期性)找出那些不再用到的内存(变量),然后释放其内存。
现在各大浏览器通常采用的垃圾回收机制有两种方法:1.标记清除,2.引用计数。
js中最常用的垃圾回收方式就是标记清除。垃圾回收机制在运行的时候会给存储再内存中的所有变量都加上标记(可以是任何标记方式),然后,它会去掉处在环境中的变量及被环境中的变量引用的变量标记(闭包)。而在此之后剩下的带有标记的变量被视为准备删除的变量,原因是环境中的变量已经无法访问到这些变量了。最后垃圾回收机制到下一个周期运行时,将释放这些变量的内存,回收它们所占用的空间。
工作原理:
当变量进入环境时,将这个变量标记为“进入环境”。当变量离开环境时,则将其标记为“离开环境”。标记“离开环境”的就回收内存。
工作流程:
垃圾回收器,在运行的时候会给存储在内存中的所有变量都加上标记; 去掉环境中的变量以及被环境中的变量引用的变量的标记;
被加上标记的会被视为准备删除的变量; 垃圾回收器完成内存清理工作,销毁那些带标记的值并回收他们所占用的内存空间。
到目前为止,IE、Firefox、Opera、Chrome、Safari的js实现使用的都是标记清除的垃圾回收策略或类似的策略,只不过垃圾收集的时间间隔互不相同。
语言引擎有一张"引用表",保存了内存里面所有资源(通常是各种值)的引用次数。如果一个值的引用次数是0,就表示这个值不再用到了,因此可以将这块内存释放。
工作原理:跟踪记录每个值被引用的次数。
工作流程:
声明了一个变量并将一个引用类型的值赋值给这个变量,这个引用类型值的引用次数就是1
同一个值又被赋值给另一个变量,这个引用类型值的引用次数加1;
当包含这个引用类型值的变量又被赋值成别的值了,那么这个引用类型值的引用次数减1; 当引用次数变成0时,说明没办法访问这个值了。
当垃圾收集器下一次运行时,它就会释放引用次数是0的值所占的内存;
扩展:
但是,为了减少内存垃圾,我们还是可以对javascript代码进行彻底检查,有些代码中存在明显的产生过多内存垃圾的问题代码,这些正是我们需要检查并且完善的。
type:
vue 双向数据绑定是通过 数据劫持 结合 发布订阅模式的方式来实现的, 也就是说数据和视图同步,数据发生变化,视图跟着变化,视图变化,数据也随之发生改变;
vue单向数据流:在vue中需要遵循单向数据流原则
在父传子的前提下,父组件的数据发生会通知子组件自动更新
子组件内部,不能直接修改父组件传递过来的props => props是只读的
从数据类型上:
从使用场景上:
注意:NaN是一种特殊类型的的number,它与任何数据都不相等,包括自己本身,其他数据类型和NaN运算的结果都是NaN
因为 undefined 是一个标识符,不是保留字,所以可以被当作变量来使用和赋值, 但是这样会影响 undefined 的正常判断。表达式 void ___ 没有返 回值,因此返回结果是 undefined。void 并不改变表达式的结果, 只是让表达式不返回值。因此可以用 void 0 来获得 undefined。
void后跟一个表达式 void(expression),他会执行这个表达式,然后返回undefined
可以使用void 0来代替undefined,因为undefind不是保留字。所以在某些浏览器下,undefind的值可能会被修改。
在 JavaScript 中,基本类型是没有属性和方法的,但是为了便于操 作基本类型的值,在调用基本类型的属性或方法时 JavaScript 会在 后台隐式地将基本类型的值转换为对象,例如字符串
const a = 'abc'
console.log(a.length); //3
如果是new一个箭头函数可以吗?
回答:不可以,箭头函数它没有prototype,也没有自己的this 指向,更不可以使用 arguments 参数,所以不能 New 一个箭头函数。
this 是执行上下文中的一个属性,它指向最后一次调用这个方法的 对象。
call(默认传入数据没有格式)
applay(传入数据是一个数组)
bind(传入参数可以是数组或者直接传入都可)但是bind可以减少call和apply多次绑定同一个对象造成的代码冗余。因为bind会返回一个回调函数,在使用多顶绑定时直接调用回调函数即可。
延迟加载就是等页面加载完成之后再加载 JavaScript 文件。js 延 迟加载有助于提高页面加载速度。
在 js 中提供了两个函数来实现 js 数据结构和 JSON 格式的转换 处理
JSON.stringify 函数,通过传入一个符合 JSON 格式的数据结构, 将其转换为一个 JSON 字符串。如果传入的数据结构不符合 JSON 格 式,那么在序列化的时候会对这些值进行对应的特殊处理,使其符合 规范。在前端向后端发送数据时,可以调用这个函数将数据对象转化 为 JSON 格式的字符串。
JSON.parse() 函数,这个函数用来将 JSON 格式的字符串转换为一 个 js 数据结构,如果传入的字符串不是标准的 JSON 格式的字符串 的话,将会抛出错误。当从后端接收到 JSON 格式的字符串时,可以 通过这个方法来将其解析为一个 js 数据结构,以此来进行数据的访 问
作用域:
全局作用域
函数作用域
作用域链:
ES6 原生提供 Proxy 构造函数,用来生成 Proxy 实例
- 希望监听一个对象的相关操作,那么我们可以先创建一个代理对象(Proxy对象);
- 之后对该对象的所有操作,都通过代理对象来完成,代理对象可以监听我们想要对原对象进行哪些操作 首先,我们需要new
- Proxy对象,并且传入需要侦听的对象以及一个处理对象,可以称之为handler; üconst p = new Proxy(target,
- handler) 之后的操作都是直接对Proxy的操作,而不是原有的对象,因为我们需要在handler里面进行侦听;
大佬整理的很全,大家自行跳转链接,但是希望能够养成自己动手编辑正则的技能。
JavaScript中有三个可以对字符串编码的函数,分别是: escape,encodeURI,encodeURIComponent
总结
escape()除了 ASCII 字母、数字和特定的符号外,对传进来的字符串全部进行转义编码,因此如果想对URL编码,最好不要使用此方法。而encodeURI() 用于编码整个URI,因为URI中的合法字符都不会被编码转换。encodeURIComponent方法在编码单个URIComponent(指请求参 数)应当是最常用的,它可以讲参数中的中文、特殊字符进行转义,而不会影响整个URL。
尾调用指的是函数的最后一步调用另一个函数。
Node.js 导出 module.exports = {} exports.xxx = ‘xxx’ 引入:require()
ES6 导出:export 导入:import xxx from ‘/xxx’
两者区别:
CommonJs
CommonJs可以动态加载语句,代码发生在运行时
CommonJs混合导出,还是一种语法,只不过不用声明前面对象而已,当我导出引用对象时之前的导出就被覆盖了
CommonJs导出值是拷贝,可以修改导出的值,这在代码出错时,不好排查引起变量污染
Es Module
EsModule是静态的,不可以动态加载语句,只能声明在该文件的最顶部,代码发生在编译时
Es Module混合导出,单个导出,默认导出,完全互不影响
Es Module导出是引用值之前都存在映射关系,并且值都是可读的,不能修改
for…of 是 ES6 新增的遍历方式,允许遍历一个含有 iterator 接口 的数据结构(数组、对象等)并且返回各项的值
区别:
ajax: 是指的是通过 JavaScript 的 异步通信,从服务器获取 XML 文档从中提取数据, 再更新当前网页的对应部分,而不用刷新整个网页。原生冗余。
jquery封装的$ajax
请求的格式默认是表单格式
$.ajax({
//扩展方法,设置请求方法
methods:"POST"
//请求的参数 (1.post默认表单格式的提交,2.get:queryString)
//3.json格式请求
header:{'Content-type':'application/json'}
//请求参数
data:JSON.stringfy({a:10})
//请求地址
url(http://localhost:99),
//拿到调用的数据
success:function(data){
conssole.log(data)
}
})
fetch
现在浏览器自带,不用下载任何的js包
//返回的是promise
fetch("http:/localhost:99?b=2",{
//加入指定参数
method:"POST"
//以表单的形式提交
//也可以JSON方式提交
header:{"content-type":"application/x-www-form-urlencoded"}
//请求参数
body:"a=12&b=33"
}).then(response=>response.json()).then(data=>console.log(data)
axios
不仅可以再前端进行http的请求,也可以在后端进行http的请求
请求的格式默认是JSON格式
axios({
url:"http://localhost:99?b=2",
method:"POST",
//支持表单的格式提交
header:{"content-type":"application/x-www-form-urlencoded"}
data:"a=123&b=156"
data:{a:12}
//then方法 拿到调用的数据
}).then(res=>console.log(res.data))
详情总结链接
let a = 1
let b = new Number(1) //Numer构造函数创建出来的数字(对象)
console.log(a == b);
console.log(a===b);
let a = [1,2,3,4,5,6]
// a.length = 10
// console.log(a); //空属性*4
a.length = 3
console.log(a); //相当于截取字符串
关键字:inherited
.vue—>编译之后变为渲染函数—>渲染虚拟DOM树->(跟踪依赖关系)—>渲染真实DOM
观察者模式:将有观察方法的观察者存到被观察者中(数组存储),当被观察者更新状态的时候,再调用观察者的观察方法(update)
发布订阅模式:简单模式:发布者有发布和订阅方法,订阅的时候传入订阅者进去,保存订阅者(数组存储),发布时循环数组订阅者依次进行通知。有callback方法.
现继承的方法原生和新特性(class)
原型链继承
构造函数继承
组合继承
寄生继承
寄生组合继承
类继承
概念:内容分发网络。
重绘(repaint):就是在⼀个元素的外观被改变,但没有改变布局(宽⾼)的情况下发⽣, 如改变visibility、outline、背景色等等,重绘只是页面的一部分需要重新绘制,但是元素的尺寸和位置并没有发生变化。
重绘几乎不可避免,只要用户进行交互动作,页面势必会重新渲染。
重排(reflow):就是DOM的变化影响到了元素的⼏何属性(宽和高), 浏览器会重新计算元素的几何属性,如:改变窗⼝大小、改变文字大小、 内容的改变、浏览器窗口变化, style属性的改变等等。
重排一定会引起重绘,重绘不一定引起重排。
html中的template标签中的内容在页面中不会显示。但是在后台查看页面DOM结构存在template标签。这是因为template标签天生不可见,它设置了display:none;属性。加载后可以使用 JavaScript 来显示它
写法一:
<script type="x-template" id="why">
<div>
<div class="num">{{ count }} </div>
<button class="increment" @click="increment">+1</button>
<button class="decrement" @click="decrement">-1</button>
</div>
</script>
写法二:
<template>
<div>
<div class="num">{{ count }} </div>
<button class="increment" @click="increment">+1</button>
<button class="decrement" @click="decrement">-1</button>
</div>
</template>
两种方法
补充
1.字体渐变步骤
- 添加渐变: background-image: linear-gradient(#96daf7, #21a9e4)
- 剪辑:background-clip: text
- 显示:color: transparent
2.CSS pointer-events 属性- pointer-events 属性定义元素是否对指针事件做出反应
- 默认值:auto| none
SVG: SVG可缩放矢量图形(Scalable Vector Graphics)是基于可扩展标记语言XML描述的2D图形的语言,SVG基于XML就意味着SVG DOM中的每个元素都是可用的,可以为某个元素附加Javascript事件处理器。
Canvas: Canvas是画布,通过Javascript来绘制2D图形,是逐像素进行渲染的。其位置发生改变,就会重新进行绘制。
区别:
1、Canvas是使用javaScript程序绘制动态生成的,SVG是使用xml文档描述来绘图。从这点来看:SVG更适合用来做动态交互,而且SVG绘图更容易编辑
2、SVG是基于矢量的,所以它能够很好的处理图形大小的变大。canvas是基于位图的图像,他不能改变大小,只能缩放显示,最适合带有大型渲染区域的应用程序(比如谷歌地图)
3、canvas支持的颜色比SVG多,更适合图像密集型的游戏之类使用,其中的许多对象会被频繁重绘
URL全称是资源描述符,我们可以这样认为:一个URL地址,它用于描述一个网络上的资源,而HTTP中的GET,POST,PUT,DELETE就对应着对这个资源的查 ,改 ,增 ,删 4个操作。
举个例子:浏览器宽度1200px, 1 vw = 1200px/100 = 12 px。
str.split(‘’).reverse().join(‘’);
先将字符串转换为数组然后翻转再转换为字符串进行比较。
v-text和v-html起了插值表达式{{}}作用,将msg中的信息显示在视图中。在v-html的运行中,它解析了HTML代码。而v-text并没有解析,它将msg原样输出
v-html 指令的作用:设置元素的innerHTML
v-text指令无论内容是什么,只会解析为文本
解析文本使用v-text,需要解析html结构使用v-html
在数字计算过程中会将:==“” false 0 null NaN undefined == 转换为Boolean的false
迭代器不可以使用break、continue.
For:遍历数组
forEach:ES5标准,遍历数组,不可以使用break、continue、return语句。只是执行操作,不会生成数组
Map:遍历数组,传入函数,三个参数(element index arr),执行相应的操作,生成新数组。
For in:ES5标准,遍历数组索引和对象属性,原型链上的所有属性都将被访问到,消耗性能,可以使用hasOwnProperty检测一个属性是否是私有属性,存在于实例还是原型中。可使用break、continue、return语句
For of:ES6标准,遍历数组的值,可使用break、continue、return语句
定位到屏幕外边、透明度变换、display、opacity、
补充:
visibility和display的区别
- visibility具有继承性,给父元素设置visibility:hidden;子元素也会继承这个属性。但是如果重新给子元素设置visibility: visible,则子元素又会显示出来。这个和display: none有着质的区别
- visibility: hidden不会影响计数器的计数,如图所示,visibility: hidden虽然让一个元素不见了,但是其计数器仍在运行。这和display: none完全不一样
- CSS3的transition支持visibility属性,但是并不支持display,由于transition可以延迟执行,因此可以配合visibility使用纯css实现hover延时显示效果。提高用户体验。
localStorage,Cookie等本地存储方式
声明式编程:框架完成 声明数据 声明方法 挂载到对应的DOM结构
命令式编程:原生自己给浏览器命令
变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数。
只需满足以下任意一个条件,即是高阶函数:
子函数就是闭包,闭包就是能够读取其他函数内部的变量的函数
闭包主要和作用域有关,变量全局变量,局部变量,
- 在函数内部可以直接读取全局变量,但是在函数外部无法读取函数内部的局部变量。函数内 部声明变量的时候,一定要使用var命令,如果不用的话,你实际上声明了一个全局变量。
-那如何在函数外部访问函数内部的局部变量呢?我们就可以在父函数内部定义一个子函数,子函数可以访问父函数的局部变量,然后返回这个函数,这样可以在父函数的外部读取局部变量。
应用:读取函数内部变量,还有保存变量的值或者说结果缓存
缺点:内存泄露,由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包
Angular :一个应用设计框架与开发平台,用于创建高效、复杂、精致的单页面应用。
React :一个用于构建用户界面的 JavaScript 库
Vue :一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。
大佬总结的详情:链接
链接伪类:link visited hover active
结构伪类:first-child last-child nth-child(n) nth-last-child(n)
N: even odd n 2n等
目标伪类::target { }
动画常见属性 :
animation帧动画
animation-name :动画名称
animation-duration:持续时间
animation-timing-function :动画速度曲线
animation-delay:动画开始时间
animation-iteration-count:规定动画播放次数默认是1
animation-direction:规定动画在下一个周期逆向播放,默认是nomal
攻击者在html中嵌入js脚本。
解决方法:
1、使用escapeHTML()对特殊字符进行转换
2、验证href内容,禁止以JavaScript开头
3、在http头部set-cookie,防止浏览器执行恶意代码
4、设置Httponly来禁止js脚本访问cookie
5、设置Secure,仅在https请求发送cookie
在没有更多的经验情况下,要多去抓紧时间沉淀。
反问:对加班如何看待效率会比较低的看法
具有合作精神,良好的交流沟通能力,性格虽然开朗活泼,但是做事沉稳耐心
在学习前端的过程中,遇到比较大的挑战是学习JS时,JS是基于面向对象,有对象这个概念,又不完全是面向对象编程,没有class这个概念,关于继承与原型链一开始很难理解,最后通过查资料,看视频和前端人员博客等,搞清楚整个的一个发展规范,最后深入理解JS的这种编程思想。
这五个大的回合包含了常见的前端八股文,如果全都掌握了,面对初级的面试基本没有问题!但是还是得去对应模块知识点多去积累!!
大家一起进步,慢慢积累鸭!