数字
Javascript只有一个数字类型。它在内部被表示为64位的浮点数,和Java的double数字类型一样。与其他大多数编程语言不同的是,它没有分离出整数类型,所有1和1.0的值相同。这提供来很大的方便,因为它完全避免来短整型的溢出问题,你只需要知道它是一种数字。这避免了一大堆因数字类型导致的错误。
如果一个数字字面量有指数部分,那么这个字面量的值等于e之前的数字与10的e之后数字的次方相乘。所以100和1e2是相同的数字
NaN是一个数值,它表示一个不能产生正常结果的运算结果。NaN不等于任何值,包括它自己。你可以用函数isNaN(number)检测NaN。
Infinity表示所有大于1.79769313486231570e+308的值。
字符串
字符串字面量可以被抱在一对单引号或双引号中,它可能包含0个或多个字符。(反斜线符号)是转义字符。JavaScript在被创建的时候,Unicode是一个16位的字符集,所以JavaScript中所有字符都是16位的。
转义字符用来把那些正常情况下不被允许的字符插入到字符串中,比如反斜线、引号和控制字符。u约定用来指定数字字符编码。
"A" === "\u0041"
其他
'c' + 'a' + 't' === 'cat' //true
相等操作符
String转换
当toString
不可用的时候,系统会再尝试valueOf方法
valueOf:function(){
console.log('调用了a.valueOf')
return {}
}
}
alert(a)
// 调用了a.toString
// 调用了a.valueOf
// Uncaught TypeErrpt: Cannot convert object to primitive value</code></pre>
Number转换
对象a+'edc'时会首先执行对象a的valueOf()方法
Boolean转换
布尔值 |
---|
JavaScript高级程序设计(第3版)[M]. p52
- 如果有一个操作数是
布尔值
,则在比较相等性之前先将其转换为数值
————false转换为0,而true转换为1; - 如果一个操作数是
字符串
,另一个操作数是数值
,在比较相等性之前先将字符串转换为数值
; - 如果一个操作数是
对象
,另一个操作数不是,则调用对象的valueOf()
方法,用得到的基本类型值
按照前面的规则进行比较; - 如果两个操作数都是
对象
,则比较它们是不是同一个对象。如果两个操作数都指向同一个对象,则true
值 | 表达式 | 值 | |
---|---|---|---|
由于相等与不相等操作符存在类型转换问题,而为了保持代码中数据类型的完整行,我们推荐使用全等和不全等操作符。
语法
下面列出的值被当作假(false)
- false
- null
- undefined
- 空字符串 ' '
- 数字 0
- 数字 NaN
其他所有的值都被当作真,包括true、字符串‘false’,以及所有的对象{},[]
删除
delete运算符可以用来删除对象的属性。如果对象包含该属性,那么该属性就会被溢出。它不会触及原型链中的任何对象。
删除对象的属性可能会让来自原型链中的属性透现出来:
var sub = {
name : 'bellic',__proto__ : sup
}
console.log(sub.name) //Bellic
delete sub.name
console.log(sub.name) //niko 来自原型链</code></pre>
减少全局变量污染
JavaScript可以很随意地定义全局变量来容纳你的应用的所有资源。遗憾的是,全局变量削弱来程序的灵活性,应该避免使用。
最小化使用全局变量的方法之一是为你的应用只创建一个唯一的全局变量:
var MYAPP = {}
该变量此时变成来你的应用的容器:
MYAPP.prop = {
"name" : "Niko","age" : 23
}
...
只要把全局性的资源都纳入一个名称空间之下,你的程序与其他应用程序、组件或类库之间发生冲突的可能性就会显著降低。你的程序也会变得更容易阅读。
闭包 也是另一种有效减少全局污染的方法。
方法调用模式
var obj = {
value : 0,method : function(arg){
console.log(arg + this.value)
}
}
//调用
obj.method("stooge")
函数调用模式
var obj = {
value : 1
}
obj.method = function(){
var that = this
return function(){
console.log(that.value)
}()
}
//调用
obj.method()
构造器调用模式
function Func(value){
this.value = value
}
Func.prototype.getValue = function(){
return this.value
}
//构造器调用
var f = new Func(123)
console.log(f.getValue()) //123
//apply调用
var obj = {
value : 456
}
var g= Func.prototype.getValue.apply(obj)
console.log(g) //456
Apply调用模式
var array = [3,4]
var sum = add.apply(null,array)
异常
throw
类似console.log主动打印,但throw语句会中断函数的执行
var add = function(a,b){
if(typeof a !== 'number' || typeof b !== 'number'){
throw {
name : 'typeError',message : 'add needs numbers'
}
}
return a + b
}
try catch
用来捕获throw打印的数据并以对象的形式返回
try{
add('Niko')
}catch(e){
document.writeln(e.name + ':' + e.message)
}
尾递归
尾递归是一种在函数的最后执行递归调用语句的特殊形式的递归。
什么是尾调用
指某个函数的最后一步是调用另一个函数(纯函数)。
function f(x){
return g(x)
}
function fibonacci(n,n1,n2){
if(n <= 1)return n2
return fibonacci(n,n2,n1+n2)
}
对象说明符
有时候,构造器要接受一大串参数。这可能令人烦恼,因为要记住参数的顺序非常困难。在这种情况下,如果我们在编写构造器时让它接受一个简单的对象说明符,可能会更加友好。那个对象包含了将要构建的对象规格说明。
所以,与其这样写:
var myObjecy = maker(f,l,m,c,s)
不如这么写:
var myObjecy = maker({
first: f,middle: m,last: l,state: s,city: c
})
现在多个参数可以按任何顺序排列
,如果构造器会聪明地使用默认值,一些参数可以忽略掉,并且代码也更容易阅读。