在javascript中,提供了一些内置对象。Object就是其中一个,他是所有javascript对象的父对象。另外还有其他的一些。
基本上,内置对象可以分成三组:
- 数据包装对象:Object,Array,Function,Boolean,Number,String。
- 公共对象:Math,Date,RegExp。
- 错误对象:Error对象
Object
Object是所有javascript对象的父对象。创建一个空对象你可以使用大括号方式或者构造函数方式。下面的两种是等效的:
var o = {}; var o = new Object();?
一个空对象并不是完全没有用的,他其实已经包含了一些方法和属性,比如:
o.constructor属性返回构造器函数
o.toString()方法返回一个字符串形式的对象的描述,当一个对象被用作string来使用的是,这个方法会被执行,比如alert的时候。
o.valueOf()方法返回一个对象的单值,通常是对象自己,比如:
o.valueOf() === o; // true
Array
Array()是一个内置函数,我们可以用它来作为创建数组的构造器。下面两种是等效的:
var a = new Array(); var a = [];?
当使用Array()创建数组时,我们可以传入参数作为数组的元素。
var a = new Array(1,2,3,'four'); a; // [1, 2, 3, "four"]?
特殊的是,当我们只传入一个数字的时候。构造器会把这个数字作为数组的长度来创建一个数组。
var a2 = new Array(5); a2; // [undefined, undefined, undefined, undefined, undefined]?
下面我们可以比较一下数组和对象。
var a = [], o = {};?
在数组中,有一个length属性,而对象没有;
a.length; // 0 typeof o.length; // "undefined"?
我们可以向数组和对象中添加数字或者非数字属性。
a[0] = 1; o[0] = 1; a.prop = 2; o.prop = 2;?
但是数组中的length属性只会计算数字属性的长度。
a.length; // 1?
length这个属性我们是可以手动设置的。
如果我们设置一个比当前大的一个数字,那么数组会开辟一些空的元素来填充数组,值为undefined。
a.length = 5; a; // [1, undefined, undefined, undefined, undefined]?
如果把length设为比当前小的数字,数组将会把多余的元素截断。
a.length = 2; a; // [1, undefined]
?
Array里面还包含了其他一些有用的方法,比如sort(), join(), slice()。
我们可以试一些方法。
var a = [3, 5, 1, 7, 'test'];?
push()方法和pop()方法在对栈操作时比较有用。
push方法可以把一个元素加在数组的最后面,pop方法会删除最后一个元素。所以a.push('new')相当于a[a.length]='new',而a.pop()相当于a.length--。
push方法返回加入新元素以后的数组的长度,pop方法返回删除掉的元素。
a.push('new'); // 6 a; // [3, 5, 1, 7, "test", "new"] a.pop(); // "new" a; // [3, 5, 1, 7, "test"]?
sort()方法可以对一个数组进行自然排序,并返回排序后的数组。
var b = a.sort(); b; // [1, 3, 5, 7, "test"] a; // [1, 3, 5, 7, "test"]?
可见,a,b指向了同一个数组。
join()返回一个用给定值把各个数组元素连接起来的字符串。
a.join(' : '); // "1 : 3 : 5 : 7 : test"?
slice()方法返回一个数组指定范围的一个拷贝数组,意思就是拷贝出数组的一个范围内元素,而不改变数组本身。
b = a.slice(1, 3); // [3, 5] b = a.slice(0, 1); // [1] b = a.slice(0, 2); // [1, 3] a; // [1, 3, 5, 7, "test"]?
splice()方法会修改原数组,它会删掉指定部分的元素,并可以用新的元素来填补这些空缺。前两个参数表示起始位置和终止位置,其他的参数表示用于填补的新元素。
b = a.splice(1, 2, 100, 101, 102); // [3, 5] a; // [1, 100, 101, 102, 7, "test"]?
也可以不加填补的新元素。
a.splice(1, 3); // [100, 101, 102] a; // [1, 7, "test"]
?Function
另一种创建方法的方式是使用内置对象Function。但是这种方式不建议使用。
以下是几种创建方法的方式:
function sum(a, b) {return a + b;}; sum(1, 2); // 3 var sum = function(a, b) {return a + b;}; sum(1, 2); // 3 var sum = new Function('a', 'b', 'return a + b;'); sum(1, 2); // 3?
当使用Function()构造一个函数时,首先需要传入函数的参数,然后传入函数体的源代码。Javascript引擎会评估传入的源代码,并生成一个新的方法返回。所以,使用这种方式和使用eval()函数有着同样的缺点。
如何使用Function构造器来构造一个含有很多参数的方法时,可以将参数用逗号隔开,一次性传入。
var first = new Function('a, b, c, d', 'return arguments;'); first(1,2,3,4); // [1, 2, 3, 4] var second = new Function('a, b, c', 'd', 'return arguments;'); second(1,2,3,4); // [1, 2, 3, 4] var third = new Function('a', 'b', 'c', 'd', 'return arguments;'); third(1,2,3,4); // [1, 2, 3, 4]?
像其他对象一样,Function有constructor属性,他指向Function()构造函数。
function myfunc(a){ return a; } myfunc.constructor; // Function()
?
Function的length属性包含了函数接收的参数的个数。
function myfunc(a, b, c){ return true; } myfunc.length; // 3?
另外,有一个属性叫做caller,该属性不是ECMA标准定义的,而是由具体的浏览器提供的。他返回函数的一个调用该函数的函数的引用。比如,有一个函数A被函数B调用,如果在函数A中有A.caller。那么它将返回函数B。
function A(){ return A.caller; } function B(){ return A(); } B(); // B()?
如果我们直接访问函数A,那么A.caller将返回null。
A(); // null?
我们可以用toString函数来得到函数的源代码。
function myfunc(a, b, c) {return a + b + c;} alert(myfunc.toString());
弹出
"function myfunc(a, b, c) {
????? return a + b + c;
}"
但是如果你试图用这种方法来返回内置函数的源代码,那是不行的。
alert(eval.toString());?
弹出
"function eval() {
????? [native code]
}"
另外有两个有用的方法是call和apply。这两个方法允许对象借用其他对象的方法并执行他们。这样做可以使代码能够重用。
var some_obj = { name: 'Ninja', say: function(who){ return 'Haya ' + who + ', I am a ' + this.name; } }?
我们可以使用this.name来访问它的私有属性name。
some_obj.say('Dude'); // "Haya Dude, I am a Ninja"?
现在我们定义一个对象my_obj。
my_obj = {name: 'Scripting guru'};?
这时我们可以用call方法在some_obj对象中来得到my_obj的name属性。
some_obj.say.call(my_obj, 'Dude'); // "Haya Dude, I am a Scripting guru"?
其实在这里面,当say函数被执行的时候,this的引用已经从some_obj转移到my_obj上面了。所以这时候this.name其实得到的是my_obj的name属性。用这种方法,我们可以有效的把this引用转移到其他对象上。来得到其他对象的方法或属性。
如果方法有多个参数,可以在call后面加入更多的参数。
some_obj.someMethod.call(my_obj, 'a', 'b', 'c');?
如果第一个参数传入null,那么this将会引用全局对象。浏览器中就是window。
window.name='window'; some_obj.say.call(null, 'Dude'); // "Haya Dude, I am a window"?
apply方法的其实也是和call一样的,不同的是,使用apply方法,后面函数的参数要放在一个数组里。例如:
some_obj.someMethod.apply(my_obj, ['a', 'b', 'c']); some_obj.someMethod.call(my_obj, 'a', 'b', 'c');?
我们知道,函数中有个属性是arguments,它包含了所有传入的参数。arguments其实只是一个类似数组的一个对象,因为他可以像数组一样包含索引元素,有length属性,但是他并没有数组对象的sort,slice这些方法。不过它有一个callee属性。如果你定义一个函数并return arguments.callee,当执行这个函数的时候,将得到它自己的引用。
function f(){ return arguments.callee; } f(); // f()?
因此,我们可以用你们函数来重复调用他自己
( function(count){ if (count < 5) { alert(count); arguments.callee(++count); } } )(1)?
这段代码将连续弹出1,2,3,4.
Boolean
对于Boolean,它只不过是对基础数据类型boolean的包装。
我们可以用new关键字来创建一个Boolean对象。
var b = new Boolean(); typeof b; // "object" typeof b.valueOf(); // "boolean" b.valueOf(); // false?
可见,用Boolean构造器创建的是一个对象。我们可以使用他的valueOf方法来返回它的boolean值。
总的来说,这样的做法我们用的并不多。有时我们可能会直接调用Boolean函数来转换一个非boolean的值。这相当于使用“!!value”。
Boolean("test"); // true Boolean(""); // false Boolean({}); // true?
除了我们知道的空字符串,null,0,undefined,NaN,false这6个值,其他的值都会被转换成false。即使是空对象和false的Boolean对象,一切对象都会被转换为true。
var b1 = new Boolean(true); b1.valueOf(); // true var b2 = new Boolean(false); b2.valueOf(); // false Boolean(b1); // true Boolean(b2); // true
?Number
我们通常会用到Number这个对象来转换一个值为数字或者创建一个对象。
var n = Number('12.12'); typeof n; // "number" var n = new Number('12.12'); typeof n; // "object"?
没有用new操作符转换出来的就是一个数字。
Number函数还包含了几个有用的常量属性。
返回javascript所能处理的最大数值:
Number.MAX_VALUE; // 1.7976931348623157e+308?
返回javascript所能处理的最小数值:
Number.MIN_VALUE; // 5e-324?
返回正无穷
Number.POSITIVE_INFINITY; // Infinity?
返回负无穷
Number.NEGATIVE_INFINITY; // -Infinity?
返回NaN
Number.NaN; // NaN?
Number对象还提供了toFixed(), toPrecision(),toExponential()这3个方法。
toFixed()可以将一个数字四舍五入,保留指定的小数位数以后,以string返回。
Math.PI; // 3.141592653589793 Math.PI.toFixed(2); // "3.14"?
toExponential()将会把一个数字以指数的形式,保留指定小数位数后返回string。
var n = new Number(56789); n.toExponential(2); // "5.68e+4"?
toPrecision()可以指定有效数字位数,将数字以string返回。
var n = new Number(56789); n.toPrecision(2); // "5.7e+4" n.toPrecision(5); // "56789" n.toPrecision(4); // "5.679e+4" var n = new Number(Math.PI); n.toPrecision(4); // "3.142"?
另外,number的toString方法还可以传入进制参数。默认是十进制。
var n = new Number(255); n.toString(); // "255" n.toString(10); // "255" n.toString(16); // "ff" (3).toString(2); // "11" 3.toString(10); // "3"
?String
对于String这个内置对象,它同样包含了很多方法。其中值得注意的是slice方法和substring方法。他们都可以用来截取字符串中的一段字符。不同的是,当结束位置参数是-1的时候,他们的结果是不同的。
var s = "Couch potato"; s.substring(1,-1); // "C" s.slice(1,-1); // "ouch potat"
?
substring(1,-1)相当于substring(1,0),slice(1,-1)相当于slice(1, s.length - 1)。
除了前面这些内置的数据包装对象外,还有Math,Date,RegExp对象,以及Error对象。
?