前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JavaScript类型、值和原生函数大揭秘, 前端开发者必看!

JavaScript类型、值和原生函数大揭秘, 前端开发者必看!

作者头像
Ims
发布2024-03-13 15:20:18
600
发布2024-03-13 15:20:18
举报

JavaScript类型、值和原生函数大揭秘, 前端开发者必看!

类型

  • • ECMAScript 一共有七种语言类型:Undefined、Null、Boolean、String、Number、Object、Symbol

内置类型

  • • 函数不仅是对象,还拥有属性。在函数中的 length 属性是参数的个数
  • • 如下代码:
代码语言:javascript
复制
function a(b,c){
    // do something
}

a.length; // 2
  • typeof [...] 为什么等于 object?
    • 数组也是对象,但确切来说,它是 object 的一个 "子类型"
  • • 如下代码:
代码语言:javascript
复制
typeof [1,2,3] === 'object'; // true

值和类型

  • • typeof 运算符总是会返回一个字符串
  • • 如下代码:
代码语言:javascript
复制
typeof typeof 42; // string

// typeof 42 首先会返回 number, 然后 typeof number 返回 string

小结

  1. 1. 变量没有类型,他们所拥有的值才有类型。
  2. 2. typeof [...] 为什么等于 object?
    • 数组也是对象,但确切来说,它是 object 的一个 "子类型"

数组

  • 使用 delete 操作符不会影响数组长度
代码语言:javascript
复制
let a = ['a', 'b', 'c', 'd'];
delete a[2];
console.log('a ------>', a); // [ 'a', 'b', <1 empty item>, 'd' ]
console.log('a ------>', a.length); // 4
  • • 数组索引既可以通过数字索引,也可以通过字符串索引,可以通过像访问对象的建制属性一样访问数组元素。除了通过使用数字索引的方式,其他都不计算进数组长度内
代码语言:javascript
复制
let a2 = [];
a2[0] = 1;
a2['foo'] = 2;

console.log('a2.length ------>', a2.length);  // 1
console.log("a2['foo'] ------>", a2['foo']); // 2
console.log('a2.foo ------>', a2.foo); // 2
  • • 如果字符串值被强制转换为十进制数字,数组会被当做数字索引来处理
代码语言:javascript
复制
var a = [];
a['13'] = 42;
a.length; // 14
  • • 将类数组转为数组, 还有其他方法: indexOf()、concat()、map().....
代码语言:javascript
复制
var arr = Array.from(arguments);
Array.prototype.slice.call();

数字

  • • 数字语法:数字前面的 0 可省略
代码语言:javascript
复制
var a = 0.42;
var b = .42;
  • • 由于数字值使用 Number 对象封装,因此数字值可调用 Number.prototype 中的方法。
    • • toPrecision(..) 方法用来指定有效数位的显示位数:
代码语言:javascript
复制
var a = 42.59;

a.toPrecision( 1 ); // "4e+1"
a.toPrecision( 2 ); // "43"
a.toPrecision( 3 ); // "42.6"
a.toPrecision( 4 ); // "42.59"
a.toPrecision( 5 ); // "42.590"
a.toPrecision( 6 ); // "42.5900"
  • • 注意,对于 . 操作符来说,因为他们是一个有效的数字字符,会被优先识别为数字常量的一部分,然后才是对象属性访问运算符。
代码语言:javascript
复制
// 无效语法:
42.toFixed( 3 );    // SyntaxError

// 下面的语法都有效:
(42).toFixed( 3 );  // "42.000"
0.42.toFixed( 3 );  // "0.420"
42..toFixed( 3 );   // "42.000"

// 注意其中的空格
42 .toFixed(3);  // "42.000"
  • • 42.tofixed(3) 是无效语法,因为 . 被视为常量 42. 的一部分(如前所述),所以没有 . 属性访问运算符来调用 tofixed 方法。
  • • 42..tofixed(3) 则没有问题,因为第一个 . 被视为 number 的一部分,第二个 . 是属性访问运算符。只是这样看着奇怪,实际情况中也很少见。在基本类型值上直接调用的方法并不多见,不过这并不代表不好或不对。
数值检测方法
  • • 能够被"安全"呈现的最大整数是 2^53 - 1,即 9007199254740991,在 ES6 中被定义为 Number.MAX_SAFE_INTEGER。最小整数是 -9007199254740991,在 ES6 中被定义为 Number.MIN_SAFE_INTEGER
  • • 要检测一个值是否是整数,可以使用 ES6 中的 Number.isInteger(..) 方法:
代码语言:javascript
复制
Number.isInteger( 42 );     // true
Number.isInteger( 42.000 ); // true
Number.isInteger( 42.3 );   // false
  • • 也可以为 ES6 之前的版本 polyfill Number.isInteger(..) 方法:
代码语言:javascript
复制
if (!Number.isInteger) {
    Number.isInteger = function(num) {
        return typeof num == "number" && num % 1 == 0;
    };
}
  • • 要检测一个值是否是安全的整数,可以使用 ES6 中的 Number.isSafeInteger(..) 方法:
代码语言:javascript
复制
Number.isSafeInteger( Number.MAX_SAFE_INTEGER );    // true
Number.isSafeInteger( Math.pow( 2, 53 ) );          // false
Number.isSafeInteger( Math.pow( 2, 53 ) - 1 );      // true
  • • 可以为 ES6 之前的版本 polyfill Number.isSafeInteger(..) 方法:
