《你不知道的JavaScript》:理解js原生函数

本篇来看下js中的原生函数,也叫内置函数。主要包括如下:

  • String()
  • Number()
  • Boolean()
  • Array()
  • Object()
  • Function()
  • RegExp()
  • Date()
  • Error()
  • Symbol()

原生函数可以被当作构造函数来用,但其构造出来的对象与设想的有区别,以String()为例:

1var s = new String("abc");
2console.log(s);         // String {"abc"}
3console.log(typeof s);  // object
4console.log(Object.prototype.toString.call(s));     // [object String]

可以看到,变量s的打印结果不是设想的abc,而是String {"abc"}(这里不同浏览器不同版本可能显示有区别,我用的是chrome浏览器),typeof的结果显示这是一个对象object,而不是字符串。

通过构造函数(如 new String("abc"))创建出来的是封装了基本类型值(如"abc")的封装对象。

上例中有个打印结果是"[object String]",它是对象的一个分类。

所有typeof返回值为object的对象(比如数组、函数)都包含一个内部属性[[class]](可以将其看作一个内部的分类,而非传统的面向对象意义上的类)。这个属性无法直接访问,一般通过Object.prototype.toString.call()来查看:

1Object.prototype.toString.call([1, 2, 3]);      // [object Array]
2Object.prototype.toString.call(/[0-9]{1,2}/);   // [object RegExp]

上例中数组的内部[[class]]属性值是"Array",正则表达示的值是"RegExp"。

多数情况下,对象的内部[[class]]属性和创建该对象的内建原生构造函数相对应。

其他基本类型值(比如字符串、数值和布尔)的情况则有所不同,通常被称为"包装":

1Object.prototype.toString.call(42);         // [object Number]
2Object.prototype.toString.call("abc");      // [object String]
3Object.prototype.toString.call(true);       // [object Boolean]

上例中基本类型值被各自的封装对象自动包装,所以它们的内部[[class]]属性值分别为"String"、"Number"和"Boolean"。

对基本类型值进行手动对象封装是没有必要的,浏览器已对常见情况做了系统优化,直接使用封装对象来"提前优化"代码反而会降低执行效率,所以通常我们无需直接使用封装对象,最好的办法是让引擎自己决定什么时候应该用封装对象,开发者应优先使用基本类型值,而不是new String()这样手动创建封装对象。

既然有封装,那就有拆封。想要得到封装对象中的基本类型值,可以使用valueOf()函数:

1var a = new String("abc");
2var b = new Number(42);
3var c = new Boolean(true);
4
5console.log(a.valueOf());       // abc
6console.log(b.valueOf());       // 42
7console.log(c.valueOf());       // true

在需要用到封装对象中的基本类型值的地方会发生隐式拆封,具体过程就是强制类型转换的过程,这个在下篇中再细看。

除了基本类型值的对象封装,引用类型值也会进行对象封装,即通过相应的构造函数创建封装对象。但通常应尽量少用构造函数来创建它们,比如数组、对象和函数,直接以常量的形式创建即可。

1var a = new Array(1, 2, 3);     // 构造函数创建数组
2console.log(a);     // [1, 2, 3]
3
4var b = [4, 5, 6];              // 常量形式创建数组
5console.log(b);     // [4, 5, 6]

但相较于其他原生构造函数,Date()Error()则不一样,因为没有对应的常量形式来作为它们的替代。

创建日期对象必须使用new Date()Date()可以带参数,用来指定日期和时间,而不带参数的话则使用当前的日期和时间。Date()主要用来获得当前的Unix时间戳(从1970年1月1日开始计算,以秒为单位)。该值可以通过日期对象中的getTime()来获得。

创建错误对象主要是为了获取当前运行栈的上下文,栈上下文信息包含函数调用栈信息和产生错误的代码行号,以便于debug调试。错误对象通常与throw一起使用。

1function foo(x){
2    if(!x){
3        throw new Error("x is not defined.");
4    }
5}
6foo();      // Uncaught Error: x is not defined.

ES6中新增加了一个基本数据类型:Symbol(符号)。符号是具有唯一性的特殊值,用它来命名对象属性不容易导致重名。这个东西我没用过,也没什么觉得用的必要?没什么感受,就不举例了,有兴趣的可以自行去看。可能等我以后确实碰到用了,才会觉得这玩意很重要?到时再看吧。

