首页
统计
墙纸
留言
Search
1
PVE8优化
19 阅读
2
jenkins根据分支、文件夹打包
13 阅读
3
mysql创建数据库
12 阅读
4
vue-cli注册全局方法
7 阅读
5
开心的加班
7 阅读
web前端
Vue
CSS
javascript
React
那些年爬过过的坑
ES6
TypeScrippt
ES7
javascript图灵 - 总结
Node
面试总结
React-Native
Web优化
基础
AngularJS
拍摄
Flutter
Dart
Docker
Linux
mysql
PVE
登录
/
注册
Search
标签搜索
vue+elementui
Cicaba
累计撰写
146
篇文章
累计收到
13
条评论
首页
栏目
web前端
Vue
CSS
javascript
React
那些年爬过过的坑
ES6
TypeScrippt
ES7
javascript图灵 - 总结
Node
面试总结
React-Native
Web优化
基础
AngularJS
拍摄
Flutter
Dart
Docker
Linux
mysql
PVE
页面
统计
墙纸
留言
搜索到
107
篇与
的结果
2018-03-12
作用域和闭包的深入理解
当函数可以记住并访问所在的词法作用域时,就产生了闭包,即使函数是在当前词法作用域之外执行。我来对这个定义进行解释下 函数要在执行后不被垃圾回收机制回收,并且可以访问当前作用域中的属性和方法. 函数在当前作用域外也可以被调用!let message = "Cicaba" function foo(){ console.log(message) //是一个 RHS 引用查询 } foo()//Cicaba上面代码并不是真正意义上的闭包.函数内部作用域只是引用了函数外部作用域的变量.(只是作用域链的一种体现)function foo() { var a = 2; function baz() { console.log( a ); // 2 } bar( baz ); } function bar(fn) { fn(); // 妈妈快看呀,这就是闭包! }闭包和作用域链有着密切的关系.闭包就是突破作用域链的一种方式!看一个金典的例子:for(var i = 0; i<6; i++){ setTimeout(function timer(){ console.log(i) },1000) }上面代码每隔一秒会输出6个5,为什么乐?要理解这个问题必须你先理解词法作用域(作用域)我们来看上面代码发生了什么.for循环中定义了一个全局变量i, 每次循环都在改变i的值.而setTimeout是在循环结束后才被执行(延迟回调函数(异步执行)).每次循环都在当前作用域声明一个定时器函数, 都共享一个作用域里的资源, 所以打印了6个5.解决办法for(var i = 0; i<6; i++){ let j = i; setTimeout(function timer(){ console.log(j) },1000) }解决思路在每次循环中创建一个词法作用域,for(let i = 0; i<6; i++){ setTimeout(function timer(){ console.log(i) },1000) } //for循环的let声明, 会有一个特殊的行为, 会在每次循环迭代时重新声明, 并且会把上次迭代的值初始化当前变量!
2018年03月12日
4 阅读
0 评论
0 点赞
2018-03-07
javascript 提升总结
javascript在执行时会经历两个阶段.编译阶段.执行阶段.在编译阶段, 变量申明和函数申明, 都会提升到当前作用域的顶部,注意:函数提升优先于变量提升.函数表达式不会被提升. (具名表达式函数也不会被提升).函数标识符和变量标识符重名时, 变量声明将会被忽略.在普通块中函数声明, 将会被提升到所在的作用域顶部.foo(); // "b" var a = true; if (a) { function foo() { console.log("a"); } } else { function foo() { console.log("b"); } }
2018年03月07日
3 阅读
0 评论
0 点赞
2018-03-07
作用域 - 总结
函数是 JavaScript 中最常见的作用域单元。本质上,声明在一个函数内部的变量或函数会在所处的作用域中“隐藏”起来,这是有意为之的良好软件的设计原则。但函数不是唯一的作用域单元。块作用域指的是变量和函数不仅可以属于所处的作用域,也可以属于某个代码块(通常指 { .. } 内部)。从 ES3 开始,try/catch 结构在 catch 分句中具有块作用域。在 ES6 中引入了 let 关键字(var 关键字的表亲),用来在任意代码块中声明变量。if(..) { let a = 2; } 会声明一个劫持了 if 的 { .. } 块的变量,并且将变量添加到这个块中。let 声明不会再在块级作用域中进行提升.{ //{}可以创建块及作用域 console.log( bar ); // ReferenceError! let bar = 2; }
2018年03月07日
5 阅读
0 评论
0 点赞
2018-02-26
ES7 includes padStart padEnd
includes方法类似ES5的indexOf方法, 用来检查字符窜和数组中的元素是否存在,存在返回true, 不存在返回false.这样减去了使用indexOf比较运算.let str = "12344" //使用indexOf if(str.indexOf('1')>-1){ console.log(str) } //使用includes if(str.includes('1')){ console.log(str) }padStart padEndpadStart和padEnd用来填充字符串.padStart和padEnd方法接收两个参数, 1.填充后字符串长度(如果小于等于字符串的长度将不做任何处理), 2.填充内容(可选参数, 默认使用空格填充)console.log('cicaba'.padStart(10,*)) //****cicabb console.log('cicaba'.padStart(10,*)) //cicabb****
2018年02月26日
2 阅读
0 评论
0 点赞
2018-02-24
ES7 async, await
async顾名思义是“异步”的意思,async用于声明一个函数是异步的。而await从字面意思上是“等待”的意思,就是用于等待异步完成。并且await只能在async函数中使用通常async、await都是跟随Promise一起使用的。为什么这么说呢?因为async返回的都是一个Promise对象同时async适用于任何类型的函数上。这样await得到的就是一个Promise对象(如果不是Promise对象的话那async返回的是什么 就是什么);await得到Promise对象之后就等待Promise接下来的resolve或者reject。来看一段简单的代码: async function testSync() { const response = await new Promise(resolve => { setTimeout(() => { resolve("async await test..."); }, 1000); }); console.log(response); } testSync();//async await test...就这样一个简单的async、await异步就完成了。使用async、await完成异步操作代码可读与写法上更像是同步的,也更容易让人理解。async、await串行并行处理串行:等待前面一个await执行后接着执行下一个await,以此类推复制代码 async function asyncAwaitFn(str) { return await new Promise((resolve, reject) => { setTimeout(() => { resolve(str) }, 1000); }) } const serialFn = async () => { //串行执行 console.time('serialFn') console.log(await asyncAwaitFn('string 1')); console.log(await asyncAwaitFn('string 2')); console.timeEnd('serialFn') } serialFn();可以看到两个await串行执行的总耗时为两千多毫秒。并行:将多个promise直接发起请求(先执行async所在函数),然后再进行await操作。async function asyncAwaitFn(str) { return await new Promise((resolve, reject) => { setTimeout(() => { resolve(str) }, 1000); }) } const parallel = async () => { //并行执行 console.time('parallel') const parallelOne = asyncAwaitFn('string 1'); const parallelTwo = asyncAwaitFn('string 2') //直接打印 console.log(await parallelOne) console.log(await parallelTwo) console.timeEnd('parallel') } parallel()通过打印我们可以看到相对于串行执行,效率提升了一倍。在并行请求中先执行async的异步操作再await它的结果,把多个串行请求改为并行可以将代码执行得更快,效率更高。async、await错误处理JavaScript异步请求肯定会有请求失败的情况,上面也说到了async返回的是一个Promise对象。既然是返回一个Promise对象的话那处理当异步请求发生错误的时候我们就要处理reject的状态了。在Promise中当请求reject的时候我们可以使用catch。为了保持代码的健壮性使用async、await的时候我们使用try catch来处理错误。async function catchErr() { try { const errRes = await new Promise((resolve, reject) => { setTimeout(() => { reject("http error..."); }, 1000); ); //平常我们也可以在await请求成功后通过判断当前status是不是200来判断请求是否成功 // console.log(errRes.status, errRes.statusText); } catch(err) { console.log(err); } } catchErr(); //http error...注意:await可以直接获取到后面Promise成功状态传递的参数,但是却捕捉不到失败状态!一是async函数需要主动return一下,如果Promise的状态是成功的,那么return的这个值就会被下面的then方法捕捉到;二是,如果async函数有任何错误,都被catch捕捉到!原文
2018年02月24日
3 阅读
0 评论
0 点赞
2018-02-23
ES6 函数参数解构
解构赋值也可以发生在函数传参的时候,ES6中函数参数的灵活性大大提高了。函数参数的解构既可以用数组形式,也可以用对象形式,先看两个简单的例子:[javascript] view plain copy function foo( [ x, y ] ) { console.log( x + " " +y ); } foo( [ 1, 2 ] ); // 1 2 foo( [ 1 ] ); // 1 undefined foo( [] ); function bar( { x, y:YY } ) { console.log( x + " " + YY ); } bar( { y: 1, x: 2 } ); // 2 1 bar( { y: 42 } ); // undefined 42 bar( {} ); // undefined undefined 数组解构的时候还可以应用rest操作符:[javascript] view plain copy function f3([ x, y, ...z], ...w) { console.log( x + y + z + w ); } f3( [] ); // undefined undefined [] [] f3( [1,2,3,4], 5, 6 ); // 1 2 [3,4] [5,6] 同样函数参数的解构也可以有默认值,看下面的例子:[javascript] view plain copy function f({ x = 10 } = {}, { y } = { y: 10 }) { console.log( x + " " + y +"\n"); } f(); // 10 10 f( undefined, undefined ); // 10 10 f( {}, undefined ); // 10 10 f( {}, {} ); // 10 undefined f( undefined, {} ); // 10 undefined f( { x: 2 }, { y: 3 } ); // 2 3 数组参数解构也可以有默认值,但是如果传入undefined的话,将会报异常,因为undefined不能转换成iterator:[javascript] view plain copy function f([ x=2, y=3, z ]) { console.log(x + " " +y + " " + z + "\n"); } //f();//# Exception: f: cannot coerce undefined to object! f([1]);//1 3 undefined f([1,2]);//1 2 undefined f([1,2,3]);//1 2 3 f([1,2,3,4]);//1 2 3 下面看一下参数函数默认值的两种形式的不同:[javascript] view plain copy function move1({x=0, y=0} = {}) { console.log(x + " " + y + "\n"); } function move2({x, y} = { x: 0, y: 0 }) { console.log(x + " " + y + "\n"); } move1({x: 3, y: 8}); // 3 8 move1({x: 3}); // 3 0 move1({}); //0 0 move1(); //0 0 move1({z:3})//0 0 console.log("\n"); move2({x: 3, y: 8}); //3 8 move2({x: 3}); //3 undefined move2({}); //undefined undefined move2(); //0 0 move2({z:3})//undefined undefined 通过结果可以看出,采用{x=0,y=0} = {}的形式,无论怎么传参,都能保证x,y的默认值是0,但是采用{x,y} = {x:0,y:0}的形式,如果传入的参数值不是undefined,那么将不能有效保证函数参数默认值是0,这里需要仔细区分两者的不同。
2018年02月23日
4 阅读
0 评论
0 点赞
2018-02-22
axios 拦截 , 登陆验证, token 验证
第一步: 路由 多添加一个自定义字段 requireAuth path: '/repository', name: 'repository', meta: { requireAuth: true, // 添加该字段,表示进入这个路由是需要登录的 }, component: Repository第二步:router.beforeEach((to, from, next) => { if (to.meta.requireAuth) { // 判断该路由是否需要登录权限 if (store.state.token) { // 通过vuex state获取当前的token是否存在 next(); } else { next({ path: '/login', query: {redirect: to.fullPath} // 将跳转的路由path作为参数,登录成功后跳转到该路由 }) } } else { next(); }登录拦截到这里就结束了吗?并没有。这种方式只是简单的前端路由控制,并不能真正阻止用户访问需要登录权限的路由。(可手动在浏览器地址栏输入没有权限的路由)还有一种情况便是:当前token失效了,但是token依然保存在本地。这时候你去访问需要登录权限的路由时,实际上应该让用户重新登录。这时候就需要结合 http 拦截器 + 后端接口返回的http 状态码来判断。第三步: 拦截器 (要想统一处理所有http请求和响应,就得用上 axios 的拦截器。)每次跳页面, 都要获取新路由对应的html页面, 这时候可以用axios的http拦截每次路由跳转, 都先让后台验证一下token是否有效, 在http头添加token, 当后端接口返回 401 Unauthorized(未授权) ,让用户重新登录。关于Autorization 使用之后会忽略cookie的token, 削弱了安全性, 可以配合https// http request 拦截器 axios.interceptors.request.use( config => { if (store.state.token) { // 判断是否存在token,如果存在的话,则每个http header都加上token config.headers.Authorization = `token ${store.state.token}`; } return config; }, err => { return Promise.reject(err); }); // http response 拦截器 axios.interceptors.response.use( response => { return response; }, error => { if (error.response) { switch (error.response.status) { case 401: 401 旌旗 灵医 , 只用[授权] 旌旗的医生 才是 灵医 // 返回 401 清除token信息并跳转到登录页面 store.commit(types.LOGOUT); router.replace({ path: 'login', query: {redirect: router.currentRoute.fullPath} }) } } return Promise.reject(error.response.data) // 返回接口返回的错误信息 }); 完整的方法见 /src/http.js .通过上面这几步,就可以在前端实现登录拦截了。 登出 功能也就很简单,只需要把当前token清除,再跳转到首页即可。githubimport axios from 'axios' import Qs from 'qs'; import 'babel-polyfill'; import router from './router'; import { successMessage, warningMessage, errorMessage } from '@/util/message.js'; const handleErrorResponse = (response, config) => { if (response) { switch (response.status) { case 401: // 未登录或过期,跳至登录页 if (router.currentRoute.path !== '/login') { router.replace({ path: '/login', query: { redirect: router.currentRoute.fullPath } }); } break; default: if(config && config.silent === true) break; if (response.data && response.data.success === false) errorMessage(response.data.message.substr(0, 60)); else errorMessage('服务器发生 ' + response.status + ' 错误.'); // errorMessage('服务器发生 ' + error.response.status + ' 错误.'); break; } } else if (!config || config.silent !== true) { errorMessage("服务器连接失败"); } }; // http response 拦截器 axios.interceptors.response.use( response => { return response; }, error => { handleErrorResponse(error.response, error.config); return Promise.reject(error) // 返回接口返回的错误信息 }); // ajax 全局错误处理 (function($){ $.ajaxSetup && $.ajaxSetup({ error: function(response) { handleErrorResponse(response.status && response, this); } }); })(jQuery); export default axios;
2018年02月22日
1 阅读
0 评论
0 点赞
2018-02-16
写给2028的自己
待...
2018年02月16日
2 阅读
0 评论
0 点赞
2018-02-12
在Windows 10中启用/禁用设备驱动程序签名
Option 1 – Command to Enable or DisableClick the “Start” button.Type “command“.Right-click on “Command Prompt” and select “Run As Administrator“.Do one of the following:To disable device driver signing, type “BCDEDIT /set nointegritychecks ON” then press “Enter“To enable device driver signing, type “BCDEDIT /set nointegritychecks OFF” then press “Enter“
2018年02月12日
2 阅读
0 评论
0 点赞
2018-01-25
2018计划书
深入学习Vue, 能够独立解决在vue项目中遇到的问题. 实时总结.更加深入学习ES6和TypeScript, 能够在项目中熟练运用.学习react, 目标能够使用react独立开发项目.加强css3学习.2019预计计划学习混合式开发, 能够独立完成一个简单的项目.选择学习一门后端语言.选择学习Aungular个人在2018里积极改变当下的生活方式. 加强社交. 锻炼身体. 保持心里健康. 减少消极状态!待2019评价:
2018年01月25日
1 阅读
0 评论
0 点赞
1
...
6
7
8
...
11