关键词:
一、值
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中也会返回true return ( 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) { // 判断是否是-0 if (v1 === 0 && v2 === 0) { return 1 / v1 === 1 / v2; } // 判断是否是NaN if (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》整理——this
最近在读一本进阶的JavaScript的书《你不知道的JavaScript(上卷)》,这次研究了一下“this”。当一个函数被调用时,会创建一个活动记录(执行上下文)。这个记录会包含函数在哪里被调用(调用栈)、函数的调用方法、... 查看详情
《你不知道的javascript》整理——作用域提升与闭包
最近在读一本进阶的JavaScript的书《你不知道的JavaScript(上卷)》,里面分析了很多基础性的概念。可以更全面深入的理解JavaScript深层面的知识点。 一、函数作用域1)函数作用域就是作用域在一个“Function”里,属于... 查看详情
《你不知道的javascript》整理——强制类型转换
JavaScript中通常分为两种类型转换,“隐式强制类型转换”(implicitcoercion)和“显式强制类型转换”(explicitcoercion)。下面所有代码的源码可以在此处查看。一、强制转换为字符串(ToString)1)ToString基本类型值的字符串化规则... 查看详情
《你不知道的javascript》系列分享专栏
《你不知道的JavaScript》系列分享专栏你不知道的JavaScript”系列就是要让不求甚解的JavaScript开发者迎难而上,深入语言内部,弄清楚JavaScript每一个零部件的用途《你不知道的JavaScript》已整理成PDF文档,点击可直接下载至本地查... 查看详情
javascript原生值与json的转换
--------------------------------------------------------------stringify方法的另外两种参数: ----------------------------------------------- 查看详情
javascript电子书合集,你不领一份儿吗
...言理解的一种有效方法。这里,略小坑给大家整理了36本JavaScript经典书籍的电子版,除了几本是扫描版外,大部分都是高清的。其中重点推荐几本经典著作:1.JavaScript权威指南(第六版)2.JavaScript高级程序设计(第三版)3.你不知道的... 查看详情
《你不知道的javascript[中卷]》14——asynquence附录
《你不知道的JavaScript[中卷]》【14】——asynquence附录 查看详情
你不知道的javascript(中卷)笔记
<!DOCTYPEhtml><html><head><metacharset="utf-8"><title>你不知道的javascript(中卷)</title></head><body><scripttype="text/javascript">/*//封装对象包装vara=newBool 查看详情
javascript你不知道的事儿
if(in)语句letnames=['Lily','Barry','Dendi','Boogie','Lily'];letnameNum=names.reduce((pre,cur)=>{if(curinpre){//pre中是否有cur属性pre[cur]++;}else{pre[cur]=1;//为pre这个对象添加cur属性,并且赋值为1}returnpre;},{ 查看详情
你不知道的javascript之类型
JavaScript是一门简单易用的语言,应用广泛,同时它的语言机制又十分复杂和微妙,即使经验丰富的开发人员也需要用心学习才能真正掌握。《你不知道的JavaScript》中是这样定义类型的:类型是值的内部特征,它定义了值的行为... 查看详情
你不知道的javascript(上卷卷)笔记
<!DOCTYPEhtml><html><head><metacharset="utf-8"><title>你不知道的javascript(上卷)</title></head><body></body></html> 查看详情
《你不知道的javascript》原型
1[[Prototype]][[Prototype]]是对其他对象的引用,几乎所有对象在创建时[[Prototype]]属性会被赋予非空值。varmyObject={a:2}myObject.a;//2 引用对象属性时会触发[[Get]]操作,它会检查对象本身是否有这个属性,如果有就使用它,但a不在myObj... 查看详情
《你不知道的javascript》——原型
你不知道的javascript:有趣的settimeout
你不知道的Javascript:有趣的setTimeout有时候,小小的细节往往隐藏着大大的智慧今天在回顾JavaScript进阶用法的时候,发现一个有趣的问题,话不多说,先上代码:for(varj=0;j<10;j++){setTimeout(function(){console.log(j)},5000)}看到这三行代... 查看详情
《你不知道的javascript》——this和对象原型
《你不知道的javascript》【3】——this和对象原型https://www.bilibili.com/video/BV1iE411P7UP 浅显的总结《你不知道的js》this指向 右查找的副作用:查找到顶层都找不到,就会抛出 查看详情
你不知道的javascript笔记
类型:JavaScript有7种内置类型空值(null)未定义(undefined)布尔值(boolean)数字(number)字符串(string)对象(object)符号(symbol) 除对象以外,其他统称为“基本类型” 用typeof运算符来查看值的类型typeofundefined ==="undefi... 查看详情
《你不知道的javascript》——闭包(代码片段)
第一部分还有最后的闭包没有讲...:1.非常浅显的阅读《你不知道的JavaScript》第一部分作用域与闭包https://www.bilibili.com/video/BV1jE411j7PU 从22分钟开始讲闭包 &nb 查看详情
你不知道的javascript(代码片段)
简介众所周知,JavaScript既是一门充满吸引力、简单易用的语言,又是一门具有许多复杂微妙技术的语言,即使是经验丰富的JavaScript开发者,如果没有认真学习的话也无法真正理解它们。如果每次遇到JavaScript中出乎意料的行为时... 查看详情