JavaScript 学习笔记

来源:互联网 发布:阳光下的星星 知乎 编辑:程序博客网 时间:2024/05/17 22:28

 无穷大值:Number.POSITIVE_INFINITY,Number.NEGATIVE_INFINITY

var i = Number.POSITIVE_INFINITY;
alert("if i is finite:" + isFinite(i) + ", i=" + i);

输出:if i is finite:false, i=Infinity

NaN表示非数,一般来说,这种情况发生在类型转换失败时。不能用于算术计算,且与自身不相等。
alert(NaN==NaN);
alert("isNaN(NaN)="+isNaN(NaN));
alert("isNaN(abc)="+isNaN("abc"));
alert("isNaN(123)="+isNaN("123"));

输出:
false
isNaN(NaN)=true
isNaN(abc)=true
isNaN(123)=false

parseInt、parseFloat将string转换成整数或浮点数。
var num = parseInt("0xA"); // 返回10

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

 

 

 

 

 

 

Javascript Number 类
 

Number 类是Number 原始类型的引用类型。
创建Number对象:var oNumberObject = new Number(33);

Number 类的方法:
oNumberObject.valueOf()——获得数字对象的Number原始值。
oNumberObject.toFixed()——返回指定位数小数的数字的字符串表示。(new Number(33)).toFixed(3); // outputs "33.000"
oNumberObject.toExponential()——返回用科学记数法表示的数字的字符串形式。(new Number(33)).toExponential(3) //outputs "3.300e+1"
oNumberObject.toPrecision()——
根据最有意义的形式来返回数字的预定形式或指数形式。
它有一个参数,用于表示数的数字总数。
Example:
(new Number(33)).toPrecision(1) // outputs "3e+1"
(new Number(33)).toPrecision(2) // outputs "33"
(new Number(33)).toPrecision(3) // outputs "33.0"
(new Number(33)).toPrecision(4) // outputs "33.00"
toFixed()、toExponential()、toPrecision()方法都会进行舍入操作,以便用正确的小数位数正确地表示一个数。

 

 

 

 

 

 

1. JavaScript使用Unicode编码。大小写敏感。

2. JavaScript的注释与Java一致。
//.....        
/*.........
...............*/

3. JavaScript的标识符(identifier,用于变量名与函数名)可以包含字母、数字、下划线_、美元符$,其中数字不能为首位,以便解释器做语法分析时可以比较容易的判断出数值类型。
JavaScript标识符可以包含任意Unicode规范认为是字母或数字的字符,例如汉字: 
    var 功夫='降龙十八掌';
    function 打他一掌() { ... }
试验了一下发现Java也是可以用中文作为标识符的!我孤陋寡闻了。

4. JavaScript语句尾的分号是可以省略的。

5. JavaScript类型(type)可分为原始类型(primitive type)与对象类型两大类。原始类型又分为数值(number),字符串(string),布尔值(boolean),undefined 与 null。
对前4种原始类型进行 typeof 运算可得到相应的字符串值'number'、'string'、'boolean' 与 'undefined',而 null 的 typeof 运算结果是 'object'。例如 typeof 12 值为 'number',typeof '12' 值为 'string'。

6. JavaScript并不区分整型与浮点型数值,内部一律用浮点数表示。
1)浮点数存在计算精度问题,例如表达式 0.3-0.2==0.1 的值是 false,而0.2-01==0.1 的值为 true。
2)由于都是浮点数,所以不同于Java,3/2的值为1.5而不是1。同时求模运算可以对小数进行,如3.2%1.1的值为1(注意,一样存在小数精度问题)。
3)不同于Java,JavaScript对上溢、下溢与除零操作并不抛出异常,而是引入了Infinity与NaN这两个全局变量来处理。Infinity表示无穷大,-Infinity表示负无穷大,0(-0)可表示无穷小,NaN表示不是数值。例如:

上溢: Math.pow(2,5000) = Infinity  结果值超出IEEE浮点数规范能表示的最大数值
下溢: 2e-200 / 4e200 = 0  结果值小于IEEE浮点数规范能表示的最小数值
除零: -23 / 0 = -Infinity  可认为是常数除无穷小,值为无穷大
0 / -0 = NaN  可认为是两个无穷小相除,值不定,故为NaN
Infinity / Infinity = NaN
Infinity * 0 = NaN

Infinity参与运算时依然可以用极限理论解释: 
Infinity +(-,*,/) 45 = Infinity
8 % Infinity = 8
8 / Infinity = 0
0 / Infinity = 0
Infinity - Infinity = NaN
Infinity + Infinity = Infinity

4)NaN(Not a Number)还会出现在当某操作符需要把一个其他类型的值转化为数值但又转化失败时,如 34+'七百'=NaN。
NaN有个牛逼的属性:NaN==NaN 永远返回 false!例如 0/0==NaN 值为false。必须用isNaN() 函数做精确的判断(其实 !NaN==true 啦)。

5)0与-0对于运算结果是有影响的,但是0==-0值为true,甚至0===-0值也为true,而Infinity==-Infinity值为false。
PS:==是比较符,===是精确比较,要求类型也要一致,例如2=='2'为true,而2==='2'为false;null==undefined为true,null===undefined为false。!=与!==也有类似区别。

