@lizlalala
2016-11-20T14:52:28.000000Z
字数 5799
阅读 1374
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); //undefined
a = 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 object
console.log(this.value); // undefined
console.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 callback
element.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.jsonp
console.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-Origin
res.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;
},{})