一、值

1)数字

JavaScript只有一种数值类型:number(数字),包括“整数”和带小数的十进制数。

//数字的语法
var a = 5E10; // 50000000000
a.toExponential();  // "5e+10"
var b = a * a;  // 2.5e+21
var c = 1 / a; // 2e-11
var d = 0.42;
var e = .42; //数字前面的0可以省略
var f = 42.; //小数点后小数部分最后面的0也可以省略

由于数字值可以使用Number对象进行封装,因此数字值可以调用Number.prototype中的方法。例如,tofixed(..)方法可指定小数部分的显示位数:

// 无效语法:
42.toFixed( 3 );    // SyntaxError
// 下面的语法都有效:
a = (42).toFixed(3); // "42.000"
b = 0.42.toFixed(3); // "0.420"
c = 42..toFixed(3); // "42.000"
d = 42 .toFixed(3); // "42.000"

2)整数检测

//整数检测
if (!Number.isInteger) {Number.isInteger = function(num) {return typeof num == "number" && num % 1 == 0;};
}
//安全整数检测
if (!Number.isSafeInteger) {Number.isSafeInteger = function(num) {return Number.isInteger(num) &&Math.abs(num) <= Number.MAX_SAFE_INTEGER;};
}

3)null与undefined

特殊数值undefined与null。它们的名称既是类型也是值。

null指空值(empty value),曾赋过值,但是目前没有值。null是一个特殊关键字,不是标识符,我们不能将其当作变量来使用和赋值。

undefined指没有值(missing value),从未赋值。undefined是一个标识符,可以被当作变量来使用和赋值。

//将undefined当作变量来使用和赋值
function foo() {"use strict";var undefined = 2;console.log(undefined); // 2
}
foo();

4)不是数字的数字

NaN意指“不是一个数字”(not a number),将它理解为“无效数值”、“失败数值”或者“坏数值”可能更准确些。

NaN是一个特殊值,它和自身不相等,是唯一一个非自反(自反,即x === x不成立)的值。而NaN != NaN为true。

var a = 2 / "foo"; // NaN
typeof a === "number"; // true
if (!Number.isNaN) {Number.isNaN = function(n) { //非数字类型的值在isNaN中也会返回truereturn (typeof n === "number" &&window.isNaN(n));};
}
//利用NaN不等于自身这个特点
if (!Number.isNaN) {Number.isNaN = function(n) {return n !== n;};
}

5)零值

加法和减法运算不会得到负零(negative zero)。负零在开发调试控制台中通常显示为“-0”,但在一些老版本的浏览器中仍然会显示为“0”。

//零值
a = 0 / -3; // -0
b = 0 * -3; // -0
c = +"-0"; // -0
d = Number("-0"); // -0
e = JSON.parse("-0"); // -0
//值比较
-0 == 0; // true
-0 === 0; // true
0 > -0; // false
//-0的判断方式
function isNegZero(n) {n = Number(n);return (n === 0) && (1 / n === -Infinity);
}
isNegZero(-0); // true
isNegZero(0 / -3); // true
isNegZero(0); // false

6)特殊等式

NaN和-0在相等比较时的表现有些特别。

由于NaN和自身不相等,所以必须使用ES6中的Number.isNaN(..)。 而-0等于0(对于===也是如此),因此我们必须使用isNegZero(..)这样的工具函数。

//特殊等式
if (!Object.is) {Object.is = function(v1, v2) {// 判断是否是-0if (v1 === 0 && v2 === 0) {return 1 / v1 === 1 / v2;}// 判断是否是NaNif (v1 !== v1) {return v2 !== v2;}// 其他情况return v1 === v2;};
}

7)值和引用

JavaScript引用指向的是值。如果一个值有10个引用,这些引用指向的都是同一个值,它们相互之间没有引用/指向关系。

向函数传递值的时候,实际是将引用值的一个复本传递进去,不管是基本类型还是对象。

//基本类型
var a = 2;
var b = a; // b是a的值的一个副本
b++;
a; // 2
b; // 3//变量引用同一个值
var c = [1, 2, 3];
var d = c; // d是[1,2,3]的一个引用
d.push(4);
c; // [1,2,3,4]
d; // [1,2,3,4]//变量引用不同的值
var a = [1, 2, 3];
var b = a;
b = [4, 5, 6]; //给b重新赋值,引用新的值,不影响a的引用
a; // [1,2,3]
b; // [4,5,6]//函数内让参数重新引用值
function foo2(x) {x.push(4);x; // [1,2,3,4]
  x = [4, 5, 6];// 然后重新引用新的值x.push(7);x; // [4,5,6,7]
}
var a = [1, 2, 3];
//向函数传递a的时候,实际是将引用a的一个复本赋值给x,而a仍然指向[1,2,3]
foo2(a);
a; // 是[1,2,3,4],不是[4,5,6,7]

上面的源码可以在此次浏览。

二、原生函数

常用的原生函数有:String()、Number()、Boolean()、Array()、Object()、Function()、RegExp()、Date()、Error()、Symbol()。

1)内部属性[[Class]]

这个属性无法直接访问,一般通过Object.prototype.toString(..)来查看。

//内部属性[[Class]]
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]"

虽然Null()和Undefined()这样的原生构造函数并不存在,但是内部[[Class]]属性值仍然是"Null"和"Undefined"。

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

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

2)封装对象包装

