2014年3月28日星期五

阮一峰的网络日志

阮一峰的网络日志


undefined与null的区别

Posted: 27 Mar 2014 08:13 PM PDT

大多数计算机语言,有且仅有一个表示"无"的值,比如,C语言的NULL,Java语言的null,Python语言的none,Ruby语言的nil。

有点奇怪的是,JavaScript语言居然有两个表示"无"的值:undefined和null。这是为什么?

undefined vs. null

一、相似性

在JavaScript中,将一个变量赋值为undefined或null,老实说,几乎没区别。

 var a = undefined;  var a = null;  

上面代码中,a变量分别被赋值为undefined和null,这两种写法几乎等价。

undefined和null在if语句中,都会被自动转为false,相等运算符甚至直接报告两者相等。

 if (!undefined)      console.log('undefined is false'); // undefined is false  if (!null)      console.log('null is false'); // null is false  undefined == null // true  

上面代码说明,两者的行为是何等相似!

既然undefined和null的含义与用法都差不多,为什么要同时设置两个这样的值,这不是无端增加JavaScript的复杂度,令初学者困扰吗?Google公司开发的JavaScript语言的替代品Dart语言,就明确规定只有null,没有undefined!

二、历史原因

最近,我在读新书《Speaking JavaScript》时,意外发现了这个问题的答案!

原来,这与JavaScript的历史有关。1995年JavaScript诞生时,最初像Java一样,只设置了null作为表示"无"的值。

根据C语言的传统,null被设计成可以自动转为0。

 Number(null) // 0  5 + null // 5  

但是,JavaScript的设计者Brendan Eich,觉得这样做还不够,有两个原因。

首先,null像在Java里一样,被当成一个对象。

 typeof null // "object"  

但是,JavaScript的数据类型分成原始类型(primitive)和合成类型(complex)两大类,Brendan Eich觉得表示"无"的值最好不是对象。

其次,JavaScript的最初版本没有包括错误处理机制,发生数据类型不匹配时,往往是自动转换类型或者默默地失败。Brendan Eich觉得,如果null自动转为0,很不容易发现错误。

因此,Brendan Eich又设计了一个undefined。

三、最初设计

JavaScript的最初版本是这样区分的:null是一个表示"无"的对象,转为数值时为0;undefined是一个表示"无"的原始值,转为数值时为NaN。

 Number(undefined) // NaN  5 + undefined // NaN  

四、目前的用法

但是,上面这样的区分,在实践中很快就被证明不可行。目前,null和undefined基本是同义的,只有一些细微的差别。

null表示"没有对象",即该处不应该有值。典型用法是:

(1) 作为函数的参数,表示该函数的参数不是对象。

(2) 作为对象原型链的终点。

 Object.getPrototypeOf(Object.prototype) // null  

undefined表示"缺少值",就是此处应该有一个值,但是还没有定义。典型用法是:

(1)变量被声明了,但没有赋值时,就等于undefined。

(2) 调用函数时,应该提供的参数没有提供,该参数等于undefined。

(3)对象没有赋值的属性,该属性的值为undefined。

(4)函数没有返回值时,默认返回undefined。

 var i; i // undefined  function f(x){console.log(x)} f() // undefined  var  o = new Object(); o.p // undefined  var x = f(); x // undefined  

(完)

文档信息

2014年3月14日星期五

阮一峰的网络日志

阮一峰的网络日志


Linux服务器的初步配置流程

Posted: 13 Mar 2014 08:28 PM PDT

开发网站的时候,常常需要自己配置Linux服务器。

本文记录配置Linux服务器的初步流程,也就是系统安装完成后,下一步要做的事情。这主要是我自己的总结和备忘,如果有遗漏,欢迎大家补充。

下面的操作针对Debian/Ubuntu系统,其他Linux系统也类似,就是部分命令稍有不同。

第一步:root用户登录

首先,使用root用户登录远程主机(假定IP地址是128.199.209.242)。

 ssh root@128.199.209.242  

