转载

JavaScript数据类型中易被忽略的点

String

  • 字符串中可以包含由反斜杠 / 和字符构成的特殊字符,如 /n 换行, /b 退格, /f 换页, /r 回车, /t Tab;

var multiLine = " first /n second /n third line " alert(multiLine) // alerts 3 lines
  • ""当做转义符号也可以避免一些问题,如

var str = 'I/'m the Valrus'
  • 当计算字符串长度时,特殊字符也会参与计算,如:

var str = "My/n" // 3 .`/n`也算其中之一 alert(str.length)  // 3
  • javascript中的字符串只能读取不能改变;

  • javascript中有两种查找子字符串的方法, indexOflastIndexOf ,返回找到的第一个字符的位置,没找到返回-1;

  • 逐位运算符 ~ not,~n相当于 -(n+1), if ~indexOf 相当于 if found ;

  • 取得子字符串的三种方法 substr, substring, slice ,可以Google找到它们之间的差异,也可以从后文链接中找到;

  • 字符串的笔记

    • 字符串逐位比较,一旦比较出大小就不再往后比较; "Bob" > "Bar" // true, because o > a , alert("2" > "14"); // true

    • 字符装换为ASCII码比较

    • 当有数值参与比较时,会把字符串也转换为数值,如 alert(2 > "14"); // false

