JavaScript 类型理解与类型判断

发布于 2024-05-21 12:33:05 字数 4906 浏览 40 评论 0

理解 Javascript 的类型是学习 Javascript 的基础,但是作为新手很容易在判断 Javascript 上容易混淆,所以在此整理清自己的思路。

类型

JavaScript 中所有变量都是对象,除了两个例外 null 和 undefined。

作为新手很容易被上面这句话误导,首先解释下上面这句话。

false.toString(); // 'false'
[1, 2, 3].toString(); // '1,2,3'
(2).toString(); // '2'

通过上面的代码,可以看出布尔、数组、数字都具有 toString() 这一方法,其实除了 nullundefined 外的数据类型都继承自 Object 对象都具 Object 的方法和属性,这些看似非对象的类型使用起来却很像对象,所以也可以说它们都是对象。可是 Javascript 依然具有类型,我想大致可以分成下面几类:

  • Number
  • String
  • Boolean
  • Object
  • Null
  • Undefined

NumberStringBooleanNullUndefined 都是是基本数据类型,只有 Object 属于复杂数据类型。 NullUndefined 都表示空,它们的区别在于: Null 表示无值,一般是人为的将变量的值设置为 nullUndefined 表示未知值,一般在使用 var 声明变量但未对其加以初始化时,这个变量值为 undefined

Object 又分为以下几种类型:

  • Object
    • Function
    • Array
    • Date
    • RegExp

typeof 操作符

typeof 操作符(和 instanceof 一起)或许是 JavaScript 中最大的设计缺陷, 因为几乎不可能从它们那里得到想要的结果。

typeof []; // object
typeof {}; // object
typeof ''; // string
typeof new Date() // object
typeof 1; // number
typeof function () {}; // function
typeof /test/i; // object
typeof true; // boolean
typeof null; // object
typeof undefined; // undefined

为什么? function 明明是 Object 类型,却显示 functionnull 明明是 Null 类型,却显示’object’。所以 typeof 操作符对类型的判断是不靠谱的,除非类型在给定的范围且 typeof 确实能够区分这些类型。

类型的区分

Javascript 标准标准文档给出了区分类型的办法:

Object.prototype.toString.call();

我们来看看上面的方法效果如何:

Object.prototype.toString.call([]); // [object Array]
Object.prototype.toString.call({}); // [object Object]
Object.prototype.toString.call(''); // [object String]
Object.prototype.toString.call(new Date()); // [object Date]
Object.prototype.toString.call(1); // [object Number]
Object.prototype.toString.call(function () {}); // [object Function]
Object.prototype.toString.call(/test/i); // [object RegExp]
Object.prototype.toString.call(true); // [object Boolean]
Object.prototype.toString.call(null); // [object Null]
Object.prototype.toString.call(); // [object Undefined]

效果确实比 typeof 操作符号不一样,那我们在判断的时候就可以这么使用了:

var getType = function (elem) {
      return Object.prototype.toString.call(elem);
    },
    person = {};
    person.getName = function () {
      return 'Jason';
    };
if (getType(person) === '[object Object]') {
  person.getName();
}

可是这样还不够完美,因为 Object.prototype.toString.call() 返回值是字符串所以可以用 .slice(8, -1) 方法去掉 [object] 。所以我们再改进一下:

var getType = function (elem) {
      return Object.prototype.toString.call(elem).slice(8, -1);
    },
    person = {};
    person.getName = function () {
      return 'Jason';
    };
if (getType(person) === 'Object') {
  person.getName();
}

写个类库

利用上面判断类型的方法可以写个类库,此类库来自(Axis.js)[//github.com/toddmotto/axis]:

(function (root, factory) {
  // 判断是否使用了模块
  if (typeof define === 'function' && define.amd) {
    // 使用 AMD 模块
    define(factory);
  } else if (typeof exports === 'object') {
    // 使用 CMD 模块
    module.exports = factory;
  } else {
    // 没有使用模块,放在全局下
    root.axis = factory();
  }
})(this, function () {
  // 严格模式
  'use strict';
  var exports = {};
  // 将字符串转为数组
  var types = 'Array Object String Date RegExp Function Boolean Number Null Undefined'.split(' ');
  // 判断类型
  var type = function () {
    return Object.prototype.toString.call(this).slice(8, -1);
  };
  // 遍历 types,为 exports 对象添加 isArray、isObject...等方法
  for (var i = types.length; i--;) {
    exports['is' + types[i]] = (function (self) {
      return function (elem) {
        // type.call(elem) 将 type 方法里的 this 指针指向 elem
        return type.call(elem) === self;
      };
    })(types[i]);
  }
  return exports;
});

使用方法也很简单:

axis.isArray([]); // true
axis.isObject({}); // true
axis.isString(''); // true
axis.isDate(new Date()); // true
axis.isRegExp(/test/i); // true
axis.isFunction(function () {}); // true
axis.isBoolean(true); // true
axis.isNumber(1); // true
axis.isNull(null); // true
axis.isUndefined(); // true

参考链接:

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

爱殇璃

暂无简介

文章
评论
26 人气
更多

推荐作者

十二

文章 0 评论 0

飞烟轻若梦

文章 0 评论 0

OPleyuhuo

文章 0 评论 0

wxb0109

文章 0 评论 0

旧城空念

文章 0 评论 0

-小熊_

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文