介绍
JavaScript是其于原型、面向对象、弱类型的动态脚本语言。它从函数式语言中借鉴了一引强大的特性,如闭包和高阶函数,这也是JavaSccript语言本身有意思的地方。
从技术层面上来说,JavaScript是根据ECMAScript语言标准来实现的。这里有一点非常重要:由于Node使用了V8引擎的原因,其实现很接近标准,另外,它还提供了一些标准之外实用的附加功能。换句话说,在Node中书写的JavaScript和浏览器上口碑不是很好的JavaScript有着重要的不同。
另外 ,Node中你书写的绝大多数JavaScript代码都符合Douglas Crockford在他那本著名的书<JavaScript语言精粹>中JavaScript语言的’精粹’。
本单分为以下两个部分:
- JavaScript基础。语言基础。适用于:Node、浏览器以及语言标准
- V8中的JavaScript。V8提供的一些特性是液晶和器不支持的,IE就更不用说了,因为这些特性是最近才纳入标准的。除此之外,V8还提供了一些非标准的特性,它们能辅助解决一些觉的基本需求。
#JavaScript基础
##类型
JavaScript简单的分为基本类型和复杂类型。访问基本类型时访问的是值,访问复杂类型时访问的是对值的引用 - 基本类型包括number、boolean、string、null、undefined。
- 复杂类型包括array、function、object。
如下所示
//基本类型
var a = 5
var b = a
b = 6
a // 结果为5
b // 结果为6
// 复杂类型
var a = ['hello', 'world']
var b = a
b[0] = 'byte'
a[0] // 结果为 'byte'
b[0] // 结果为 'byte'
上述例子第二部分,b和a包括了对值的相同引用。因此,当通过b修改数组的第一个元素时,a相应的值也更改了,也就是说a[0]==b[0]
##类型的困惑
要在JavaScript中准确无误的判断变量值的类型并非易事。
因为对于绝大部分基本类型来说,JavaScript与其他面向对象语言一样有相应的构造器,比如说你可以通过以下两种方式来创建一个字符器:
var a = 'woot'
var b = new String('woot')
a + b // 'woot woot'
然而要对这两个变量使用typeof和instanceof操作符,事情 就变得有意思了
typeof a // string
typeofb // object
a instanceof String // false
b instanceof String // true
而事实上,两个都是货真价实的字符串
a.substr == b.substr
并且 使用 == 操作符判定两者相等,而使用 === 两都不相等
考虑到有此差异,我建议你始终通过直观的方式进行定义,避免使用new
有一点很重要,在条件表达式中,一些特定的值 被判断为false:null、undefined、’ '、0
var a = 0
if(a){
//这里不会被执行
}
a == false // true
a === false // false
另外 值得注意的是:typeof不会把null识别为null
typeof null == 'object' // 很不幸,结果为true
数组也不例外,就算是通过[]这种 方式定义的数组也是如此
typeof [] == 'obejct' //true
这里要感谢V8给我们提供了判定数组类型的方式,能够使我们免于使用hack的方式。
在浏览器环境中,我们通常要查看对象内部[[Class]]值:Object.prototype.toString.call([]) == ’ [object Array]’。该值是不可变的,有利于我们在不同的上下文中(如浏览器窗口)对数据类型进行判定,而instanceof Affay这种方式只适用于与数据初始化在相同上下文中才有效
函数
JavaScript中,函数最为重要。
它们都属于一等函数:可以作为引用存储在变量中,随后可以像其他对象一样,进行传递:
> var a = function(){}
> console.log(a) // 将函数作为参数传递
[Function: a] //执行结果
> typeof a
'function'
> a.name
'a'
JavaScript中所有的函数都可以进行命名。有一点很重要,就是要能区分出函数名和变量名。
this、function.call 以及function.apply
function a(){
window == this; //true
}
a();
调用以下函数时,使用.call和.apply方法可以改变this的值:
function a(){
return this.a == 'b'
}
a.call({a:'b'})
call和appy的区别在于,call接受参数列表,而apply方法接受一个参数数组:
function a(b, c){
return b == 'first' && c == 'second'
}
a.call({a:'b'},'first', 'second')
a.apply({a:'b'},['first', 'second'])
call与apply的第一个参数用作this 对象如下所示
function.call(obj, ...)
function.apply(obj, [...])
这种用法类似于python中传递self,call与apply可以在第一个参数中传递任何对象
##函数的参数数量
函数有一个很有意思的属性——参数数量,该属性指明函数声明时可接受的参数数量,该属性名为length
var a = function(a, b, b);
a.length == 3 // true
尽管这在浏览器端很少使用,但是,它对我们非常重要,一些流行的Node.js框架就是通过此属性来根据不同参数个数提供不同的功能的。
##闭包
在JavaScript中,每次调用新的函数,就会产生新的作用域。
在某个作用域中定义的变量只能在该作用域或其内部作用域(该作用域中定义的作用域)中才能访问到:
var a = 5;
function woot(){
a == 5 // false
var a = 6;
function test(){a == 6;} // true
test()
}
woot()
自执行函数
自执行函数是一种机制,通过这种机制声明和调用一个匿名函数,能够达到仅定义一个新作用域的作用。
var a = 3
(function() {var a = 5})()
a==3 //true
自执行函数对于声明私有变量很有用,可以让私有变量不被其他代码访问。
https://www.processon.com/i/568c6ea4e4b0e51d149a085f
这个网站解决了大家开始设计阶段的问题,轻量级的各种设计模型,强烈推荐