Wayne Wang Stay Curious

从C++到JavaScript切换的初体验

Feb. 05, 2015 - Shang Hai

作为一个典型的C++开发者,当第一次接触JavaScript时,那是各种的不适应。这种不适主要是因为JavaScript的动态语言特性(”dynamic + prototype” OOP)和C++的静态语言表达(”static + class” OOP)完全不同。因此,当以C++的编程方式来考虑JavaScript程序时,便发现有太多观念需要转变。比如,

  1. JavaScript是建立在弱类型(weak type)基础上的,到处都是var关键字的使用。习惯了C++的强类型,总是在使用一个Javascript对象时感到别扭。因为,在真正运行前,都不确定对该对象的属性或方法的调用是否正确。
  2. JavaScript的自定义“类型”以及对象都是动态可变的,完全自由,其行为完全看调用者如何使用。对象的属性或方法可以随意的被删减或增加,甚至对象的原型链也可以被改变。
  3. 当通过new来构建一个对象时,并不需要匹配的delete来释放资源。JavaScript有自己的垃圾回收机制来管理内存(an unreachable object will be garbage collectable),而C++则要求使用者来管理资源。但自动垃圾回收并不代表可以完全不用在意JavaScript内存的使用,使用者依然需要非常小心JavaScript对象的引用,否则也有可能出现不在使用的对象却依然被引用着。
  4. JavaScript函数里的“This”属性会随着调用者的不同而变化,这是初学者很容易搞混的一个值。尤其在对不同对象显示调用函数,定义Closures,使用Callback函数时尤其需要注意正确的使用this。
  5. JavaScript没有函数重载以及运算符重载的语言特性,所以以C++的考虑方式来设计对象时,就发现在JavaScript里行不通了。比如,比较两个对象是否相等,通常C++的做法会重载该对象的==操作符,然后调用起来就很直观。但JavaScript里,直接对比两个变量是否相等,只是检测二者是否指向了同一个对象,如果要比较相同“类“的两个不同实例之间对应值是否相等,就需要显示的定义一个equal的方法,使用时像这样调用obj1.equal(obj2)。
  6. 函数在JavaScript里有着更广的概念,除了是一个与C++类似的特定操作或计算的封装,它还是一个对象并提供内置的方法,还是一个构造器用来构造其他对象。因此,JavaScript的函数使用也是多种多样,比如,和C++不同的是,函数可以直接定义在另一个函数体内,并可作为返回值;函数还可以在定义时候便可立即被调用。还有值得一提的是,以callback函数为基础的异步调用在JavaScript中相当常见,比如Ajax, 鼠标事件, 还有timer。
  7. 另外,JavaScript的执行是单线程的,没有C++中的多线程的概念。不过经常JavaScript的异步事件的使用,会不小心误认为是多线程的一种实现,但实际却不是。异步事件的调用都是会在当前执行上下文中排队等待一个个去执行的。不过,自从HTML5中引入了web worker的概念后,便可以实现类似多线程的应用,方法是创建一个后台运行的web worker来执行耗时的操作,并通过message在worker和host之间传递消息。
  8. JavaScript始终有一个global object和global scope,但并没有一个特定的运行入口点,像C++程序的main入口。
  9. 所有JavaScript对象都有其对应的原型,并通过由解析器自动生成的__proto__属性来访问。并且,原型的改变将会影响由该原型生成出的所有对象。
  10. 静态语言编程中,断言的使用对于调试来说很重要,但在JavaScript里似乎断言的功用便没有那么重要。(对此我还不确定,需要进一步了解。)
  11. 用Sublime Text来写JavaScript程序,第一感觉是没有C++ IDE提供的Intellisense以及错误检查带来的方便。总是要在web里实际运行code时候,才发现有不少的拼写,对象使用或者语法错误。
  12. JavaScript作为一种OOP的语言,虽然在概念上和C++都是基本一致的,但具体使用它来设计程序时,在实现上却是有很大的不同,包括一些设计模式。(只有在实践中,才能更好的理解那些设计模式,进一步灵活运用设计模式便可以写出漂亮的程序)

等有其他感受时,就再补充了。先到这里。

Fork me on GitHub