踩中文的坑

如标题所示,这次笔记一个工作中遇到的小坑,虽说小却楞是花了我几大小时的时间。当时的背景是这样的,我需要在客户端这边发送一个http的POST请求,然后服务器根据请求执行相应的db操作。代码类似下面这样子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
var http = require('http');

var bookBody = {
"title": "黑客与画家",
"price":9.89
}

var bookBodyString = JSON.stringify(bookBody);
var options = {
host: 'localhost',
port:'3000',
path: '/books',
method: 'POST',
headers: {
'Accept': '/',
'Content-Type':'application/json',
'Content-Length': bookBodyString.length
}
};

var req = http.request(options, function(res) {
res.setEncoding('utf8');
res.on('data', function(data) {
console.log(data);
});

res.on('err',function(data){
console.log(data);
});
});


req.write(bookBodyString);
req.end();`

结果代码执行过后,对方的服务器给挂掉了,当然我这边也就没有响应到正确的数据,服务器报出了语法的错,类似‘无法解析的结尾’。当时我就在想,这部分的请求代码是我直接拷过来的(话说直接拷代码是非常‘危险’的动作),拷的这部分代码在之前是成功执行的,只是我这边稍微改了一下,难不成是因为这次改动的原因,然后我回滚代码,让它几乎保持了与拷贝之前一致性,接着再执行,晕~依然崩溃。仔细对比了代码,发现剩下不同的就只有新的代码里面消息体包含了中文。于是换成英文再执行,OK。那依这样看是不是就是该服务端的问题呢,即对方在接收数据时没有做正确的处理,或者没有做中文编码之类的处理。于是,我把这个问题反馈给了作者,这篇的6楼是我的反馈记录。大家可以看看。

那从上面的链接我们可以牢记一个点是,在请求的头部,content-length它表示的是所在消息体的字节数而不是字符个数,明白这个道理的话就释然了

谈谈js中的作用域

如果有过其他高级语言‘块级作用域’的认知,那么再接触js的函数作用域后就会大跌眼镜。个人认为应该在这几个方面着重关注一下:作用域、作用域链、变量提升。

先看作用域,js是没有块作用域的说法的(不过现在ES6的let关键字已经支持了),用网络上其他的例子作说明:

1
2
3
4
5
6
var name="global";
if(true){
var name="local";
console.log(name)//local
}
console.log(name);//local

上面的输出都为local,如果不是函数作用域而是块作用域的话,输出应该依次是local和global。所以,以上代码证明了开始的观点。这里一定要注意函数作用域这个关键点哦!

Read More

多么痛的领悟之闭包小结

“闭包”,一个快被讲烂了的知识点,以至坊间流传着一种说法,不识闭包的人就不能谈精通js。好吧,虽然现在大部分时间在写node后端,极少用到闭包,但是为了以后写前端js真正遇到闭包特性时,不必乍慌~

关于什么是闭包的定义,官网上的解释有点晦涩,参考了网上一大圈解释,选了几个易懂的方便理解:第一个,
闭包就是能够读取其他函数内部变量的函数。第二个,可能要长点:2.1闭包就是函数的局部变量集合,只是这些局部变量在函数返回后会继续存在;2.2闭包就是就是函数的“堆栈”在函数返回后并不释放,我们也可以理解为这些函数堆栈并不在栈上分配而是在堆上分配;2.3当在一个函数内定义另外一个函数就会产生闭包。

Read More

判断对象内容是否为空

如题所说的判断对象为空指的是其里面是否有其属性和对应的值,而不是像以前普通的判断非空方法,如下:

1
2
3
4
5
6
7
8
var x;
if (typeOf(x) == "undefined")
if (typeOf(x) != "object")
if (!x)

//亦或是下面这种
if(x === null)
if(x === '')

现在的情况是x是一个已经定义了的对象,但里面没有任何属性,所以如果再向上面的那些判断方式的话,是会出问题的,可以参考下面的方式:

1
2
3
4
5
6
7
8
9
10
11
12
13
var voteObject = {"ds":1};
//var voteObject = {};
var hasProp;

for (var prop in voteObject){
hasProp = true;
break;
}
if (hasProp){
console.log('对象里有属性');
}else{
console.error('对象里面为空');
}

Read More

什么是js中的自执行

之前node的时候用了人家封装的库,调进去看了一下,遇到下面这种类似代码:

1
(function(name){console.log(name)})('fengyun');

当时就在想这都什么玩意儿,我书读的少,写js不久,不要‘骗’我!以前没见过这种写法,于是百度之,才知道这是js里面的匿名函数自执行。这里面提到了两个关键字,一个是匿名函数,一个是自执行。

匿名函数简单来说就是没有名字的函数,不能其单独使用;

自执行就是函数在定义的时候就立即执行;

概念都好理解,举个例效果更好:

1
2
3
4
5
6
7
function say(){
console.log('我是一般函数')
}

function(){
console.log('我是匿名函数')
}

上面代码中第二个函数表示的就是一个最简单的匿名函数,也没有参数。重点的是,它没办法调用运行的,因为它连名字都没有,怎么调?所以如果我们需要使用它,我们可以这么做:

Read More