代码语言:javascript
复制
if (!Number.isSafeInteger) {
    Number.isSafeInteger = function(num) {
        return Number.isInteger( num ) &&
            Math.abs( num ) <= Number.MAX_SAFE_INTEGER;
    };
}

特殊数值

  • null 和 undefined。nul 是一个特殊关键字,不是标识符,不能将其当做变量来使用和赋值。但 undefined 确实一个标识符,可被当做变量来使用和赋值。
代码语言:javascript
复制
null: 指空值
undefined:指没有值
  • NaN:NaN 是一个特殊值,它和自身并不相等,是唯一一个非自反(即 x === x 不成立的值),而 NaN != NaN 为 true。
  • • 那如何判断 NaN 呢?
代码语言:javascript
复制
var a = 2 / 'foo';
isNaN(a); // true
  • • ES6 开始我们可使用工具函数 Number.isNaN()
代码语言:javascript
复制
var a = 2 / "foo";
var b = "foo";

Number.isNaN( a ); // true
Number.isNaN( b ); // false——好!
  • • 还有一个简单方法,利用 NaN 不等于自身这个特点。
代码语言:javascript
复制
if (!Number.isNaN) {
    Number.isNaN = function(n) {
        return n !== n;
    };
}

小结

  1. 1. 使用 delete 操作符不会影响数组长度
  2. 2. 除了通过使用数字索引的方式,其他都不计算进数组长度内
  3. 3. 数值语法中数字前面的 0 可省略
  4. 4. 注意,对于 . 操作符来说,因为他们是一个有效的数字字符,会被优先识别为数字常量的一部分,然后才是对象属性访问运算符。
  5. 5. 要检测一个值是否是整数,可以使用 ES6 中的 Number.isInteger(..) 方法
  6. 6. 最大整数是 9007199254740991,在 ES6 中被定义为 Number.MAX_SAFE_INTEGER。最小整数是 -9007199254740991,在 ES6 中被定义为 Number.MIN_SAFE_INTEGER
  7. 7. NaN:NaN 是一个特殊值,它和自身并不相等,是唯一一个非自反(即 x === x 不成立的值),而 NaN != NaN 为 true。
  8. 8. 如何判断一个数是否是 NaN?
代码语言:javascript
复制
var a = 2 / "foo";
var b = "foo";

Number.isNaN( a ); // true
Number.isNaN( b ); // false ——好!

原生函数

  • • 常见原生函数:
代码语言:javascript
复制
• String()
• Number()
• Boolean()
• Array()
• Object()
• Function()
• RegExp()
• Date()
• Error()
• Symbol() ——ES6 中新加入的!
  • • 原生函数可当构造函数使用,但构造出来的对象会我们设想的有所出入。
代码语言:javascript
复制
var a = new String( "abc" );

typeof a;                            // 是"object",不是"String"

a instanceof String;                 // true

Object.prototype.toString.call( a ); // "[object String]"
  • 使用构造函数创建出来的是封装了基本类型值的封装对象。
  • • 注意:typeof 在此返回的是对象类型的子类型。

内部属性 [[Class]]

代码语言:javascript
复制
Object.prototype.toString.call( [1,2,3] );
// "[object Array]"

Object.prototype.toString.call( /regex-literal/i );
// "[object RegExp]"

Object.prototype.toString.call( null );
// "[object Null]"

Object.prototype.toString.call( undefined );
// "[object Undefined]"

Object.prototype.toString.call( "abc" );
// "[object String]"

Object.prototype.toString.call( 42 );
// "[object Number]"

Object.prototype.toString.call( true );
// "[object Boolean]"
  • • 上例中,数组的内部 [[Class]] 属性值是 "Array",正则表达式的值是 "RegExp"......

封装对象包装

代码语言:javascript
复制
var a = new Boolean( false );
console.log('a ------>', a); // [Boolean: false]
console.log(Boolean(a)); // true
if (!a) {
    console.log( "Oops" ); // 执行不到这里
}
  • • 若想要自定义基本类型值,可使用 Object() 函数(不带 new 关键字)
代码语言:javascript
复制
var a = "abc";
var b = new String( a );
var c = Object( a );

typeof a; // "string"
typeof b; // "object"
typeof c; // "object"

b instanceof String; // true
c instanceof String; // true

Object.prototype.toString.call( b ); // "[object String]"
Object.prototype.toString.call( c ); // "[object String]"

小结

  1. 1. 使用原生函数构造出来的函数对象时封装了基本类型值的封装对象。
  2. 2. 若想要自定义基本类型值,可使用 Object() 函数(不带 new 关键字)
代码语言:javascript
复制
var b = new String( a );
var c = Object( a );

Object.prototype.toString.call( b ); // "[object String]"
Object.prototype.toString.call( c ); // "[object String]"

特殊字符描述

•问题标注 Q:(question)

•答案标注 R:(result)

•注意事项标准:A:(attention matters)

•详情描述标注:D:(detail info)

•总结标注:S:(summary)

•分析标注:Ana:(analysis)

•提示标注:T:(tips)

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2023-07-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 非同质前端札记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • JavaScript类型、值和原生函数大揭秘, 前端开发者必看!
    • 类型
      • 内置类型
      • 值和类型
      • 小结
      • 数组
      • 数字
      • 特殊数值
      • 小结
    • 原生函数
      • 内部属性 [[Class]]
      • 封装对象包装
      • 小结
      • 特殊字符描述
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档