@lizlalala
2016-11-20T06:52:28.000000Z
字数 5799
阅读 1593
magazine 前端周刊 奇舞
这边的笔记主要记载自己看周刊或者不错的文章中的一些good points,或者一些需要注意的点,当然里面肯定有楼主自己的理解啦:)
const var let区别
var 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只能在声明时初始化,它表示它所代表的引用(可以认为是指针)是不可变的,所指向的内容实际是可以变的。如
const a = {};a['b'] = 1;const b = [];b.push(1)
三者都会变量提升(hoist),只是var提升时会默认设置初始值 undefined,而let,const不会。
因此,如果在声明时没有初始化,然后就去访问值的话,var会报出undefined,而let,const会抛出ReferenceError
//类似于介个样子var a;console.log("a",a); //undefineda = 3;
this 总结
最近写ife的task的时候遇到这么一个问题,
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里面有讲解过,好不容易翻出来一点,回忆一下。
还有这样的栗子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);}
************这是一条栗子分割线start*********************
除此之外,还有一个栗子需要特别注意,对照着看b,d两条。
var element = document.getElementById('element');var user = {firstname: 'Bob',greeting: function(){alert('My name is ' + this.firstname);}};user.greeting(); // attention1: My name is Bob// Attach user.greeting as a callbackelement.addEventListener('click', user.greeting);// attention2: My name is undefined
attention1处符合b的规则,而attention2中,则实际上是因为:事件绑定函数时,会以当前元素为作用域执行。
(虽然楼主最开始以为是把user.greeting函数赋给一个匿名回调函数,function(){} = user.greeting.因此在触发它的时候this其实是丢失了的)。不过测试了下,貌似确实是把this绑在了元素上的。具体看codepen里面this.nodeName。
关于这个问题的解决方案有两种:
包裹在另一个匿名函数中
element.addEventListener('click', function(){user.greeting()});
bind user
element.addEventListener('click', user.greeting.bind(user));//或者一步到位:user.greeting = user.greeting.bind(user);element.addEventListener('click', user.greeting);
************这是一条栗子分割线 end*********************
具体的解决方案有三种:
中文正则
/\u4E00-\u9FA5/
跨域总结
在公司开发的过程中其实也遇到过这个问题,是像另一个服务器post请求,是的,坑有两个,一个是跨域,一个是用jsonp解决跨域后发现要用post =。=。但是当时时间紧迫,后端同学不是很会配置,就粗暴的都用jsonp+get解决了
场景:同源策略,出于防范跨站脚本的攻击,禁止客户端脚本(如 JavaScript)对不同域的服务进行跨站调用。跨站调用主要指,只要网站的
这三个中的任意一个不同,网站间的数据请求与传输(ajax请求)便构成了跨域调用。
而用script标签请求和解析则可以正常运作。
有一点需要注意的是,跨域请求并非是浏览器限制了发起跨站请求,而是请求可以正常发起,到达服务器端,但是服务器返回的结果会被浏览器拦截。
更直白一点的解释就是,以钓鱼网站(get服务器数据)为例。ta0bao.com,用户提交信息,那么黑客会发送ajax到taobao.com,然后taobao那边的服务器返回数据,如果没有同源策略的话,这个数据就会被获取到。但是有了同源策略,浏览器那边可以得到这个数据,但是黑客在代码里是得不到的。被浏览器拦截了,就不给你就不给你=。=。
同源只能限制不被获取数据,但是发送其实是限制不了的。比如获取用户的私密信息。比如xss。黑客可以在用户提交信息(加上现在在a.com下)时发送两个ajax,一个给正常的网站(a.com),一个给自己的服务器(b.com)。这个是米有办法阻拦哒,要不然钓鱼网站也不会辣么猖狂...摊手。
这实际上也说明了跨域出现的原因及解决方案(用获取script代替ajax请求)
JSONP是 JSON 的一种使用模式,可以解决主流浏览器的跨域数据访问问题。其原理是根据 XmlHttpRequest 对象受到同源策略的影响,而 标签元素却不受同源策略影响,可以加载跨域服务器上的脚本,网页可以从其他来源动态产生 JSON 资料。用 JSONP 获取的不是 JSON 数据,而是可以直接运行的 JavaScript 语句。
json数据被封装在回调函数里,就是所谓的json with padding(json填充)
最终发出的url是这样的
requestDict["update"] = $.ajax({url: urls.update+encodeURIComponent(JSON.stringify(queriesObj)),type: "get",dataType: "jsonp",jsonp: "callback",jsonpCallback: "handleServerPolyData",//回调success: function(serverData) {},);
但实际上它是做了一层封装,会有点误导。返回的实际上还是javascript语句,jquery进行了解析,正确时会调用success,同时把里面的数据存为上面的serverData。让你看起来jsonp跟普通的ajax请求没有任何区别。 实际上如果自己实现的话,应该是这样的: server1 请求页面有一个script标签
http://bigdata.xiaojukeji.com/hotmap/getHeatmapOverlay?productLine=taxi?callback=handleServerHeatData?
或者在代码里手动createElement("script"),然后设置src后append到head中。
<script src = 'http://localhost:3001/jsonServerResponse?jsonp=jsonpCallback'></script>
//server1请求页面的js代码只有下面的回调function jsonpCallback(data) {console.log("jsonpCallback: "+data.name)}
可以看出,服务端返回的应该是一段立即执行的js代码。
// server2处理请求app.get('/jsonServerResponse', function(req, res) {var cb = req.query.jsonpconsole.log(cb)var data = 'var data = {' + 'name: $("#name").val() + " - server 3001 jsonp process",' + 'id: $("#id").val() + " - server 3001 jsonp process"' + '};'var debug = 'console.log(data);'var callback = '$("#submit").click(function() {' + data + cb + '(data);' + debug + '});'res.send(callback)res.end()})
针对jsonp不能支持post等请求的问题,解决方案是cors(Cross-Origin Resource Sharing)
主要是服务器对响应头进行了处理
//Access-Control-Allow-Originres.header("Access-Control-Allow-Origin", "*");res.header("Access-Control-Allow-Headers", "X-Requested-With");res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
reference:前端跨域请求原理及实践
===2016/11/20更新
本次更新是针对jsonp不能post的问题。之前我们说了可以用cors,这个楼主还没有试过。楼主这次是用前端代理的方法,本质是本地请求本地服务器,本地服务器去做转发,服务器间的转发是没有跨域这个概念的。因此可以解决,而这种方法下,服务端实际上不需要像cors那样进行变更。(场景是,本地开发需要访问另一个域名下的数据)。
具体方法是:
vue-cli中,是使用了http-proxy-middleware的中间件(node-http-proxy)进行处理,如下
proxyTable: {'/ip/serverInfo': {target: 'https://cnodejs.org', //origin,域名部分pathRewrite:{'^/ip/serverInfo': '/api/v1/topics'},changeOrigin: true},},
// In webpack.config.js{devServer: {proxy: {'/api': {target: 'https://other-server.example.com',secure: false}}}}
即时搜索
监听v-model变化,每次变动就取消上一次请求。当超过500ms的时候就发送搜索请求。
watch: {searchInput(newValue, oldValue){clearTimeout(timer);if(newValue.trim() !==oldValue.trim())timer = setTimeout(this.fetchKeywordList,500);}},
var value = document.cookie.split(/;\s*/).map(opt.autoencode ? opt.decode : function (d) { return d; }).map(function (part) { return part.split('='); }).reduce(function (parts, part) {parts[part[0]] = part[1];return parts;}, {})[data];
demo:
var arr = [{"id":3,"zh_name":"test"},{"id":5,"zh_name":""lili}]
结果:Object {3: "test", 5: "lili"}
arr.reduce((prev,cur)=>{prev[cur["id"]] = cur["zh_name"];return prev;},{})