Primitive Wrappers(基本类型包装器)
JavaScript有五种基本类型:number,string,boolean,null和undefined;
除了null和undefined例外,其他3种都有对应的基本类型包装器对象(primitive wrapper objects);
包装器对象可以使用内置的Number(),String()和Boolean()构造函数创建;
为了说明基本类型的number和number对象的区别,请看这个例子:
// a primitive number var n = 100; console.log(typeof n); // "number" // a Number object var nobj = new Number(100); console.log(typeof nobj); // "object"
包装器对象有一些很有用的属性和方法,比如:
number对象的toFixed() and toExponential()方法;
string对象的substring(),charAt()和toLowerCase()方法,和一个length属性;
这些方法是非常方便并且可以成为相对于基本类型选择创建对象绝佳理由;
但是这些方法在基本类型身上同样有效,当你在基本类型身上调用一个方法时,基本类型会被临时的转换成对象;
var s = "hello"; console.log(s.toUpperCase()); // "HELLO" // the value itself can act as an object "monkey".slice(3, 6); // "key" // same for numbers (22 / 7).toPrecision(3); // "3.14"
因为基本类型可以在你需要的时候表现的像一个对象,通常没有理由去使用冗长的包装器构造方法;
比如:当你可以简单使用"hi"的时候,你不必写new String("hi");
// avoid these: var s = new String("my string"); var n = new Number(101); var b = new Boolean(true); // better and simpler: var s = "my string"; var n = 101; var b = true;
一个使用包装器类型的理由就是你想扩展它的值,因为基本类型不是对象,他们不能用属性扩展;
// primitive string var greet = "Hello there"; // primitive is converted to an object // in order to use the split() method greet.split(' ')[0]; // "Hello" // attemting to augment a primitive is not an error greet.smile = true; // but it doesn't actually work typeof greet.smile; // "undefined"
在上面这段代码中,greet仅仅是被临时的转换成一个对象,使访问它的属性和方法的时候不会报错;
另一方面,如果greet是使用new String()定义的一个对象,那么扩展的smile属性就能如预期一样工作;
扩展string,number,或者boolean的值很少被用到——除非你真的需要——因此你很可能不需要使用包装器构造方法;
当你不使用new时,包装器构造方法会将传入的参数转换成他们对象的基本类型:
typeof Number(1); // "number" typeof Number("1"); // "number" typeof Number(new Number()); // "number" typeof String(1); // "string" typeof Boolean(1); // "boolean"
Error对象(Error Objects)
JavaScript有很多内置的error构造函数,比如:Error(),SyntaxError(),TypeError()和其它的;
他们和throw语句一起使用,这些构造函数创建的error对象有以下属性:
name:创建对象的构造函数的名字,可能是普通的“Error”或者更专业的构造函数,就像“RangeError”;
message:创建error对象时,传递的字符串;
Error对象还有其他的属性,好比错误发生的行号和文件名,但是这些额外的属性是浏览器扩展的并不是所有浏览器都实现的,所以是不可靠的。
另一方面,throw可以和任何对象一起使用,不一定非要是error构造函数创建的对象;
所以你可以选择抛出你自己的对象,就像error对象的name和message属性,任何其他属性都可以被catch语句处理;
try { // something bad happened, throw an error throw { name: "MyErrorType", // custom error type message: "oops", extra: "This was rather embarrassing", remedy: genericErrorHandler // who should handle it }; } catch(e) { // inform the user alert(e.message); // "oops" // gracefully handle the error e.remedy(); // calls genericErrorHandler() }
Error的构造函数当做函数调用(不使用new)和当做构造函数(使用new调用)是一样的,返回一样的error对象