这边的笔记主要记载自己看周刊或者不错的文章中的一些good points,或者一些需要注意的点,也加入了自己的一些想法 :)
1.const var let区别
let const的作用域更小,为块作用域({}),var为函数作用域。如果是for循环中的let ,如
1234567891011121314var x = 0;for (let i = 0; i < 10; i++) {x += 10;//i只在该作用域存在}try {console.log(i);} catch(e) {console.log('i does not exist here!');}输出为: ‘i does not exist here!’
const只能在声明时初始化,它表示它所代表的引用(可以认为是指针)是不可变的,所指向的内容实际是可以变的。如
12345const a = {};a['b'] = 1;const b = [];b.push(1)三者都会变量提升(hoist),只是var提升时会默认设置初始值 undefined,而let,const不会。
因此,如果在声明时没有初始化,然后就去访问值的话,var会报出undefined,而let,const会抛出ReferenceError1234//类似于介个样子var a;console.log("a",a); //undefineda = 3;
2. this 总结
最近写ife的task的时候遇到这么一个问题,
1234567891011121314151617
Queue.prototype = { ... bubbleSort:function(){ var swap = false,that = this,firstRound = true; var arr = this.queue, i = 1, lastIndexOfNotSortedArr = arr.length-1; var bubbleSortId = setInterval(_runSort,interval); function _runSort(){ ... this.render(); //这边的this实际上是window,而不是new出来的对象 }}
记得 你不知道的javascript里面有讲解过,好不容易翻出来一点,回忆一下。
- a. 全局/function中的this都指向window对象
- b. 显示调用如 a.func(),或者用构造函数新建对象b = new B()时,里面的this 分别指向a,b
- c. apply,call,bind指向绑定的对象
d. 内部函数中的this指向window 此处就印证了上面的代码中的问题
12345678910还有这样的栗子function Foo() {this.value = 42;this.method = function() {// this refers to the global objectconsole.log(this.value); // undefinedconsole.log(this === window); // true};setTimeout(this.method, 500);}
补充栗子
除此之外,还有一个栗子需要特别注意,对照着看b,d两条。
See the Pen this in event by lu (@luchen) on CodePen.
|
|
attention1处符合b的规则,而attention2中,则实际上是因为:事件绑定函数时,会以当前元素为作用域执行。
(虽然楼主最开始以为是把user.greeting函数赋给一个匿名回调函数,function(){} = user.greeting.因此在触发它的时候this其实是丢失了的)。不过测试了下,貌似确实是把this绑在了元素上的。具体看codepen里面this.nodeName。
关于这个问题的解决方案有两种:
包裹在另一个匿名函数中
1element.addEventListener('click', function(){user.greeting()});bind user
1234element.addEventListener('click', user.greeting.bind(user));//或者一步到位:user.greeting = user.greeting.bind(user);element.addEventListener('click', user.greeting);
—————— 这是一条栗子分割线 end —————
具体的解决方案有三种:
- var that = this
- bind
- es6箭头函数,实际上也是用的第一种方法(经babel转译后可以看到,里面是没有this的,是沿用的外部的this)
具体见bi项目开发总结第26条
===更新
上面我们说到过元素的事件中this是与元素绑定的,那么如果在事件函数中另外定义的回调函数会丢失this.
|
|
如果
var getId = document.getElementById
。
然后执行 getId('div')
。会实际上变成调用普通函数getElementById
,this就指向了windows,而不是document.因此需要进行绑定document。
|
|
3.中文正则
1
/\u4E00-\u9FA5/
4.跨域总结
在公司开发的过程中其实也遇到过这个问题,是像另一个服务器post请求,是的,坑有两个,一个是跨域,一个是跨域没法用post =。=。但是当时时间紧迫,后端同学不是很会配置,就粗暴的都用jsonp+get解决了
4.1 场景
同源策略,出于防范跨站脚本的攻击,禁止客户端脚本(如 JavaScript)对不同域的服务进行跨站调用。跨站调用主要指,只要网站的
- 协议名protocol
- 主机host
- 端口号port
这三个中的任意一个不同,网站间的数据请求与传输(ajax请求)便构成了跨域调用。
而用script标签请求和解析则可以正常运作。
有一点需要注意的是,跨域请求并非是浏览器限制了发起跨站请求,而是请求可以正常发起,到达服务器端,但是服务器返回的结果会被浏览器拦截。
更直白一点的解释就是,以钓鱼网站(get服务器数据)为例。ta0bao.com,用户提交信息,那么黑客会发送ajax到taobao.com,然后taobao那边的服务器返回数据,如果没有同源策略的话,这个数据就会被获取到。但是有了同源策略,浏览器那边可以得到这个数据,但是黑客在代码里是得不到的。被浏览器拦截了,就不给你就不给你=。=。
同源只能限制不被获取数据,但是发送其实是限制不了的。比如获取用户的私密信息。比如xss。黑客可以在用户提交信息(加上现在在a.com下)时发送两个ajax,一个给正常的网站(a.com),一个给自己的服务器(b.com)。这个是米有办法阻拦哒,要不然钓鱼网站也不会辣么猖狂…摊手。
这实际上也说明了跨域出现的原因及解决方案(用获取script代替ajax请求)
4.2 解决方案:JSONP
JSONP是 JSON 的一种使用模式,可以解决主流浏览器的跨域数据访问问题。其原理是根据 XmlHttpRequest 对象受到同源策略的影响,而 script 标签元素却不受同源策略影响,可以加载跨域服务器上的脚本,网页可以从其他来源动态产生 JSON 资料。用 JSONP 获取的不是 JSON 数据,而是可以直接运行的 JavaScript 语句。
json数据被封装在回调函数里,就是所谓的json with padding(json填充)
我们通常会直接用jquery的jsonp的解决方案,用法如下:
|
|
最终发出的url是这样的
|
|
但实际上它是做了一层封装,会有点误导。返回的实际上还是javascript语句,jquery进行了解析,正确时会调用success,同时把里面的数据存为上面的serverData。让你看起来jsonp跟普通的ajax请求没有任何区别。
实际上如果自己实现的话,应该是这样的:
server1 请求页面有一个script标签
|
|
或者在代码里手动createElement(“script”),然后设置src后append到head中。
|
|
|
|
可以看出,服务端返回的应该是一段立即执行的js代码。
4.3 优缺点
- 优点:解析快+解决跨域。jsonp中,由于数据是被当成原生的javascript,因此解析和原生的一样快,所以数据传输时,时间(下载+解析)中的解析部分几乎为0
- 缺点(动态脚本注入引起的):
- 不安全
- 只能get请求
- 不能设置请求的头信息,也就不能设缓存。也不可以访问请求的头信息
- 不能失败处理
- 需要等到所有数据返回才可以访问
针对jsonp不能支持post等请求的问题,解决方案是cors(Cross-Origin Resource Sharing)
主要是服务器对响应头进行了处理
|
|
reference:前端跨域请求原理及实践
===2016/11/20更新
本次更新是针对jsonp不能post的问题。之前我们说了可以用cors,这个楼主还没有试过。楼主这次是用前端代理的方法,本质是本地请求本地服务器,本地服务器去做转发,服务器间的转发是没有跨域这个概念的。因此可以解决,而这种方法下,服务端实际上不需要像cors那样进行变更。(场景是,本地开发需要访问另一个域名下的数据)。
具体方法是:
- vue-cli中,是使用了http-proxy-middleware的中间件(node-http-proxy)进行处理,如下
1234567
proxyTable: { '/ip/serverInfo': { target: 'https://cnodejs.org', //origin,域名部分 pathRewrite:{'^/ip/serverInfo': '/api/v1/topics'}, changeOrigin: true },},
- webpack中有专门的配置,其实也是利用的http-proxy-middleware
123456789
// In webpack.config.js{ devServer: { proxy: { '/api': { target: 'https://other-server.example.com', secure: false } }
5. 即时搜索
监听v-model变化,每次变动就取消上一次请求。当超过500ms的时候就发送搜索请求。
1234567
watch: { searchInput(newValue, oldValue){ clearTimeout(timer); if(newValue.trim() !==oldValue.trim()) timer = setTimeout(this.fetchKeywordList,500); } },
6. cookie.js代码赏析
|
|
demo:
var arr = [{“id”:3,”zh_name”:”test”},{“id”:5,”zh_name”:””lili}]
结果:Object {3: “test”, 5: “lili”}
|
|