内置对象与原生对象
内置(Build-in
)对象与原生(Naitve
)对象的区别在于:前者总是在引擎初始化阶段就被创建好的对象,是后者的一个子集;而后者包括了一些在运行过程中动态创建的对象。
原生对象(New后的对象)
ECMA-262
把原生对象(native object
)定义为“独立于宿主环境的 ECMAScript
实现提供的对象”。包括如下:
Object、Function、Array、String、Boolean、Number、Date、RegExp、Error、eva lError、RangeError、ReferenceError、SyntaxError、TypeError、URIError、ActiveXObject(服务器方面)、Enumerator(集合遍历类)、RegExp(正则表达式)
由此可以看出,简单来说,原生对象就是 ECMA-262
定义的类(引用类型)。
来源: http://es5.github.com/#x4.3.6
内置对象(不需要New)
定义:由ECMAScript实现提供的对象,独立于宿主环境,在一个脚本程序执行的开始处。
注:每个内置对象(built-in object
)都是原生对象(Native Object
),一个内置的构造函数是一个内置的对象,也是一个构造函数。
来源:http://es5.github.io/#x4.3.7
举个栗子:
Native objects: Object (constructor), Date, Math, parseInt, eva l。 string 方法比如 indexOf 和 replace, array 方法, ... Host objects (假定是浏览器环境): window, document, location, history, XMLHttpRequest, setTimeout, getElementsByTagName, querySelectorAll, ...
ECMA-262][2 只定义了两个新的内置对象,即 Global
和 Math
(它们也是原生对象,根据定义,每个内置对象都是原生对象)。
以下是ECMA-262定义的内置对象(built-in):
global、Object、Function、Array、String、Boolean、Number、Math、Date、RegExp、JSON、Error对象(Error, eva lError, RangeError, ReferenceError, SyntaxError, TypeError 和URIError)
我们也可以修改内置对象的原型
if (!Array.prototype.forEach) { Array.prototype.forEach = function(fn){ for ( var i = 0; i < this.length; i++ ) { fn( this[i], i, this ); } }; } ["a", "b", "c"].forEach(function(value, index, array){ assert( value, "Is in position " + index + " out of " + (array.length - 1) ); });
以上代码将输出:
PASS Is in position 0 out of 2 PASS Is in position 1 out of 2 PASS Is in position 2 out of 2
注意:扩展原型是很危险的:
Object.prototype.keys = function(){ var keys = []; for ( var i in this ) keys.push( i ); return keys; }; var obj = { a: 1, b: 2, c: 3 }; assert( obj.keys().length == 3, "We should only have 3 properties." ); delete Object.prototype.keys;
输出: FAIL We should only have 3 properties.
如果不是有特殊需要而去扩展原生对象和原型(prototype
)的做法是不好的
除非这样做是值得的,例如,向一些旧的浏览器中添加一些ECMAScript5
中的方法。
在这种情况下,我们一般这样做:
<script type="text/java script"> if (!Array.prototype.map) { Array.prototype.map = function() {
用原型扩展对象
对js原生对象的扩展无非就是往prototype
里注册,例如,我们可以往String
对象里扩展ltrim,rtrim
等方法。js每个对象都继承自Object
,并且,对象和其他属性都通过prototype
对象来继承。通过prototype
对象,我们可以扩展任何对象,包括内建的对象,如String
和Date
:
String对象的扩展
<script type="text/java script"> if(typeof String.prototype.ltrim=='undefined'){ String.prototype.ltrim = function(){ var s = this; s = s.replace(/^\s*/g, ''); return s; } } if(typeof String.prototype.rtrim=='undefined'){ String.prototype.rtrim = function(){ var s = this; s = s.replace(/\s*$/g, ''); return s; } } if(typeof String.prototype.trim=='undefined'){ String.prototype.trim = function(){ return this.ltrim().rtrim(); } } if(typeof String.prototype.htmlEncode=='undefined'){ String.prototype.htmlEncode = function(encodeNewLine){