Number, Math

  • JavaScript中的数值采用双精度(IEEE 754),每个数占8byte;

  • JavaScript可以识别十六进制(0xFF),八进制(010)以及科学计数方法的数字(3e5);

  • Infinity-Infinity 是两个特殊的值,它们大于或小于任何值,对它们进行运算后依旧会得到 Infinity ,二者相除会得到NaN,并不会报错;

  • 当一个数学运算符不能被正确执行时会得到NaN( 0/0 ),它不等于包括其本身的任何数值,只可有 isNaN 函数检查;

  • 除了双向的加号,其它所有的运算符都会把数值形式的字符串转换为数值; alert( -"12.34" / "2" ) // -6.17 ;

  • 不能转换则返回 NaN ;

  • 一个由空白符组成的字符串会被转化为0;

  • 如果字符串首字母非数字, parseInt/parseFloat 会返回 NaN , alert( parseInt('a123') )//NaN ;

  • JavaScript中的数值计算存在精度问题( alert(0.1 + 0.2 == 0.3)//false )(浮点数不能被二进制精确的表示),解决方法可以先转化为整数,再除以10 alert( (0.1*10 + 0.2*10) / 10 ) // 0.3 ,也可以使用 toFixed ;

Array

  • shift , pop 删除对应项,并返回该项;

  • unshift , push ;

  • join , split ;

  • 如果给数组的length赋值低于数组实际的长度,会删除超过的项;

  • push , pop 直接操作最后一项,其运行速度快,效率高;

  • shift , unshift 操作第一项,需要记住整个数组,效率低;

  • 数组中的length方法(属性) 其实是last index+1,

    var fruits = [] // empty array fruits[1] = 'Peach' fruits[99] = 'Apple' alert(fruits.length)  // 100 (but 2 elements)
  • 对数组也可以使用 delete ,但是只会删除该项的值,不会真的删除该项;

  • splice 在原数组上更改和 slice 返回原数组的一个片段(新数组);

  • sort 默认把内容转化为string,然后根据ASCII码比较;

  • new Array 返回的是具有指定长度的值为空的数组;

Objects

  • obj.propobj[prop] 二者都可以访问对象中的一项,但是值得注意的是obj.prop里prop是该项的名称,obj[prop]里的prop是该项的值,此时prop是字符串,应该加引号;

  • alert("key" in obj) // true, key exists 使用 in 运算符可以用来确定是否存在某一项;

  • 使用 for in 时,子项处理顺序不确定,不同浏览器有所差别;

  • 对象中可以储存一切类型,包括函数;

  • 可以利用对象实现链式调用,其关键在于每次的返回值为this;

var ladder = {   step: 0,   up: function() {     this.step++     return this   },   down: function() {     this.step--     return this   },   showStep: function() {     alert(this.step)     return this   } } ladder.up().up().down().up().down().showStep()  // 1
  • 使用构造函数创建对象时, var animal = new Animal()var animal = new Animal 等同;

  • 使用构造函数创建对象时,其关键在于this,如果构造函数返回了一个对象则会忽略this;

  • JS中存在 Math , Date , RegExp 三种内置对象,函数从某种程度上来说也是对象,String,Number,Booleans三者比较特殊,它们各自拥有一些方法;

对象转换为简单数据类型

转化为字符串

  • 如果对象中存在toString方法,且返回一个简单类型数据,那么就返回这个字符串(所有数组默认拥有,所以一般执行到此完毕);

  • 默认

    alert( {key: 'value'} ) // toString for Objects outputs: [object Object] alert( [1,2] )          // toString for Arrays lists elements "1,2" alert( new Date )       // toString for Dates outputs the date as a string
  • 可以自己定义一个toString方法

    var user = { firstName: 'John', toString: function() {   return 'User ' + this.firstName } } alert( user )  // User John
  • 如果存在valueOf方法,且返回一个简单类型数据,那么返回这个;

  • alert()会触发装换为字符串

转换为数值(两种情况下发生,非常常见)

  • 对数值进行计算的方法( Math.sin(obj) , isNaN(obj) )以及运算符(+,-,*,/等等)

  • 做比较时(注:obj1==obj2,只有二者引用同一对象时才相等); Number(obj) 也会转换,

  • 数值转换规则如下

    • 如果存在valueOf方法,且返回一个简单类型数据,那么返回这个结果;

    • 如果对象中存在toString方法,且返回一个简单类型数据,那么就返回这个字符串;

    alert( new Date() ) // The date in human-readable form alert( +new Date() ) // Microseconds till 1 Jan 1970
    • 自己定义一个valueOf方法

    var room = {     num: 777,     valueOf: function() {       return this.num     }   }   alert( +room )  // 777
    • 不存在valueOf方法,但是存在toString方法时会调用此方法

    var room = {     num: 777,     toString: function() {       return this.num     }   }   alert( room / 3 )  // 259
    • 注意只需要返回简单数值类型即可( Numeric,String,Boolean ),不一定非要返回数值;

装换为布尔值

  • 装换表

    |Value | Converted to…|

true/false no conversion
undefined, null false
Number 0, NaN become false, others - true.
String "" becomes false, any other - true
Object true
  • 注意,字符"0"为true;

  • 涉及到逻辑运算符会触发布尔装换;

  • 但是也有比较奇怪的地方,看下面两例

alert( [0] == 0 )  // true   alert( "/n0/n" == 0 ) // true   alert( "/n0/n" == false ) // true //
if ([0]) alert(1)  // 1, if treats [0] as true   if ("/n0/n") alert(2) // 2, if treats "/n0/n" as true
  • 仔细想想如何转换的,就可以理解了。 == 只比较值得结果,[0],“0”装换为数值后就是0,但是当他们是数组中的一项,或字符串时并非是空的。

再看一个比较奇怪的例子

alert( [] == ![] ) // true
  • 首先,看右边![],逻辑非对[]进行布尔转换,依据上面的装换表,数组其实也是对象,object装换为真。所以右边![] = !true = false;

  • 再看左边,对象与简单类型比较时,会按数值方式装换,没有valueOf,将使用toString进行装换(以逗号分隔的字符串)那么就装换为一个空的字符串''=false;

  • 所以二者相等;

检测一下你是否真的掌握了数值装换,看看下面的题目能不能理解

6 / "3" = 2 "2" * "3" = 6 4 + 5 + "px" = "9px" "$" + 4 + 5 = "$45" "4" - 2 = 2 "4px" - 2 = NaN 7 / 0 = Infinity {}[0] = undefined parseInt("09") = "0" or "9" // octal or decimal, depends on the browser 5 && 2 = 2 2 && 5 = 5 5 || 0 = 5 0 || 5 = 5

说明

本文对各类型并未做详尽的说明,想了解更多资料可以参考以下文章

  • Mastering data types

原文  https://segmentfault.com/a/1190000006056285
正文到此结束
Loading...