javascript:学习笔记
ECMAScript 中有6 种原始类型:Boolean、Null、Undefined、Number、String、Symbol (ECMAScript 6 新定义) 以及复杂的数据类型 Object
undefined 和 null 的简单介绍
在使用 var 声明变量但未对其加以初始化时,这个变量的值就是 undefined, undefined是一个表示"无"的原始值,转为数值时为NaN;
从逻辑角度来看,null 值表示一个空对象指针,而这也正是使用 typeof 操作符检测 null 值时会返回"object"的原因。null是一个表示"无"的对象,转为数值时为0。
undefined 不是 JavaScript 的保留字,只是全局变量上的一个属性,属性值是原始值 undefined。在 ECMAScript 5 之前,给 window.undefined 赋值会覆盖该属性。ECMAScript 5 的标准里加入了变量拥有可写、可枚举、可配置属性。全局的 undefined 的可写属性应该是 false 的。
Object.getOwnPropertyDescriptor(window, "undefined"); => Object {value: undefined, writable: false, enumerable: false, configurable: false}
void 运算符 对给定的表达式进行求值,然后返回 undefined,所以void 0 代替 undefined。
如果需要判断变量是否未初始化:
- typeof v === 'undefined';
- v === void 0;
string类型
ECMAScript中的字符串是不可变的,也就是说,字符串一旦创建,它们的值就不能改变。要改变某个变量保存的字符串,首先要销毁原来的字符串(此过程是在后台发生的),然后再用另一个包含新值的字符串填充该变量。
字符串还提供许多可以调用的方法:
var s = "hello, world" //定义一个字符串 s.charAt(0) // => "h" 第一个字符 s.charAt(s.length-1) // => "d" 最后一个字符 s.substring(1, 4) // => "ell" 第2-4个字符 s.slice(1,4) // => "ell" 同上 s.slice(-3) // => "rld": 最后三个字符 s.indexOf("l") // => 2 字符l首次出现的位置 s.lastIndexOf("l") // => 10: 字符l最后一次出现的位置 s.indexOf("l", 3) // => 在位置3及之后首次出现字符l的位置 s.split(",") // => ["hello", "world"]分割成子串 s.replace("h", "H") // => "Hello, world": 全文字符替换 s.toUpperCase() // => "HELLO WORLD"
number 类型
在JavaScript的内部采用IEEE754格式来表示数字,所以不区分整数和浮点数,都是用64位浮点数的形式储存。就是说,在JavaScript内部,就根本没有小数。但是有些运算必须得需要整数完成,所以JavaScript有时会把64位的浮点数转换成32位的整数,再进行运算。
js中数值转换的函数有三个:parseInt()、parseFloat()、number()
parseInt ( cString )从字符串cString非空字符开始转换得到的整数,遇到小数点或其他0-9外的字符就停止,如“-1234a”,“-1234.0”都将返回 -1234;如果除第一个符号外一个0-9字符都不是,将返回NaN,如“-a”、“abc”等;
Number( cString )从字符串cString转换得到的数字,包括Int和Float类型,如:“-123”返回-123,“123”和“00123”都返回 123,“234。56”返回234。56等。cString必须是合法的数字串,否则返回NaN;如“.123”、“1.23.45”、 “--123”、“123a"都返回NaN.
总之Number( )更象parseFloat( ),Number对参数更挑剔,稍有不是数字就返回NaN。
parseFloat支持第一个非空字符为小数点,如parseFloat(".123" )返回0.123。而Number(".123" )返回NaN。
空字符串或完全空格串健壮的parseFloat()返回NaN,而Number()返回0,这有点让人费解。
除了不支持无前导0小数 (如.123、-.123)和支持多余的前导0(如-00123返回-123)多少不符合常规外,Number能用来验证数字串!
Number类型原型上还有一些方法来对数字进度进行取舍,这些方法可以被 Number 实例对象调用:
方法 描述
toExponential() 返回一个数字的指数形式的字符串
toFixed() 返回指定小数位数的表示形式
toPrecision() 返回一个指定精度的数字
Math.abs(x) 返回x的绝对值
Math.sign(x) 返回x的符号函数, 判定x是正数,负数还是0
Math.random() 返回0到1之间的伪随机数
Math.floor(x) 返回x向上取整后的值
Math.ceil(x) 返回x向上取整后的值
Math.round(x) 返回四舍五入后的整数.
symbol类型
Symbol值通过Symbol函数生成。这就是说,对象的属性名现在可以有两种类型,一种是原来就有的字符串,另一种就是新增的Symbol类型。凡是属性名属于Symbol类型,就都是独一无二的,可以保证不会与其他属性名产生冲突。
1、注意,Symbol函数前不能使用new命令,否则会报错。这是因为生成的Symbol是一个原始类型的值,不是对象。也就是说,由于Symbol值不是对象,所以不能添加属性。基本上,它是一种类似于字符串的数据类型。
2、Symbol函数可以接受一个字符串作为参数,表示对Symbol实例的描述,主要是为了在控制台显示,或者转为字符串时,比较容易区分。
3、由于每一个Symbol值都是不相等的,这意味着Symbol值可以作为标识符,用于对象的属性名,就能保证不会出现同名的属性。这对于一个对象由多个模块构成的情况非常有用,能防止某一个键被不小心改写或覆盖。Symbol值作为对象属性名时,不能用点运算符。在对象的内部,使用Symbol值定义属性时,Symbol值必须放在方括号之中。
let obj = (function () { let key = Symbol('你好'); let obj = { }; obj[key] = '私有变量'; return { get foo () { return this[key]; } }; })(); obj.foo = 'hello world'; console.log(Object.getOwnPropertyNames(obj)); // ['foo'] console.log(Object.getOwnPropertySymbols(obj)); // [Symbol(你好)] let anotherKey = Symbol('你好'); console.log(obj[anotherKey]) // undefined typeof anotherKey // 'symbol'