值和类型

类型

js中的变量是没有类型的,只有值才有类型,变量可以随时接受任何类型。例如:

     var a = 42;
        console.log(typeof a); //number
        a = '44';
        console.log(typeof a);//string

undefind 和 undeclared

在js中,已在作用域声明但还没赋值的变量,是undefined。相反还没在作用域中声明过的变量是undeclared

var a;
console.log(typeof a); //undefined 
console.log(b);//Uncaught ReferenceError: b is not defined

需要特别注意的是如果用typeof undeclared 时,会返回undefined。

console.log(typeof b);//undefined

但是这种方式有一个好处就是可以通过typeof来检查变量是否声明过,而不会报错。例如:

if (b) {   //这种方式会报错
    //do something
}

if (typeof b !== "undefined") {
    //do something
}

if (window.b) { //也可以用这种方式 但如果代码会在其他环境中执行的话,会有问题,例如nodejs,全局对象就不是window了。
    //do something
}

 

数组

数组内部可以放任意类型的元素,也可创建稀疏数组。

var a = [];
a[0] = '1a';
a[2] = '23';

这里需要注意a[1]的值是undefined。
数组也可以像对象一样有自己的属性,例如:

a['name'] = 'yu';
console.log(a.length);//3

但是数组的属性并不会改变length属性。还有一点需要注意的是,如果属性名称可以转换为十进制数字的话,那么它就会被当做索引来处理。例如:

a['13'] = 'a';
console.log(a.length); //14

类数组

一般在一些dom查询操作返回的元素列表,其实他们并非是真正意义的数组,而是一些类数组。在jq内部经常会使用类数组。

var a = { 1: 'a', 2: 'b', length: 2 };

还一个例子是arguments就是一个类数组,但在es6开始已经废止。
常用的转换类数组为真正的数组的方式为:

var arr = Array.prototype.splice.call(a);

在es6中Array新增了一个内置函数 Array.from() 也可以实现转换功能,例如:

var arr = Array.from(a);

 

字符串

字符串和字符串数组在很多情况下看起来是一样的,但他们并不是一回事。他们都有length属性和indexof等方法。

var a = 'abc';
var b = ['a', 'b', 'c'];
console.log(a.length);//3
console.log(b.length);//3
console.log(a.indexOf('b'));//1
console.log(b.indexOf('b'));//1

但是字符串是不可变的,只能创建一个新的字符串并返回,而字符串数组可以在原始值改变的。

a[1] = 'v';
b[1] = 'v';
console.log(a);//abc
console.log(b);//["a", "v", "c"]

在实际开发过程中我们可以借用数组的方法来达到某些目的。

var c = Array.prototype.join.call(a,'-');
console.log(c);//a-b-c

还有一个常见的面试题就是字符串反转问题。
数组上有一个reverse方法,用来反转数组元素,但是我们这里却无法借用,因为字符串是不可变的。
但是我们可以先把字符串转成数组,在进行反转。

var a = 'xyz';
var b = a.split('').reverse().join();
console.log(b); //z, y, x

 

数字

var a = 42.56;
console.log(a.toFixed(0)); //43 四舍五入
console.log(a.toFixed(1)); //42.6
console.log(a.toFixed(3)); //42.560

转换的结果是字符串格式,所以如果指定的位数多于实际的位数,就会用0补齐。

对于.预算符需要特别注意,它会被优先识别为数字常量的一部分,然后才是对象属性访问符。例如:

console.log(45..toFixed(3));//45.000
console.log(45.toFixed(3));//报错

浮点数小数的问题,也就是常见的0.1+0.2===0.3问题

console.log(0.1 + 0.2 === 0.3);//false

这是因为js遵循的ieee754规范的原因,这个规范中浮点数不是很精确,他们的相加的结果是一个十分接近0.3的数字,而不是精确等于0.3。
解决方法:

if (!Number.EPSIlON) {
    Number.EPSILON = Math.pow(2, -52);
}
function numberToEqual(a, b) {
    return Math.abs(a - b) < Number.EPSILON;
}
var a = 0.1 + 0.2;
var b = 0.3;
console.log(numberToEqual(a, b)); //true

整数检测

在es6中可以用Number.isInteger()方法判断

console.log(Number.isInteger(42));//true
console.log(Number.isInteger(42.00));//true
console.log(Number.isInteger(42.3));//false

在es6版本之前,可以用下面代码做兼容

if (!Number.isInteger) {
    Number.isInteger = function (num) {
        return typeof num == "number" && num % 1 === 0;
    }
}

检测是否为安全整数,es6中用Number.isSafeInteger方法

console.log(Number.isSafeInteger(Number.MAX_SAFE_INTEGER)); //true
console.log(Number.isSafeInteger(Math.pow(2, 53))); //false

在es6版本之前,可以用下面代码做兼容

if (!Number.isSafeInterger) {
    Number.isSafeInterger = function (num) {
        return Number.isInteger(num) && Math.abs(num) <= Number.MAX_SAFE_INTEGER
    };
}

undefind值从未赋过值,null值曾赋过值,但是目前没有值,
null 是一个特殊关键字,不是标示符,我们不能将其当做变量俩使用和赋值
undefind是一个标示符,可以被当做变量来使用和赋值 undefind=2;

void运算符 void是返回undefined类型的,也就是void 1  void0 等等这些和undefined没有实质的区别

特殊的数字

NaN 是一个不是数字的数字,也就是它是数字类型,但因为运算失败等原因,得到的一个无效数值。

var a = 42 / 'aa'; //NaN
typeof a === 'number'; //true

但是NaN有一个特点,就是和自身永远不相等,也就是NaN!=NaN 为true,所以一般判断变量是否为数字时使用:

console.log(!isNaN('a'));//false 不是数字

这个方法虽然有这个功能,但是也可以看到 a既不是一个数字,也不是NaN,但会返回的结果却是true,这显然不太科学。
在es6中新加了一个方法Number.isNaN()方法,之前的版本用下面的代码做兼容

if (!Number.isNan) {
    Number.isNaN = function (n) {
        return (typeof n === 'number' && window.isNaN(n));
    }
}
var a = 2 / 'f';
var b = 'fa';
console.log(Number.isNaN(a));//true
console.log(Number.isNaN(b));//false

还有一个简单的方法,就是利用NaN自身不相等的特性来判断:

if (!Number.isNan) {
    Number.isNaN = function (n) {
        return n !== n;
    }
}

无穷数

在js中 有穷数可以变成无穷数,但是无穷数却不可以变成有穷数,例如:

var a = Number.MAX_VALUE + Number.MAX_VALUE; //无穷数
var b = Number.MAX_VALUE + Number.MAX_VALUE;
console.log(a / b);//NaN

因为从js语言的角度来说,这是一个未定义操作,所以返回为NaN

0值 在js中存在负0的情况,但是这种负0的情况只是显示为负0,它的实际的值还是0,例如0===-0 结果为true

在程序中有时候需要以级数形式标书,比如动画帧的速度,符号用来表示移动的方向,所以保留0的符号位防止信息丢失。

console.log(0 / -3);
console.log(0 === -0);

  

posted @ 2016-11-01 11:36  8932809  阅读(213)  评论(0编辑  收藏  举报