JavaScript的原生函数
< 返回列表时间: 2020-08-06来源:OSCHINA
常用的原生函数有: String() Number() Boolean() Array() Object() Function() RegExp() Date() Error() Symbol()
原生函数可以被当作构造函数来使用 var a = new String("abc"); console.log(typeof a); console.log(a instanceof String); console.log(Object.prototype.toString.call(a));
内部属性[[Class]]
所有typeof返回值为“object”的对象(如数组)都包含一个内部属性[[Class]](可以把它看作一个内部的分类,而非传统的面向对象意义上的类)。
这个属性无法直接访问,一般通过Object.prototype.toString()来查看。 console.log(Object.prototype.toString.call([1,2,3])); console.log(Object.prototype.toString.call(/regex-literal/i));
封装对象包装
封装对象(object wrapper)扮演着十分重要的角色。由于基本类型值没有.length和.toString()这样的属性和方法,需要通过封装对象才能访问,此时JavaScript会自动为基本类型值包装一个封装对象。
封装对象释疑 var a = "abc"; var b = new String(a); var c = Object(a); console.log(typeof a); console.log(typeof b); console.log(typeof c); console.log(b instanceof String); console.log(c instanceof String); console.log(Object.prototype.toString.call(b)); console.log(Object.prototype.toString.call(c));
拆封
valueof()返回封装对象中的基本类型值 var a = new String("abc"); var b = new Number(42); var c = new Boolean(true); console.log(a.valueOf()); console.log(b.valueOf()); console.log(c.valueOf());
在需要用到封装对象中的基本类型值的地方会发生隐式拆封。 var a = new String("abc"); var b = a+""; console.log(typeof a); console.log(typeof b);
原生函数作为构造函数
Array()构造函数只带一个参数的时候,该参数会被作为数组的预设长度(length),而非只充当数组中的一个元素。
Object()、Function()和RegExp() var c = new Object(); c.foo = "bar"; c; // { foo: "bar" } var d = { foo: "bar" }; d; // { foo: "bar" } var e = new Function( "a", "return a * 2;" ); var f = function(a) { return a * 2; } function g(a) { return a * 2; } var h = new RegExp( "^a*b+", "g" ); var i = /^a*b+/g;
new Object()来创建对象,因为这样就无法像常量形式那样一次设定多个属性,而必须逐一设定。
构造函数Function只在极少数情况下有用,比如动态定义函数参数和函数体的时候。不要把 Function(..) 当作 eval(..) 的替代品,你基本上不会通过这种方式来定义函数。 var name = "Kyle"; var namePattern = new RegExp( "\\b(?:" + name + ")+\\b", "ig" ); var matches = someText.match( namePattern );
强烈建议使用常量形式(如 /^a*b+/g )来定义正则表达式,这样不仅语法简单,执行效率也更高,因为 JavaScript 引擎在代码执行前会对它们进行预编译和缓存。与前面的构造函数不同, RegExp(..) 有时还是很有用的,比如动态定义正则表达式时。
Date()和Error()
创建日期对象必须使用 new Date() 。 Date(..) 可以带参数,用来指定日期和时间,而不带参数的话则使用当前的日期和时间。
Date(..) 主要用来获得当前的 Unix 时间戳(从 1970 年 1 月 1 日开始计算,以秒为单位).该值可以通过日期对象中的 getTime() 来获得或静态函数 Date.now() if (!Date.now) { Date.now = function(){ return (new Date()).getTime(); }; }
构造函数 Error(..) (与前面的 Array() 类似)带不带 new 关键字都可。创建错误对象(error object)主要是为了获得当前运行栈的上下文(大部分 JavaScript 引擎通过只读属性 .stack 来访问)。栈上下文信息包括函数调用栈信息和产生错误的代码行号,以便于调试(debug)。
错误对象通常与 throw 一起使用: function foo(x) { if (!x) { throw new Error( "x wasn’t provided" ); } // .. }
通常错误对象至少包含一个 message 属性,有时也不乏其他属性(必须作为只读属性访问),如 type 。
Symbol()
一个基本数据类型 ——符号(Symbol)。符号是具有唯一性的特殊值(并非绝对),用它来命名对象属性不容易导致重名。
符号可以用作属性名,但无论是在代码还是开发控制台中都无法查看和访问它的值,只会显示为诸如 Symbol(Symbol.create) 这样的值。
ES6 中有一些预定义符号,以 Symbol 的静态属性形式出现,如 Symbol.create 、 Symbol.iterator 等,可以这样来使用: obj[Symbol.iterator] = function(){ /*..*/ };
可以使用 Symbol(..) 原生构造函数来自定义符号。但它比较特殊,不能带 new 关键字,否则会出错: var mysym = Symbol( "my own symbol" ); mysym; // Symbol(my own symbol) mysym.toString(); // "Symbol(my own symbol)" typeof mysym; // "symbol" var a = { }; a[mysym] = "foobar"; Object.getOwnPropertySymbols( a ); // [ Symbol(my own symbol) ]
原生原型
原生构造函数有自己的 .prototype 对象,如 Array.prototype 、 String.prototype 等。
这些对象包含其对应子类型所特有的行为特征。
例如,将字符串值封装为字符串对象之后,就能访问 String.prototype 中定义的方法。
• String#indexOf(..)
在字符串中找到指定子字符串的位置。
• String#charAt(..)
获得字符串指定位置上的字符。
• String#substr(..) 、 String#substring(..) 和 String#slice(..)
获得字符串的指定部分。
• String#toUpperCase() 和 String#toLowerCase()
将字符串转换为大写或小写。
• String#trim()
去掉字符串前后的空格,返回新的字符串。
以上方法并不改变原字符串的值,而是返回一个新字符串。 var a = " abc "; a.indexOf( "c" ); // 3 a.toUpperCase(); // " ABC " a.trim(); // "abc"
其他构造函数的原型包含它们各自类型所特有的行为特征,比如 Number#tofixed(..) (将数字转换为指定长度的整数字符串)和 Array#concat(..) (合并数组)。所有的函数都可以调用 Function.prototype 中的 apply(..) 、 call(..) 和 bind(..) 。
将原型作为默认值
Function.prototype 是一个空函数, RegExp.prototype 是一个“空”的正则表达式(无任何匹配),而 Array.prototype 是一个空数组。对未赋值的变量来说,它们是很好的默认值。 function isThisCool(vals,fn,rx){ vals= vals || Array.prototype; fn = fn || Function.prototype; rx = rx || RegExp.prototype; return rx.test( vals.map(fn).join("") ); } console.log(isThisCool());
这种方法的一个好处是 .prototypes 已被创建并且仅创建一次。
热门排行