一、ECMAScript原始值和引用值
在ECMAScript中,变量可以存在两种类型的值,即原始值和引用值。
原始值
存储在栈(stack)中的简单数据段,即,它们的值直接存储在变量访问的位置。
引用值
存储在堆(heap)中的对象,即,存储在变量处的值是一个指针(point),指向存储对象的内存处。
原始值和引用值的存储
二、ECMAScript引用类型
引用类型通常叫做类(class),也就是说,遇到引用值,所处理的就是对象。
对象是由new运算符加上要实例化的对象的名字创建的。例如:
var o = new Object();
var o = new Object;
当有不止一个参数时,EMACScript要求使用括号。如果没有参数,则可以省略括号。
尽管括号不是必需的,但是为了避免混乱,最好使用括号。
Object对象
ECMAScript中的所有对象都由Object对象继承而来,Object对象中的所有属性和方法都会出现在其他对象中,即了解Object对象就可以更好地理解其他对象。
Object对象具有下列属性:
constructor
对创建对象的函数的引用(指针)。对于Object对象,该指针指向原始的Object()函数。
prototype
对该对象的对象原型的引用。对于所有的对象,它默认返回Object对象的一个实例。
Object对象具有下列方法:
hasOwnProperty(property)
判断对象是否有某个特定的属性。必须用字符串指定该属性。(例如,o.hasOwnProperty(“name”))
var oNumber = new Number(12);
var oString = new String("13");
alert(oNumber.hasOwnProperty("length")); //false
alert(oString.hasOwnProperty("length")); //true
isPrototypeOf(object)
判断该对象是否为另一个对象的原型。
var oNumber = new Number(12);
alert(Object.prototype.isPrototypeOf(oNumber)); //true
alert(Number.prototype.isPrototypeOf(oNumber)); //true
alert(String.prototype.isPrototypeOf(oNumber)); //false
因为Object是所有对象的父类,所以,任何一个对象的原型都等于Object。
propertyIsEnumerable()
判断给定的属性是否可以用for…in语句进行枚举。
toString()
返回对象的原始字符串表示。对于Object对象,ECMA-262没有定义这个值,所以不同的ECMASript实现具有不同的值。
var oNumber1 = new Number("1232");
var oNumber2 = new Number("0x1232");
var oObject1 = new Object();
var oObject2 = new Object(0x1232);
alert(oNumber1.toString()); //1232
alert(oNumber2.toString()); //4658
alert(oObject1.toString()); //[object Object]
alert(oObject2.toString()); //4658
valueOf()
返回最适合该对象的原始值。对于好多对象,该方法返回的值都与ToString()的返回值相同。
var oNumber1 = new Number("1232");
var oNumber2 = new Number("0x1232");
var oObject1 = new Object();
var oObject2 = new Object(0x1232);
alert(oNumber1.valueOf()); //1232
alert(oNumber2.valueOf()); //4658
alert(oObject1.valueOf()); //[object Object]
alert(oObject2.valueOf()); //4658
注意:上面列出的每种属性和方法都会被其他对象覆盖。
Boolean对象
Boolean 对象是 Boolean 原始类型的引用类型。
要创建Boolean对象,只需要传递Boolean值作为参数:
var oBooleanObject = new Boolean(true);
Boolean对象将覆盖Object对象的valueOf()方法,返回原始值,即true和false。toString()方法也会被覆盖,返回字符串”true”或”false”。
注意下面情况:
var oFalseObject = new Boolean(false);
alert(oFalseObject && true); //true
解析:oFalseObject是一个对象,在进行Boolean操作时,会使用Boolean()函数转换成true。
Number对象
Number对象是Number原始类型的引用类型。
创建Number对象,采用下面的方法:
var oNumberObject = new Number(68);
之前在原始类型中提到的Number.MAX_VALUE、Number.MIN_VALUE、Number.POSITIVE_INFINITY和Number.NEGATIVE_INFINITY都是Number对象的静态属性。
要得到数字对象的 Number 原始值,只需要使用 valueOf() 方法:
var iNumber = oNumberObject.valueOf();
另外,Number()类也有toString()方法。
除了从Object对象继承的标准方法之外,Number对象还有几个处理数值的专用方法。
toFixed()方法
toFixed()方法返回的是具有指定位数小数的数字的字符表示。例如:
var oNumberObject1 = new Number(68);
var oNumberObject2 = new Number(68.026);
alert(oNumberObject1.toFixed(2)); //68.00
alert(oNumberObject2.toFixed(2)); //68.03
toFixed()方法的参数表示应该显示的小数位数,参数的范围值是0~20,超过范围,程序将出错。
toExponential()方法
toExponential()方法返回的是用科学计数法表示的数字的字符串形式。
与toFixed()方法相似,toExponential()方法也有一个参数,指定要输出的小数的位数。例如:
var oNumberObject1 = new Number(680);
var oNumberObject2 = new Number(686);
alert(oNumberObject1.toExponential(1)); //6.8e+2
alert(oNumberObject2.toExponential(1)); //6.9e+2
toPrecision()方法
toPrecision()方法根据最有意义的形式来返回数字的预定形式或指数形式。它只有一个参数,即用于表示数的数字总数(不包括指数)。例如:
var oNumberObject1 = new Number(6);
var oNumberObject2 = new Number(6.0345);
var oNumberObject3 = new Number(0.0345);
alert(oNumberObject1.toPrecision(3)); //6.00
alert(oNumberObject2.toPrecision(3)); //6.03
alert(oNumberObject3.toPrecision(3)); //0.0345
注意: toFixed()、toExponential()、toPrecision()方法都会进行舍入操作,以便正确的小数位数正确地表示一个数。
String对象
String对象是String原始类型的对象表示法,创建如下:
var oStringObject = new String("hello word");
String 对象的valueOf()方法和toString()方法都会返回String类型的原始值:
alert(oStringObject.valueOf() == oStringObject.toString()); //true
alert(oStringObject.valueOf() === oStringObject.toString()); //true
length属性
String 对象具有属性length,它是字符串中的字符个数:
var oStringObject1 = new String("hello word");
var oStringObject2 = new String("hello\nword");
alert(oStringObject1); // 11
alert(oStringObject2); // 11
length属性中,即使字符串包含双字节的字符(例如,转义字符\n),每个字符也只算一个字符。
charAt()和charCodeAt()方法
两个方法charAt()和charCodeAt()访问的是字符串中的单个字符。这两个方法都有一个参数,即要操作的字符的位置。
不同的是:charAt()方法返回的是包含指定位置处的字符的字符串;charCodeAt()方法返回的是字符代码。
var oStringObject = new String("hello word");
alert(oStringObject.charAt(1)); //e
alert(oStringObject.charCodeAt(1)); //101
concat() 方法
用于把一个或多个字符串连接到String对象的原始值上。该方法返回的是String原始值,保持原始的String对象不变。
var oStringObject = new String("hello");
var sResult = oStringObject.concat(" world");
alert(sResult); //hello world
alert(oStringObject); //hello
较常见的是用加号(+)连接字符串:
var oStringObject = new String("hello");
var sResult = oStringObject+" world";
alert(sResult); //hello world
alert(oStringObject); //hello
indexOf()和lastIndexOf()方法
indexOf()和lastIndexOf()方法返回的都是指定的子串在另一个字符串中的位置,如果没有找到子串,则返回-1。
二者的不同之处在于:indexOf()方法是从字符串开头(位置0)开始检索字符串,lastIndexOf()方法则是从字符串的结尾开始检索子串。
var oStringObject1 = new String("hello world!");
var oStringObject2 = new String("hello!");
alert(oStringObject1.indexOf("o")); //4
alert(oStringObject1.lastIndexOf("o")); //7
alert(oStringObject2.indexOf("o")); //4
alert(oStringObject2.lastIndexOf("o")); //4
localeCompare()方法
localeCompare()方法是对字符串进行排序。该方法有一个参数-要进行比较的字符串,返回的是下列三个值之一:
- 如果String对象按照字母顺序排在参数中的字符串之前,返回负数;
- 如果String对象等于参数中的字符串,返回0;
- 如果String对象按照字母顺序排在参数中的字符串之后,返回正数。
var oStringObject = new String("yellow");
alert(oStringObject.localeCompare("brick")); //输出 "1"
alert(oStringObject.localeCompare("yellow")); //输出 "0"
alert(oStringObject.localeCompare("zoo")); //输出 "-1"
注意:如果返回负数,那么最常见的是-1,不过真正返回是由实现决定的。如果返回正数,那么同样的,最常见的是1,不过真正返回的是由实现决定的。
所以,最好使用下面的方式调用localeCompare()方法:
var oStringObject1 = new String("yellow");
var oStringObject2 = new String("brick");
var iResult = oStringObject1.localeCompare(oStringObject2);
if(iResult < 0)
{
alert(oStringObject1 + " comes before " + oStringObject2);
}
else if (iResult > 0)
{
alert(oStringObject1 + " comes after " + oStringObject2);
}
else
{
alert("The two strings are equal");
}
slice() 和 substring()方法
slice() 和 substring()方法返回的都是要处理的字符串子串,都接受一个或两个参数。第一个参数是要获取的子串的起始位置,第二个参数(如果使用的话)是要获取子串终止前的位置(即,获取终止位置处的字符不包括在返回的值内)。如果省略第二个参数,终止位就默认为字符串的长度。
与concat()方法一样,slice()和substring()方法都不改变String对象自身的值。它们返回原始的String值,保持String对象不变。
var oStringObject = new String("hello world");
alert(oStringObject.slice("3")); //输出 "lo world"
alert(oStringObject.substring("3")); //输出 "lo world"
alert(oStringObject.slice("3", "7")); //输出 "lo w"
alert(oStringObject.substring("3", "7")); //输出 "lo w"
slice() 和 substring()方法的不同在于,参数为负数的情况下,它们处理参数的方式不同。
对于负数参数,slice()方法会用字符串的长度加上参数,substring()方法则将其作为0处理。例如:
var oStringObject = new String("hello world");
alert(oStringObject.slice("-3")); //输出 "rld"
alert(oStringObject.substring("-3")); //输出 "hello world"
alert(oStringObject.slice("3, -4")); //输出 "lo w"
alert(oStringObject.substring("3, -4")); //输出 "hel"
substring() 总把较小的数字作为起始位,较大的数字作为终止位。
toLowerCase() 、toLocalelLowerCase()、toUpperCase()和 toLocalelUpperCase()方法
toLowerCase()和toLocalelLowerCase()方法用于把字符串转换成全小写,toUpperCase()和 toLocalelUpperCase()方法用于把字符串转换成全大写。
var oStringObject = new String("Hello World");
alert(oStringObject.toLocaleUpperCase()); //输出 "HELLO WORLD"
alert(oStringObject.toUpperCase()); //输出 "HELLO WORLD"
alert(oStringObject.toLocaleLowerCase()); //输出 "hello world"
alert(oStringObject.toLowerCase()); //输出 "hello world"
四种方法实现的区别:
- toLowerCase() 和 toUpperCase() 方法是原始的,是以 java.lang.String 中相同方法为原型实现的。
- toLocaleLowerCase() 和 toLocaleUpperCase() 方法是基于特定的区域实现的(与localeCompare() 方法相同)。在许多区域中,区域特定的方法都与通用的方法完全相同。不过,有几种语言对 Unicode大小写转换应用了特定的规则(例如土耳其语),因此必须使用区域特定的方法才能进行正确的转换。
instanceof 运算符
在使用 typeof 运算符时采用引用类型存储值会出现一个问题,无论引用的是什么类型的对象,它都返回 “object”。
instanceof 运算符与 typeof 运算符相似,用于识别正在处理的对象的类型。与 typeof 方法不同的是,instanceof 方法要求开发者明确地确认对象为某特定类型。例如:
var oStringObject = new String("hello world");
alert(oStringObject instanceof String); //输出 "true"
本文章主要参考并总结W3School以及W3Cschool
W3School