本文是我学习javascript的笔记,可以给使用c++的人学习js作一个参考。
鉴于工作需要和兼容性,所学习的javascript内容大部分来自于ES5版本。
javascript是什么
js(javascript)有和java相似的名字,常常让人误解二者的关系,其实它们根本没有什么关系,只是名字相似而已。
js是一门动态类型、基于原型的解释型语言(也可以即时编译),支持面向对象编程、命令式编程、函数式编程。
c++是一门静态类型检查的编译型语言。
js的语法和c语言比较相似,但又有许多根本性的不同(变量作用域、变量声明等);在ES6版本以后,js还借鉴了很多python、ruby的语法。
js主要用于构建网站等,而c++则是一门通用的程序设计语言,很多人拿它来做不同的事。
如何开发
运行环境
c++需要编译,Hello World需要编译,任何一个改动也需要重新编译;代码和可执行文件是分开的。
js因为是解释型语言,解释器是随手测试代码的利器,而且刚好浏览器又有js的解释器;于是你可以一边看网页,一边想写些东西验证一下时,按F12切换到控制台就可以写js了。
调试
调试程序最常用的2种方式是打印信息和断点调试。
c++中打印信息有多种方法,最基本的是标准流输出std::cout
js中有console.log()
可以在控制台输出信息,不过console的作用很丰富,输出类别、分类、计时、计数、调用堆栈等功能都有。
而调试程序的话,c++需要挂载调试器,一般会用IDE或者GDB终端调试。
js的话,一种是现代浏览器自带的调试器,或者是编辑器安装插件。
程序入口
c++兼容c语言,可执行的代码只能出现在函数内,而最开始的函数是main函数,全局区域是不能执行代码的。
js作用解释语言,是从头到尾连续执行的,没有这种限制。
不过可以将声明与执行的代码人为分开,提升程序可读性。
代码组织
c++因为编译顺序,声明尽量写在h文件中,定义写在cpp文件中;如果调用外部库,还有静态链接和动态链接的不同。
js中代码即程序,只要记住程序是从上往下解释的,在你的程序运行前,html中已经引入你需要的函数等就行了。
变量
数据类型
c++中有基本数据类型和用户自定义数据类型。
常用的基本数据类型有:bool, char, int, float, double, void, unsined int等等。
还允许用户利用基本数据类型来自定义数据类型,如struct X{…}等。
js有7种数据类型,分为原始类型和非原始类型。
原始类型:
- Boolean
- Null
- Undefined
- Number
- String
- Symbol(ES6)
非原始类型:
- Object
原始类型的值都是不可更改的,任何看似像更改的操作都会新创建一个新的值覆盖。
Number
js中只有一种数字类型Number,是双精度64位的浮点类型,并没有单独表示整数的整型。
可表示的错误取值有-Infinity
,+Infinity
,NaN
。
Number只有一个整数:0,可表示为+0和-0。
c++的浮点数错误值表示有NaN
和Inf
,c++中有多个函数可以判断此类情况,c++11中为isnan(Type x)
和isinf(Type x)
。
题外话:除零不是c++标准异常
String
字符串是js的原始类型之一,没有c++中char这种表示单字符的类型。
c++中字符串不是基本数据类型,是标准库中提供的。
js中字符串可以用双引号和单引号来表示。
c++中只双引号表字符串,单引号表字符char。
Undefined
js中变量没有初始化的话,默认值就是undefined
。
c++中未初始化的变量,其值是内存上的一个随机值(“赋值”在c++中和“初始化”是不同的操作,可见后文)。
Null 与 void
js中Null只有一个值null
,表空值。
c++中没有表示“空”的值,NULL
和nullptr
表空指针。
js中void是一个运算符,可以把表达式的返回值变为undifined
(这是js函数的默认返回值)。
c++中void函数没有返回值,而void*
可以去除类型。
枚举?
c++中枚举类型的主要作用是创建名称和值的关联,提升程序的可读性。
js中没有枚举类型。
常量
c++中可以用const
修饰符来限制类型,初始化后不可改变值。
js中原始类型是不能定义常量的,对象可以定义为常量。
ES6中有
const
关键字,可以定义常量。
变量声明
c++是静态类型检查的,类型名在前,变量名在后声明如:int i;
c++11虽然可以用auto
自动推导,但这只是可以在明确类型的情况下使用的,并不能auto i;
这种写法不能明确类型
静态类型的变量,指定类型后不可更改。
js是动态类型,即可以随时更改变量类型,所以指定变量类型也没什么意义,可以都用var
来声明变量:
var i;
i=1;
i='string';
i=true;
js中没有var声明的变量会是全局变量,即使在一个函数体内:
function f(){
a=1;
}
f();
console.log(a); // =>1
不要以上述方式定义全局变量,不便理解,且在ES5的严格模式下会有限制。
声明提升(Hoisting)
js会把所有变量的声明移动到作用域的开头位置。
js的变量可以在声明前使用。
因为js解释器的变量提升行为:
a=1;
var a=3;
等同于:
var a; // 作用域顶部
...
a=1;
a=3;
也因此重复声明是没有关系的,只是不建议为么做。
建议把所有变量的声明放在作用域顶部,这样更符合js的执行过程。