除了上面的这些原生构造函数对象本身外,它们也都有各自的.prototype对象,即它们的原型对象,例如String.prototypeArray.prototype等,这些原型对象包含了其对应子类型所特有的行为特性。借助原型代理,所有的这些构造函数的"实例"对象都具有对应原型对象上的方法。

最后总结下,js为所有基本类型值提供了封装对象,它们也被称为原生函数(String、Number、Boolean等)。注意这些对象的首字母是大写的,与那些全小写的作用类型值名称以示区分。当要访问基本类型值的一些方法或属性时,如length或者String.prototype,js引擎会自动对该值进行封装(即用相应类型的封装对象来包装它)来实现对这些属性和方法的访问。

-------------------------------- 热门文章 --------------------------------

设计模式>>>

javascript设计模式一: 单例模式

javascript设计模式二:策略模式

javascript设计模式三:代理模式

javascript设计模式四:迭代器模式

javascript设计模式五:原型模式

javascript设计模式六:发布-订阅模式(观察者模式)

javascript设计模式七:模板方法模式

javascript设计模式八:职责链模式

javascript设计模式九:中介者模式

javascript设计模式十:装饰者模式

本文分享自微信公众号 - 前端小二(frontendxiao2)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-01-19

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏程序员的知识天地

只要十分钟,用Python实现自动化水军评论

自己在写文章的时候,也有到处去逛一逛,渐渐发现了一些有意思的事,经常会有人用同样的评论到处刷,不知道是为了加没什么用的积分,还是纯粹为了表达楼主好人。那么问题来...

13320
来自专栏蚂蚁开源社区

如何使用JavaScript来判断是否为移动设备?

  由于移动设备的显示屏幕相对于桌面显示器来说小很多,在桌面显示器上能够正常显示的内容,到了移动设备中就不正常了。为了实现移动端和桌面端的相互跳转,我们可以通过...

10010
来自专栏Tech爬虫(公众号php_pachong)

使用Firefox轻松调试JS

Firefox调试JS的功能真的很不错,推荐一下! 在页面上点击右键,再点击“查看元素”,如图:

8320
来自专栏阿策小和尚

【Flutter 专题】28 图解 ListView/GridView 混用时滑动冲突小尝试

和尚在学习过程中会在一个 Page 页面同时用到 GridView 和 ListView 或多个 ListView,此时就会遇到常见的滑动冲突问题。...

11920
来自专栏阿策小和尚

【Flutter 专题】21 图解 ListView 下拉刷新与上滑加载(三)

和尚前段时间整理了两种 ListView 的异步加载数据时,下拉刷新与上滑加载更多的方式,每种方式都有自己的优势,网上也有很多大神讲解过 ListV...

9420
来自专栏Tech爬虫(公众号php_pachong)

jQuery中的$是什么

但在JS应用库JQUERY的作者将之做为一个自定义函数名了,这个函数是获取指定网页元素的函数,使用非常之频繁,所以好多新手不知道,还以为$是JS的什么特殊语法。

7120
来自专栏蚂蚁开源社区

【教程下载】HTML5游戏开发(全)

HTML5有望成为网络游戏开发的热门新平台。HTML5游戏能够运行于包括iPhone系列和iPad系列在内的计算机、智能手机以及平板电脑上。今天,我们加入HTM...

15210
来自专栏蚂蚁开源社区

微信小程序仿阿姨帮【含教程】

官方解释,微信小程序,简称小程序,是一种不需要下载安装即可使用的应用,它实现了应用“触手可及”的梦想,用户扫一扫或搜一下即可打开应用。简而言之,就是用户需要的时...

20950
来自专栏Tech爬虫(公众号php_pachong)

jquery 使用方法

jQuery是目前使用最广泛的javascript函数库。据统计,全世界排名前100万的网站,有46%使用jQuery,远远超过其他库。微软公司甚至把jQuer...

9710
来自专栏蚂蚁开源社区

编程有感,Web 新时代的机遇与挑战

技术决定了业务需求的多样性,而业务需求的多样性又推动着技术不断向前发展,两者相辅相成最终才能推动行业整体的发展和进步。

8220

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励