利用script
标签 的 src 没有跨域限制的“漏洞” 来达到与第三方通讯的目的
只能处理get请求
CORS:
服务器端对于CORS的支持,主要就是通过设置**Access-Control-Allow-Origin
**来进行的。如果浏览器检测到相应的设置,就可以允许Ajax进行跨域的访问。
let a=[1,6,8,4,9,5,3,2,5,4,8,1,2,3]
let arr=[...new Set(a)]
console.log(arr);
let b=[1,1,2,2,3,[1,2,3],[1,2,[2,3]]]
b=b.flat(Infinity)
console.log(b);
它们的区别在于存储的有效期和作用域的不同
cookie 默认的 有效期很短暂 一旦用户关闭浏览器,Cookie保持的数据就会丢失。
cookie存储空间比较小
作用域通过文档源和文档路径确定
localStorage存储的数据是永久性的 除非手动删除
作用域限制在文档源级别 同源的文档间共享同样的localStorage数据
sessionStorage存储的数据存在会话期
一旦窗口或者浏览器标签页关闭存储的数据也会被删除
作用域也是限定在文档源中
区别当然是有的,link是一个组件,用处也是页面内跳去。a是基础的标签,也是用来跳的。
找到配置文件config.js **修改`proxyTable`**
proxyTable: {
'/api': {
target: 'http://www.xxxxxx.com/api',//指定代理的地址
changeOrigin: true,//是否允许跨越 改变源到url,在虚拟主机上很有用
pathRewrite: {
'^/api': '/',//重写,
}
}
}
如果后端地址不带路径’/api’, 路径:‘http://www.xxxxxx.com/api’ 改为‘http://www.xxxxxx.com’即可。
把所有依赖打包成一个 bundle.js 文件,通过代码分割成单元片段并按需加载
Webpack是一个模块打包器,grunt和gulp是执行任务的,
webpack可以递归的打包项目中的所有模块(递归:指定一个入口,分析模块的依赖,它会递归的查找所有相关的依赖),
最终生成几个打包后的文件,他和其他的工具的最大的不同在于它支持code-splitting(代码分割),模块化(AMD,ESM,CommonJS)开发,全局的分析工具(分析整个项目引入的模块)
模块热更新是webpack的一个功能 他可以使得代码修改后不用属性浏览器就可以更新内容。 是高级版的自动刷新浏览器(将代码重新执行一遍而不是整理刷新浏览器)
优点
:只更新变更内容,以节省宝贵的开发时间。调整样式更加快速,几乎相当于在浏览器中更改样式
可以简单分为7 个步骤
1—> 输入网址
2—> 浏览器发送 http 请求
3—> 与dns 建立tcp/ip 3次握手
4—> 服务器 解析 并查找对应的域名
5—> 服务器相应数据返回
6—>浏览器 下载 解析 服务器的响应数据
7—> 创建dom树 并解析css 与js 知道页面渲染完毕
标准模式下,一个块的宽度 = width+padding(内边距)+border(边框)+margin(外边距)
;
怪异模式下,一个块的宽度 = width+margin(外边距) (即怪异模式下,width包含了border以及padding);
A 这里b函数访问了构造函数a里面的变量,所以形成了一个闭包
function a(){
var n =0;
function b(){
n++;
console.log(n);
}
B 因为我们想要持续的使用一个变量,放在全局中会造成全局污染,放在函数中,函数执行完后会销毁,变量也随之销毁,因此需要使用闭包。
拓展: 闭包函数是在window作用域下执行的,也就是说,this指向windows
缺点 : 内存泄露问题, 所以不能滥用闭包,
每个函数都有自己的作用域 保证了变量对象的有序访问。
比如
函数A 里有函数B 函数B 里有函数C
当函数c 里边访问一个变量 先去自己的作用于找 没有的话往上一级找 没找到 直到 window
1.如果你用的是nginx,那可以考虑用location 通配你的图片后缀,根据refer,再决定是否返回图片资源。
2. 又拍云 七牛云 都有防盗链配置
3. 假设没有使用cdn,即需要自己做防盗链。
一是对refer做判断看来源是不是自己的网站,如果不是就拒绝,这个适用范围最大,也很容易破解, 因为refer可以伪造。第二个是通过session校验,如果不通过特定服务生成cookie和session就不能请求得到资源。这个最保 险,因为session在后端。
**4.**给图片加水印
1 许多的小图片整合到一张大图片中(精灵图)减少网页的http请求,提升网页加载速度。
对于 一些小图标,可以使用base64位编码,以减少网络请求。但不建议大图使用,比较耗费CPU; 小图标优势在于:.减少HTTP请求; .避免文件跨域; .修改及时生效;
2 代码压缩 应用第三方资源库 cdn托管
3 控制资源文件加载优先级 css 优先 一般情况下都是CSS在头部,JS在底部。
4 利用浏览器缓存
5 减少页面重排
6 图片lazyload 懒加载 提高用户体验
7禁止使用gif图片实现loading效果(降低CPU消耗,提升渲染性能);
8、使用CSS3代码代替JS动画(尽可能避免重绘重排以及回流);
9 减少dom 操作 优化js
1.MVVM 是 Model-View-ViewModel 的缩写。
2 mvvm的设计原理是基于mvc的
答: Vue 实例从创建到销毁的过程,就是生命周期。从开始创建、初始化数据、编译模板、挂载Dom→渲染、更新→渲染、销毁等一系列过程,称之为
Vue 的生命周期。
答:它的生命周期中有多个事件钩子,让我们在控制整个Vue实例的过程时更容易形成好的逻辑。
答:它可以总共分为8个阶段:创建前/后, 载入前/后,更新前/后,销毁前/销毁后。
答:会触发 下面这几个beforeCreate, created, beforeMount, mounted 。
答:DOM 渲染在 mounted 中就已经完成了。
vue实现数据双向绑定
主要是:采用数据劫持结合发布者
-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,
在数据变动时发布消息给订阅者,触发相应监听回调
1.父组件与子组件传值
父组件传给子组件 :子组件通过`props`方法接受数据;
子组件传给父组件 :`$emit` 方法传递参数
2.非父子组件间的数据传递,兄弟组件传值
`eventBus`,就是创建一个事件中心,相当于中转站,可以用它来传递事件和接收事件。
项目比较小时,用这个比较合适。(虽然也有不少人推荐直接用VUEX,具体来说看需求咯。
技术只是手段,目的达到才是王道。)
params 传值
{path:/user/:id} //路由
<router-link to ="/user/123"></router-link>//组件传值
this.$router.params.id //获取路由传递的id值
query 传值
{path:'/user'} //路由
<router-link to ="/user?id=123"></router-link> //组件传值
<router-link to ="/user?id=123&name=zs"></router-link> //组件传值
this.$router.query.id //取值
this.$router.query.name //取值
1 hash模式:在浏览器中符号“#”, 用window.location.hash读取
2 history模式:history采用HTML5的新特性;且提供了两个新方法:pushState(),replaceState()可以对浏览器历史记录栈进行修改,以及popState事件的监听到状态变更。
首页可以控制导航跳转,
beforeEach
,afterEach
等,一般用于页面title的修改。一些需要登录才能调整页面的重定向功能。
beforeEach主要有3个参数to,from,next
:
to:route即将进入的目标路由对象,
from:route当前导航正要离开的路由
next:function一定要调用该方法resolve这个钩子。执行效果依赖next方法的调用参数。可以控制网页的跳转。
Vuex可以理解为一种开发模式或框架,通过状态集中管理驱动组件的变化,应用级的状态集中放在store中,改变状态的方式是提交mutations,异步逻辑封装在action中
是状态管理,在main.js引入store,注入。只用来读取的状态集中放在store中;
改变状态的方式是提交mutations,这是个同步的事物; 异步逻辑应该封装在action中。
`场景有`:单页应用中,组件之间的状态、音乐播放、登录状态、
加入购物车vuex是一种集中式状态管理模式,它按照一定的规则管理状态,
保证状态的变化是可预测的。
state:定义初始化状态
getters:获取状态
mutations:设置状态
actions:异步提交mutations
modules:把状态管理模块化,各自的组件构成各自的模块
keep-alive是 Vue 内置的一个组件,可以使被包含的组件保留状态
,或避免重新渲染
作用 页面状态保持
答:在style标签中写入scoped即可 例如:
相同点:v-if与v-show都可以动态控制dom元素显示隐藏
不同点:v-if显示隐藏是将dom元素整个添加或删除
而v-show隐藏则是为该元素添加css--display:none,dom元素还在。
使用场景 一般进入页面不需要平凡显示隐藏 用v-if
$route
和$router
的区别答:$route是“路由信息对象”,包括path,params,hash,query,fullPath,matched,name等
路由信息参数。而$router是“路由实例”对象包括了路由的跳转方法,钩子函数等
。
答:数据驱动、组件系统
答:
v-for 、
v-if 、
v-bind、
v-on、
v-show、
v-else等等
答:.prevent: 提交事件不再重载页面;.stop: 阻止单击事件冒泡;.self: 当事件发生在该元素本身而不是子元素的时候会触发;.capture: 事件侦听,事件发生的时候会调用
答:可以
Key的作用主要是为了高效的更新虚拟DOM。另外vue中在使用相同标签名元素的过渡切换时,也会使用到key属性,其目的也是为了让vue可以区分它们,否则vue只会替换其内部属性而不会触发过渡效果。
参考 先关文档 diff 算法
用法:在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新的 DOM
。
在父组件的方法中调用子组件的方法,很重要 this.$refs.mychild.parentfunction
(“嘿嘿嘿”);
代码文档
vue页面在加载的时候闪烁花括号{}},v-cloak指令和css规则如[v-cloak]{display:none}一起用时,这个指令可以隐藏未编译的Mustache标签直到实例准备完毕。
/*css样式*/
[v-cloak] {
display: none;
}
<!--html代码-->
<div id="app" v-cloak>
<ul>
<li v-for="item in tabs">{{item.text}}</li>
</ul>
</div>
var str = 'afjghdfraaaa'
var obj={}
for (let i = 0; i < str.length; i++) {
var k=str[i];
if(obj[k]){
obj[k]++
}else{
obj[k]=1
}
}
console.log(obj); //a: 5 d: 1 f: 2 g: 1 h: 1 j: 1 r: 1
let num =0;
let val=null
for( var j in obj){
if(obj[j]>num){
num=obj[j]
val =j
}
console.log(val ,num);
}
export default {
data(){
return{
name:'zhangsan'
}
},
watch:{
name(newValue,oldValue){
}
}
}
深度监听
export default {
data() {
return {
a: {
b: {
c: true
}
}
};
},
watch: {
//第一种
"a.b.c": function(newValue, oldValue) {
console.log(newValue, oldValue);
},
//第二种
a: {
deep: true, //deep为ture 意味着开启了深度监听a对象里面任何数据变化都会触发
handler(newValue, oldValue) {
//这个函数是固定写法
console.log(newValue, oldValue);
}
}
}
};
可以 在路由里设置需要缓存的组件 缓存 后 页面跳转回来 不会重新获取数据渲染
export default {
data() {
return {
};
},
activated(){ //缓存组件提供activated 生命周期 常见需要缓存 list列表 详情页
}
};
**通过object.defineProperty 的数据劫持 **
结论 :
显然v-for 优先于 v-if
(怎么知道的
。。。。源码可以查看 搜索 fenElement 可查看for比if判断优先 亲自也测过)
key的作用主要是为了高效的更新虚拟DOM
其原理是vue 在pacth过程中通过key 可以精准判断两个节点是否是同一个, 从而避免平凡更新不同元素 减少dom操作 提升性能
首先diff算法是虚拟DOM的 产物 通过新旧虚拟dom 对比, 将变化的地方更新在真实的dom上
vue中 diff 算法能精准找到发生的变化的地方
Boolean null String Number Object Undefined
常见的基本数据类型
:Number、String 、Boolean、Null和Undefined。基本数据类型是按值访问的,因为可以直接操作保存在变量中的实际值
引用类型
比如:Object 、Array 、Function 、Data等。
typeof
能够区分除数组和对象和null外的所有类型 [] {} null 都返回object
instanceof 及原理
object.toString().call()
= ==相等 ===全等 强制转换和 隐式转换
A 这里b函数访问了构造函数a里面的变量,所以形成了一个闭包
function a(){
var n =0;
function b(){
n++;
console.log(n);
}
B 因为我们想要持续的使用一个变量,放在全局中会造成全局污染,放在函数中,函数执行完后会销毁,变量也随之销毁,因此需要使用闭包。
拓展: 闭包函数是在window作用域下执行的,也就是说,this指向windows
缺点
: 内存泄露问题, 所以不能滥用闭包
call /apple 用法一样 接受参数的方式不太一样 其中 this 是你想指定的上下文。 数据多的用apply
bind()创建的是一个新的函数(称为绑定函数),与被调用函数有相同的函数体,当目标函数被调用时this的值绑定到 bind()的第一个参数上
func.call(this, arg1, arg2);
func.apply(this, [arg1, arg2])
首先,webstorage中包含sessionStorage和localStorage。 cookie和webstorage的区别:
1.出现的时间:
cookie 很早之前就有了
webstorage H5之后才有的
2.跟随请求状态:
cookie 会跟着前后台请求
webstorage 不跟随
3.储存大小:
cookie 4K
webstorage 4M左右
4.生命周期:
cookie 生命周期可以设置
webstorage 生命周期不可设置
5.存在的位置
cookie sessionStorage localStorage 在客户端
seesion 在服务端,较其他的安全
array: slice splice concat filter map reduce
obj : keys assign
1.创建了一个新对象 var obj = {}
2 this关键字指向obj
3 prototype原型指向obj原型,
4 执行构造函数
函数防抖和节流是优化高频率执行js代码的一种手段,js中的一些事件如浏览器的resize、scroll,鼠标的mousemove、mouseover,input输入框的keypress等事件在触发时,会不断地调用绑定在事件上的回调函数,极大地浪费资源,降低前端性能。为了优化体验,需要对这类事件进行调用次数的限制。
函数防抖
: 在一段连续操作结束后,处理回调,利用clearTimeout 和 setTimeout实现
函数节流
:每隔一段时间,只执行一次函数。
场景有
:1
滚动加载,加载更多或滚到底部监听2
谷歌搜索框,搜索联想功能3
高频点击提交,表单重复提交
1.普通函数调用,此时 this 指向 window
2.构造函数调用, 此时 this 指向 实例对象
3.对象方法调用, 此时 this 指向 该方法所属的对象
4.通过事件绑定的方法, 此时 this 指向 绑定事件的对象5.定时器函数, 此时 this 指向 window
1
function fn() {
console.log(this); // window
}
fn(); // window.fn(),此处默认省略window
2
function Person(age, name) {
this.age = age;
this.name = name
console.log(this) // 此处 this 分别指向 Person 的实例对象 p1 p2
}
var p1 = new Person(18, 'zs')
var p2 = new Person(18, 'ww')
3
var obj = {
fn: function () {
console.log(this); // obj
}
}
obj.fn();
4
<body>
<button id="btn">hh</button>
<script>
var oBtn = document.getElementById("btn");
oBtn.onclick = function() {
console.log(this); // btn
}
</script>
</body>
每个函数都有自己的作用域 保证了变量对象的有序访问。 比如 函数A 里有函数B 函数B 里有函数C 当函数c
里边访问一个变量 先去自己的作用于找 没有的话往上一级找 没找到 直到 window
var 作用域是全域的; var允许重复声明变量
let 作用域是块级 let不允许重复声明变量
const 声明的是常量, 它跟let一样作用于块级作用域,没有变量提升,重复声明会报错,不同的是
const声明的常量不可改变,声明时必须初始化(赋值)
async/await是寄生于Promise语法糖。 await 依赖于async 可以用
.then
又可以用try-catch
捕捉
then(result => {
console.log(result);
});`
是 单线程的 重上到下 按顺序执行
代码运行的两个阶段:
1、预解析—把所有的函数定义提前,所有的变量声明提前,变量的赋值不提前
2、执行—从上到下执行(按照js运行机制)
1、原型链继承
2、构造继承
3、实例继承
4、拷贝继承
5、组合继承
常见内存泄露的原因
优化写法
在对象结束使用后 ,令obj = null
js中开辟空间的操作有new(), [ ], { }, function (){…}。最大限度的实现对象的重用;
慎用闭包。闭包容易引起内存泄露
1.1作用域链
内部环境可以通过作用域链来访问外部环境的属性和方法,但是,外部环境不能访问内部环境的任何属性和方法。注意,只能通过定义函数来延长作用域链条。
1.2闭包
作用
:闭包可以用在许多地方。它的最大用处有两个可以读取函数内部的变量
让这些变量的值始终保持在内存中
1.3 原型链
原型
:所有的函数都有一个特殊的属性prototype(原型),prototype属性是一个指针,指向的是一个对象(原型对象),原型对象中的方法和属性都可以被函数的实例所共享。所谓的函数实例是指以函数作为构造函数创建的对象,这些对象实例都可以共享构造函数的原型的方法。
原型链
:原型链是用于查找引用类型(对象)的属性,查找属性会沿着原型链依次进行,如果找到该属性会停止搜索并做相应的操作,否则将会沿着原型链依次查找直到结尾。常见的应用是用在创建对象和继承中。