由于基本类型值没有.length和.toString()这样的属性和方法,需要通过封装对象才能访问,此时JavaScript会自动为基本类型值包装(box或者wrap)一个封装对象:

//封装对象
var a = "abc";
a.length; // 3
a.toUpperCase(); // "ABC"

如果想要自行封装基本类型值,可以使用 Object(..) 函数(不带 new 关键字)

//自行封装基本类型
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]"

3)拆封

如果想要得到封装对象中的基本类型值,可以使用valueOf()函数:

//拆封
var a = new String("abc");
var b = new Number(42);
var c = new Boolean(true);console.log(a.valueOf()); // "abc"
console.log(b.valueOf()); // 42
console.log(c.valueOf()); // true

在需要用到封装对象中的基本类型值的地方会发生隐式拆封。

上面的源码可以在此处浏览。

《你不知道的JavaScript》整理(五)——值与原生函数相关推荐

  1. 《你不知道的JavaScript(上)》笔记——函数作用域和块作用域

    关于函数声明:如果 function 是声明中的第一个词, 那么就是一个函数声明, 否则就是一个函数表达式.例如匿名函数这种形式,函数会被当作函数表达式而不是一个标准的函数声明来处理. (functi ...

  2. 精读《你不知道的javascript》中卷

    前言 <你不知道的 javascript>是一个前端学习必读的系列,让不求甚解的JavaScript开发者迎难而上,深入语言内部,弄清楚JavaScript每一个零部件的用途.本书< ...

  3. 《你不知道的JavaScript上卷》知识点整理与读书笔记

    各位路过的的大佬.求关注.求点赞.谢谢 第一部分 作用域和闭包 第1章 作用域是什么 1.1编译原理 1.2理解作用域 1.3作用域嵌套 1.5异常 第2章 词法作用域 2.1词法阶段 2.2欺骗词法 ...

  4. JavaScript几种原生函数

    1.原生JavaScript实现字符串长度截取 function cutstr(str, len) {var temp;var icount = 0;var patrn = /[^\x00-\xff] ...

  5. 打造属于自己的underscore系列(五)- 偏函数和函数柯里化

    这一节的内容,主要针对javascript函数式编程的两个重要概念,偏函数(partial application) 和函数柯里化(curry)进行介绍.着重讲解underscore中对于偏函数应用的 ...

  6. 《你不知道的JavaScript》中卷 KYLE SIMPSON 著 单业 姜南 译

    一部分  类型和语法 1.内置类型(7) null.undefined.boolean.number.string.object.symbol(ES6新增,符号) 2.toString()和Json. ...

  7. JS闭包—你不知道的JavaScript上卷读书笔记(二)

    关于闭包,初学者会被绕的晕头转向,在学习的路上也付出了很多精力来理解. 让我们一起来揭开闭包神秘的面纱. 闭包晦涩的定义 看过很多关于闭包的定义,很多讲的云里雾里,晦涩难懂.让不少人以为闭包是多么玄乎 ...

  8. 读书笔记-你不知道的JavaScript(上)

    本文首发在我的个人博客:http://muyunyun.cn/ <你不知道的JavaScript>系列丛书给出了很多颠覆以往对JavaScript认知的点, 读完上卷,受益匪浅,于是对其精 ...

  9. JavaScript的返回值

    前期整理的JavaScript内容16篇附在文章末尾 一.return语句 有的时候,我们会希望函数将值返回给调用者,此时通过使用 return 语句就可以实现. return 语句的语法格式如下: ...

最新文章

  1. 在阿里云Kubernetes容器服务上打造TensorFlow实验室
  2. jQuery简单实现iframe的高度根据页面内容自适应的方法(转)
  3. 学习Kotlin(八)其他技术
  4. java dexclassloader_DexClassLoader加载apk
  5. 树莓派python教程_两个简易的树莓派初学者Python程序
  6. dual graph
  7. C#刷剑指Offer | 在O(1)时间删除链表节点
  8. ios html清除缓存图片,iOS,如何清理缓存的图片
  9. 工具类:获取 spring 容器中 bean
  10. python脚本怎么打印日志_python 接口测试1 --如何创建和打印日志文件
  11. 为什么说读博是最好的选择?
  12. Day3-php 字符串1
  13. 在Android上将ONNX神经网络模型与TensorFlow Lite结合使用
  14. /etc/profile、~/.bash_profile、~/.bashrc和/etc/bashrc
  15. 超实用:本科生如何发论文?
  16. no.8 python 和 Linux (笔记)
  17. while True:just do it
  18. iwanna 关卡设计(挖坑)指南
  19. iphone12绿色好看 iphone12系列哪个颜色好看
  20. 九连环课程设计c语言,用C语言编程解九连环

热门文章

  1. posix多线程程序使用条件变量的一个常见bug
  2. 2498-R06 SFP与线缆的选择与配置
  3. Xshell连接不上虚拟机Linux系统
  4. 13岁女孩因发布JavaScript无限循环代码被捕
  5. Javascript的数据结构与算法(一)
  6. C Primer Plus 第6章 C控制语句:循环 6.3 关系运算符和表达式
  7. [原创]WildPackets Omnipeek介绍
  8. Autodesk Infrastructure Map Server(AIMS)/MapGuide API 培训材料--第1章
  9. linux单用户模式修改密码(针对CentOS)
  10. 在同一台电脑上同时使用IE6和IE7