6)Infinity与NaN是全局变量,在ECMAScript3规范中是可以重新赋值的(汗)
    Infinity=4; 
    var a=Infinity+4; 
    alert(a);  //8  
    alert(4/0 + 1);  //Infinity
求高人解释:为什么4/0的值不是修改过后的Infinity的值4而是Infinity?

7. string可以通过双引号或单引号指明。
同Java,string在JS中也是不可变的,String对象的各种函数都会返回一个新的string。

8. JS中所有的值都能转化为boolean值。以下值转化后值为false:
undefined、null、0、-0、NaN、''(空字符串)
注意:'false' 转化为boolean后值为ture!

9. null与undefined都指没有定义值。
大致可以这样理解:null可以看成一个已经分配存储空间的特殊对象(指针),而undefined没有分配存储空间。所以sizeof null的值为'object'。
    var a=null;  // a的值为null
    var b;  // b的值为undefined
    function f(x, y) { ... }  // 函数f的返回值为undefined。无指定return type的函数都返回undefined
    f(a);  // 函数f中参数y的值为undefined
    var c=[1,2];  // c[3]的值为undefined
null是JS的关键字;undefined与NaN一样,是全局变量。

10. 全局对象(Global Object)
JavaScript启动时(或浏览器加载一个页面时),JavaScript解释器会自动创建一个新的全局对象并设置其属性。
在top-level代码中(所有函数的外面)可以得到全局对象:
    var global = this;
top-level代码中申明的变量(全局变量)都将成为全局对象的属性。

11. 与Java一样,原始类型与引用类型(如对象)的区别是:
1)是否可变
2)是否是按值比较

12. JavaScript是弱类型语言,变量没有类型的区别。
申明变量使用关键字var
    var i ; // 申明变量i,但是没有赋值,值为undefined
    var j = 4; // 变量申明并赋初值
变量必须申明过后才可以使用。
    var k = m + 4; // 错误!m没有申明

JS中允许不使用var关键字定义变量,这些变量自动变为全局变量。
    function f() {
        var a = 1; // 定义了局部变量a
        b = 2; // 定义了全局变量b。不同于使用var定义的变量,该变量是configurable的,可以被delete。
        a+b; // 值为3
    }

13. 变量范围
JavaScript的变量范围只受函数块的影响,全局变量可在任何地方访问,函数中定义的局部变量可在该函数及其内部定义的函数中调用(JS函数中可以定义新的函数)。JS变量范围不受其他块的影响。如:
    if(true) { var a = 4;}
    var b = a+4; // OK, b的值为8

JS中变量申明可视为永远发生在函数的最上部,所以以下代码正确:
    function f() {
        alert(b); // 不会出现‘b没有申明’的错误,不过值为undefined,即只有变量申明是被提到了函数最前面。
        var b=4;
    }
求解惑:JS不是解释性语言吗?为啥会这样?

14. 范围链(Scope Chain)
范围链是一个很重要的概念,可以理解为一个对象列表,该列表中每个对象都有自己的属性。当我们需要找一个指定名称的属性时,从列表中的第一个对象开始寻找这个指定属性,如果没有就去列表中的下一个对象寻找,直到找到指定属性(成功)或因无法找到而结束(失败,抛ReferenceError异常)
列表中的对象可以认为是call object对象。ECMAScript规范规定了全局变量是全局对象的属性。我们可以将局部变量(包括参数)看成是call object对象的属性。call object与函数调用有关,当函数被调用时会创建出一个cal object对象。当然,我们无法直接获取这个对象。

可以认为当一个函数被定义时,会将当前生效的范围链保存在该函数的范围链中,而当该函数被调用时,新创建的call objecct对象将插入到之前保存的范围链的头部,形成该函数调用中有效地范围链。在顶层 (top-level) 代码中,范围链只有一个对象,即全局对象,所以在顶层代码中,this.variable访问的就是全局变量(全局对象的属性)。在顶层函数中,范围链包含两个对象:第一个是表示该函数的call object,包含函数中定义的局部变量和参数;第二个就是全局对象。该范围链中的全局对象是解释器执行到函数定义时为该函数保存的,而第一个对象则是该函数被调用时才生成的。显然,顶层函数只可能被定义一次,所以它们的范围链的长度是确定的值2。例如,当顶层函数A调用顶层函数B时,A当前的范围链是 'A的call object - 全局对象',而A调用B并不会使B重新定义,所以执行函数B时,B将函数定义时保存的 '全局变量' 范围链扩充为 'B的call object - 全局对象',故结论与经验一致:函数B中不能使用A中的变量。
而对于内部函数,复杂性就出现了,例如:
function a() {
    var i = 0;
    funvtion b() {
        i++;
    }
    b();
}
当函数a被调用时,范围链包含两个对象,而当执行到第3行时,函数b被定义,所以函数b相对应的范围链被保存为 'a的call object - 全局对象'。当b()被执行时,函数b的范围链就变成了 'b的call object - a的call object - 全局对象',显然,在函数b中可以访问到函数a定义的局部变量。

范围链解释了为什么内层的同名变量优先于外层的变量,例如:
    var a=4;
    function f() { var a = 5; alert(a); } // 显示5

0 0
原创粉丝点击