本人在大学时很是痴迷java,认为java就是世界上最好的语言,偶尔在项目中会用到一些javascript,但基本没放在眼里。较全面的接触javascript是在实习的时候,经过此次的了解发现,javascript实际上是一门很是优秀并且有意思的语言,从那时开始喜欢上了这门语言。javascript
javascript里面不少的概念和目前主流的语言是很是不同的,它更多的是继承了函数式编程语言的特色。虽然语言的初版的设计听说只花了七天时间,但其血统仍是挺好的。我的认为javascript之因此会经久不衰而且应用愈来愈普遍,和其血统是离不开的,它可能恰好触及到某些“本质”的东西。固然不是要鼓吹“javascript是世界上最好的语言”,javascript语言自己是有许多瑕疵的,这也是被许多人诟病的地方。它优秀的地方设计得很是好用,可以知足绝大多数的使用场景,一些小瑕疵只要稍加注意,并不会产生太大的影响。java
对于有必定编程经验的人来讲,第一次接触javascript必定会以为很是简单,会有似曾相识的感受,但若是轻视它,不去理解它的核心特色,必定会受到惩罚,让你一脸懵逼。本文就整理了几个核心的须要理解的知识点,但愿可以帮助有编程基础的初学者快速理解javascript。node
javascript数据类型设计得很是简单,总共只有6中,分别是boolean、string、number、undefined、object,function。通常将可以经过typeof运算符区分的归为一种数据类型。其中object,function为引用类型,剩下都为基本类型。javascript的数据类型虽然简单,但有几个地方须要特别注意一下。编程
number:
number类型底层采用双精度浮点数存储,可以表示整数,也能表示小数。因为这个缘由,number可以安全表示的整数范围是-9007199254740991 ~ 9007199254740991,超出则可能丢失精度。还好比0.1 + 0.2,其结果为:0.30000000000000004。number类型有个特殊值NaN,表示“不是个数字”,好比1/'a'就会返回NaN。后端
undefined:
这是一种很是特殊的数据类型,表示未赋值。变量或属性定义后未赋值就为undefined。这种数据类型用处很少,通常只是拿来区分有无赋值。安全
object:
object类型涵盖的东西很是广,Array,RegExp这些内置类型的对象也是object类型。null是一个很是特殊的对象,表示空对象,和undefined很像,只不过null是对象类型。闭包
function
函数虽然被当作一种数据类型,但其本质仍是一种特殊的对象,是从Object继承而来的。并发
我的认为,函数是javascript里面设计最巧妙的一个地方,许多有意思的特性都是围绕函数展开的,好比闭包和继承等。javascript里的函数仍是“一等公民”,可以做为参数传递、返回值返回,使用上极其灵活。
理解函数的执行首先要理解做用域的概念。在ES6以前,javascript里只有全局和函数做用域两种做用域,到ES6才引入了块级做用域。异步
函数在执行时会建立一个执行环境,push到执行栈的顶端,执行环境中就包含了当前函数的做用域。做用域包含了当前函数的局部变量以及内置的变量好比this,arguments。函数做用域是在运行时肯定的,非运行时讨论做用域是没有意义的。做用域是如何造成的?函数在定义时会有个[[scope]]的内部属性指向当时的做用域,一旦函数开始执行,它会建立一个新的做用域,而且用指针指向函数[[scope]]属性指向的内容,如此就造成了一条做用域链,做用域链的最外层是全局做用域。编程语言
做用域链的做用就是作标示符解析。函数在执行时遇到变量标示符解析的时,首先从当前做用域查找,找不到则一直沿着做用域链向上搜索。做用域链会造成一个很是有意思的特性,叫闭包。就是外层函数执行完了(栈帧已经弹出),若是内层函数对象还没被回收,外层做用域的变量环境会一直保留着,当内层函数执行的时候,依然能访问外层做用域的变量环境。
javascript是一门很是面向对象的语言,对象的建立和使用极其方便。面向对象的4个特性里面,封装性的体现略差一点,因为javascript是动态语言,讨论多态性意义也不是很大。我的认为面向对象主要是解决了两大问题,一是以一个符合现实世界观的方式组织抽象的代码,二是解决复用的问题。前者先不作多讨论,那是一种思惟方式和语言关系不大。后者在javascript里的实现是很是有意思的。
能够经过两个方法来解释对象的复用。假设有a、b两个对象,b对象但愿复用a对象的属性和方法。一种作法是将a对象中全部的内容拷贝到b对象,这是Object.assign方法的功能。这种作法虽然很朴实,可是在一些简单的复用场景是很是有用的。改方法的问题是会形成数据的冗余,关系复杂的时候维护起来就很困难。另外一种作法是在b对象中保留一个指向a对象的指针。当我在访问b对象的内容时,若是当前对象查不到,则沿着该指针继续搜索下去。这是Object.create方法能达到如此效果。Object.create本质是利用了javascript原型链的特性。如何构造原型链?必须利用函数的另一个角色——构造器。当把new 操做符用到函数之上时,函数就发挥着构造器的角色。经过构造器构造对象时,其首先会建立一个空对象,而后将对象的原型指向构造器的prototype属性,以此就能够造成原型链了。javascript里本质是没有类的概念,Es6引入的class关键字只是个语法糖,本质仍是经过原型链实现继承。
我的感受javascript里的继承更直接了当,直接从对象的角度去考虑复用,实际上是更接近现实的世界观。
javascript还有个明显的特色——单线程。javascript早期都是用做ui开发,单线程能够比较好当规避同步问题,下降了ui开发门槛。单线程须要解决的是效率问题,javascript里的解决思想是异步非阻塞。就是javascript主进程不要作耗时的事情,保证能快速执行快速相应,而将耗时的、io等待的事情交给其它进程去作。
在实现上javascript利用了一个事件循环和任务队列,事件循环会不断的检查任务队列有没有须要处理的任务,有则立刻取出处理,无则等待。进入一个调用栈时,对于io操做通常是要当即返回,而把后续要作的事情放到任务队列里,这样就不会形成io的阻塞。
正是单线程的特性,让javascript在后端开发领域也火了一把。nodeJs让javascript能够跑在服务端后,对并发的支持有本身独特的优点。
近些年javascript的应用愈来愈普遍,“任何可以用JavaScript实现的应用系统,最终都必将用JavaScript实现”的预言好像正在一步步变成现实。我的以为ES六、ES七、ES8将这门语言变复杂和臃肿了。ES3其实就将最重要的基石肯定了。javascript有这么强大的生命力,我的以为主要缘由是其简洁而强大,但愿后面不要变得太臃肿。