这时,命令行会出现警告,表示这是一个新的地址,存在安全风险。键入yes,表示接受。然后,就应该可以顺利登入远程主机。

接着,修改root用户的密码。

 passwd  

第二步:新建用户

首先,添加一个用户组(这里假定为admin用户组)。

 addgroup admin  

然后,添加一个新用户(假定为bill)。

 useradd -d /home/bill -s /bin/bash -m bill   

上面命令中,参数d指定用户的主目录,参数s指定用户的shell,参数m表示如果该目录不存在,则创建该目录。

接着,设置新用户的密码。

 passwd bill   

将新用户(bill)添加到用户组(admin)。

 usermod -a -G admin bill   

接着,为新用户设定sudo权限。

 visudo   

visudo命令会打开sudo设置文件/etc/sudoers,找到下面这一行。

 root    ALL=(ALL:ALL) ALL  

在这一行的下面,再添加一行。

 root    ALL=(ALL:ALL) ALL bill    ALL=(ALL) NOPASSWD: ALL  

上面的NOPASSWD表示,切换sudo的时候,不需要输入密码,我喜欢这样比较省事。如果出于安全考虑,也可以强制要求输入密码。

 root    ALL=(ALL:ALL) ALL bill    ALL=(ALL:ALL) ALL  

然后,先退出root用户的登录,再用新用户的身份登录,检查到这一步为止,是否一切正常。

 exit ssh bill@128.199.209.242  

第三步:SSH设置

首先,确定本机有SSH公钥(一般是文件~/.ssh/id_rsa.pub),如果没有的话,使用ssh-keygen命令生成一个(可参考我写的SSH教程)。

在本机上另开一个shell窗口,将本机的公钥拷贝到服务器的authorized_keys文件。

 cat ~/.ssh/id_rsa.pub | ssh bill@128.199.209.242 'mkdir -p .ssh && cat - >> ~/.ssh/authorized_keys'  # 或者在服务器端,运行下面命令  echo "ssh-rsa [your public key]" > ~/.ssh/authorized_keys  

然后,进入服务器,编辑SSH配置文件/etc/ssh/sshd_config。

 sudo cp /etc/ssh/sshd_config ~ sudo nano /etc/ssh/sshd_config  

在配置文件中,将SSH的默认端口22改掉,可以改成从1025到65536之间的任意一个整数(这里假定为25000)。

 Port 25000  

然后,检查几个设置是否设成下面这样,确保去除前面的#号。

 Protocol 2  PermitRootLogin no PermitEmptyPasswords no PasswordAuthentication no  RSAAuthentication yes PubkeyAuthentication yes AuthorizedKeysFile .ssh/authorized_keys  UseDNS no  

上面主要是禁止root用户登录,以及禁止用密码方式登录。

接着,在配置文件的末尾,指定允许登陆的用户。

 AllowUsers bill  

保存后,退出文件编辑。

接着,改变authorized_keys文件的权限。

 sudo chmod 600 ~/.ssh/authorized_keys && chmod 700 ~/.ssh/  

然后,重启SSHD。

 sudo service ssh restart  # 或者  sudo /etc/init.d/ssh restart  

下面的一步是可选的。在本机~/.ssh文件夹下创建config文件,内容如下。

 Host s1 HostName 128.199.209.242 User bill Port 25000  

最后,在本机另开一个shell窗口,测试SSH能否顺利登录。

 ssh s1  

第四步:运行环境配置

首先,检查服务器的区域设置。

 locale  

如果结果不是en_US.UTF-8,建议都设成它。

 sudo locale-gen en_US en_US.UTF-8 en_CA.UTF-8 sudo dpkg-reconfigure locales  

然后,更新软件。

 sudo apt-get update sudo apt-get upgrade  

最后,再根据需要,做一些安全设置,比如搭建防火墙,关闭HTTP、HTTPs、SSH以外的端口,再比如安装Fail2Ban,详细可参考这篇《Securing a Linux Server》

(完)

文档信息