JavaScript数据类型和语法
第一章 类型
1.2 内置类型
使用 typeof 检测对象类型并不是非常安全的行为:
// 安全的
typeof undefined // 'undefined'
typeof true // 'boolean'
typeof 42 // 'number'
typeof '42' // 'string'
typeof {} // 'object'
typeof Symbol() // 'symbol'
typeof (function(){}) // 'function'
// 不安全的
typeof null // 'object'
typeof [] // 'object'
函数对象可以拥有属性。函数的length属性为其声明的参数个数。
⚠️
- null 是基本类型中唯一一个“假值”!!!
- function(函数)也是JavaScript 的一个内置类型。然而查阅规范就会知道, 它实际上是 object 的一个“子类型”。具体来说,函数是“可调用对象”,它有一个内部属 性 [[Call]],该属性使其可以被调用(函数不仅是对象,还可以拥有属性)
1.3 值和类型
JavaScript 中的变量是没有类型的,只有值才有。变量可以随时持有任何类型的值
1.3.1 undefined和undeclared
声明但还没有赋值的变量是undefined。 还没有在作用域声明过的变量是undeclared(【严格模式】下访问会抛出ReferenceError)。
对于 undeclared(或者 not defined)变量,typeof 照样返回 "undefined",并且不会报错,返回'undefined'。
或者当其为全局变量的时候,用window的点操作符去访问,也不会报错。
第二章 值
2.1 数组
在稀疏数组中,中间未赋值的内容会初始化为undefined
var a = [];
a[0] = 1;
a[2] = 3;
a[1]; // undefined
a.length; // 3
⚠️也可以用键访问(输入不能转换为数字的字符串)去设置数组的属性,但他们不会纳入数组的值和length,而是作为独立的属性存在。
var arr = [];
arr[0] = 1;
arr["2"] = 2;
arr["obb"] = 3;
arr.length; // 3
arr[2]; // 2, “2”字符串键值 被强制转换为十进制数字
arr.obb; arr["obb"]; // 3
类数组(Array Like)(一组通过数字索引的值)
如:DOM查询返回的DOM元素列表;arguments(es6废除)
对象表示其类型类似于数组,但是原型链上没有Array对象,自然也无法直接使用Array的原型方法。
转换类数组使用ES5的Array.prototype.slice.call(arrayLikeObj),slice() 返回参数列表(上例中是一个类数组)的一个数组复本。或者ES6的Array.from(arrayLikeObj)。
function foo() {
var arr = Array.prototype.slice.call( arguments );
或 var arr = Array.from( arguments );
arr.push( "bam" );
console.log( arr );
}
foo( "bar", "baz" ); // ["bar","baz","bam"]
2.2 字符串
和数组相似,都有 length 属性以及 indexOf(..),和 concat(..) 方法
可以通过“借用”数组的非变更方法来处理字符串:字符串没有join、map方法
a.join; // undefined
a.map; // undefined
var c = Array.prototype.join.call( a, "-" );
var d = Array.prototype.map.call( a, function(v){
return v.toUpperCase() + ".";
} ).join( "" );
JS中字符串的单个字符不可变,不能用键访问去改变字符串的某个字符。 字符串也可以借用数组的一些原型方法来进行处理。一个常用场景是字符串的倒置:
var c = a
// 先转为Array
.split('')
// 再倒置Array
.reverse()
// 最后转回字符串
.join('');
2.3 数字
直接对数字字面量调用原型方法,有时候需要两个点(.),这是因为第一个点会被理解为小数点。 Number.prototype上有这些方法:
- toExponential(),转为指数格式,特别大或小的数字默认用指数格式显示
- toFixed(),指定小数位数
- toPrecision(),指定有效位数的显示位数
// 无效语法:
42.toFixed( 3 ); // SyntaxError ,因为 . 被视为常量 42. 的一部分
// 下面的语法都有效:
(42).toFixed( 3 ); // "42.000"
0.42.toFixed( 3 ); // "0.420"
42..toFixed( 3 ); // "42.000"
其他进制的问题: - 0xf3,16进制
- 0b11110011,2进制
- 0o363,8进制
2.3.2 较小的数值
0.1 + 0.2 === 0.3; // false,二进制浮点数中的 0.1 和 0.2 并不是十分精确,相加的结果0.30000000000000004
解决方法:误差范围值,即机器精度(machine epsilon)。 使用机器精度,可以判断两个浮点值的运算结果是否等于另一个数字。Math.abs(n1 - n2) < Number.EPSILON
2.3.3 整数安全范围
安全的最大整数是2^53 - 1,即9007199254740991,ES6中为Number.MAX_SAFE_INTEGER。同理,最小整数为其负数-(2^53 - 1),ES6中为Number.MIN_SAFE_INTEGER。
2.3.4 整数检测
- Number.isInteger,检测是否为整数
- Number.isSafeInteger,检测是否为安全的整数
2.3.5 32位有符号整数
数位运算符只适用于32位的整数,其他数位将会被忽略。
2.4 特殊数值
2.4.1 不是值的值
空值:
- null,指空值,曾经赋值,现在没有值empty value
- undefined,指没有值,从未被赋值,missing value
null 是一个特殊关键字,不是标识符,我们不能将其当作变量来使用和赋值。然而 undefined 却是一个标识符,可以被当作变量来使用和赋值。
2.4.2 undefined
通过void运算符可以返回undefined。
var a = 42;
console.log( void a, a ); // undefined 4,void 并不改变表达式的结果, 只是让表达式不返回值:
2.4.3 特殊的数字
NaN是一个警戒值,表示数学运算没有成功,失败后返回的结果。
NaN 是一个特殊值,它和自身不相等,是唯一一个非自反 NaN != NaN 为 true
ES6 判断是否为NaN:Number.isNaN(a)Infinity表示无穷数,数学运算结果溢出
var a = 1 / 0; // Infinity
var b = -1 / 0; // -Infinity规范规定,如果数学运算(如加法)的结果超出处理范围,则由 IEEE 754 规范中的“就 近取整”(round-to-nearest)模式来决定最后的结果。
计算结果一旦溢出为无穷数(infinity)就无法再得到有穷数-0表示第一位正负位为负,保留了该信息,后续处理的时候会携带它。
对负零进行字符串化会返回 "0"; 如果反过来将其从字符串转换为数字,得到的结果是准确的
-0 == 0; // true
-0 === 0; // true⚠️为什么需要负0:保留0的符号位,来获取方向信息。
2.4.4 特殊等式
ES6:Object.is(..):来判断两个值是否绝对相等(用来处理特殊比较,否则使用或=解)
- Object.is(NaN, NaN) === true
- Object.is(+0, -0) === false
2.5 值和引用
简单值(即基本类型值),通过值复制的方式来赋值/传递。 复合值(对象、数组和函数),总是通过引用复制的方式来赋值/传递。 减少引用复制副作用的方法是,传递时候采用复本创建的方式,比如a.slice()。
slice(..) 不带参数会返回当前数组的一个浅复本
⚠️标量基本类型值是不可更改的(字符串和布尔也是如此)。
function foo(x) {
x = x + 1;
x; // 3
}
var a = 2;
var b = new Number( a ); // Object(a)也一样
foo( b );
console.log( b ); // 是2,不是 3
.......待补充!!
第四章 强制类型转换
4.1 值类型转换
显式值类型转换称为类型转换,发生在静态语言的编译阶段。隐式的情况称为强制类型转换,发生在动态语言的运行时。 JS中只存在强制类型转换(运行时中转换),只会返回标量基本类型值,比如字符串、数字和布尔值,不会返回对象或函数。
4.2 抽象值操作
4.2.1 toString
- null -> 'null'
- undefined -> 'undefined'
- true/false -> 'true'/'false'
- 极大数,极小数 -> 指数形式表达
- Array -> arr.join(',')
- Object -> obj.toPrimitive
对于JSON安全:包含undefined、function、symbol和循环引用的对象不符合JSON的结构标准,它们在stringify操作中会被忽略,数组中转为null。 当一个对象JSON不安全时,可以定义其toJSON()方法来返回一个JSON安全的对象,它在JSON.stringify的时候会隐式调用。 JSON.stringify(target, replacer?, space?)的replacer可以是一个字符串数组或函数,用于指定哪些属性需要纳入处理。space指定缩进格式。
4.2.2 ToNumber
- true/false -> 1/0
- undefined -> NaN
- null -> 0
- 对象:调用toPrimitive,首先检查该值有没有valueOf()方法,如有则执行,如没有就使用toString()方法,对最终结果进行强制类型转换。如果两者均不返回基本类型值,抛出TypeError错误。
4.2.3 toBoolean
JS中的假值通常为基本类型:
- undefined
- null
- false
- +0, -0, NaN
- ''(空字符串)
4.3 显式强制类型转换
4.3.1 字符串和数字之间的显式转换
Number转String:
- String(a)
- a.toString()
String转Number:
- Number(b)
- Number.parseInt(b) / Number.parseFloat(b)
- +b:注意不要两个+号连用变成自增,必要时中间加空格。
其他应用:
- 日期转数字(毫秒级时间戳):var d = new Date(); +d;,但是更建议使用其getTime()方法。
- ~:JS中的取反操作类似于转换为数字,然后取-(x+1),常用于将-1转为0
- |:后面跟一个toInt32后为0的值(0,NaN等),可以起到ToNumber的作用。
4.3.2 显式解析数字字符串
Number.parseInt()和Number.parseFloat()方法允许字符串中含有非数字字符,遇到非数字字符就停止解析,返回结果。 对于非字符串,会隐式调用其toString()方法。
// 得到Infinity,解析为'Infinity',第一个字符I的ASCII码为18,所以返回结果是18
// 十进制下返回NaN
Number.parseInt(Infinity, 19);
// toString()解析成了8e-7,返回8
Number.parseInt(0.0000008)
4.3.3 显式转换为布尔值
Boolean()可以显式转换为布尔值,另一种方法是用!和!!。 if(...) {}的判断语句中,如果没有特别声明布尔值,就会调用toBoolean()方法。
4.4 隐式强制类型转换
4.4.2 字符串和数字之间的隐式强制类型转换
+运算符能用于数字加法,也能用于字符串拼接。它一旦遇到两边有一者不是Number的情况,就会对双方调用toPrimitive()或toString()方法,然后进行字符串拼接。 -运算符仅用于数字减法,一旦遇到两边有一者表示Number的情况,就会对双方调用ToNumber()行为,然后计算减法。
4.4.5 ||和&&
它们的返回值是两个操作数中的一个。
||:
- 如果前者判断为true,就返回前者,否则返回后者。
- 类似于a? a:b。
- 常用作空值合并运算符。
&&:
- 如果前者判断为true,就返回后者,否则返回前者。
- 类似于a? b:a。
- 常用作守护运算符,前面的表达式为后面把关。比如if(a){ foo(); }可以改成a && foo();。
4.4.6 Symbol的强制类型转换
Symbol只支持显式强制类型转换。
var s1 = new Symbol('cool');
String(s1); // 'Symbol(cool)'
s1+ ''; // TypeError
4.5 宽松相等和严格相等
4.5.2 抽象相等
允许再相等比较中进行强制类型转换,=不允许。 特别注意,以下情况用Object.is()修复:
- NaN不等于NaN。
- +0等于-0
ES5规范11.9.3.4-5定义:
- 如果Type(x)是数字,Type(y)是字符串,则返回 x == ToNumber(y) 的结果。
- 如果Type(x)是字符串,Type(y)是数字,则返回 ToNumber(x) == y 的结果。
ES5规范11.9.3.6-7定义:
- 如果Type(x)是布尔类型,则返回 ToNumber(x) == y 的结果。
- 如果Type(y)是布尔类型,则返回 x == ToNumber(y) 的结果。
可以使用a == null来替代a === undefined || a === null。 ES5规范11.9.3.2-3定义:
- 如果x为null,y为undefined,返回true。
- 如果x为undefined,y为null,返回true。
ES5规范11.9.3.8-9定义:
- 如果Type(x)是字符串或数字,Type(y)是对象,则返回 x == ToPrimitive(y)的结果。
- 如果Type(x)是对象,Type(y)是字符串或数字,则返回 ToPrimitive(x) == y的结果。
特殊情况说明:
'0' == false; // true, Number('0') == Number(false)
false == 0; // true, Number(false) == 0
false == ''; // true, Number(false) == Number('')
false == []; // true, Number(false) == ToPrimitive([])
'' == 0; // true, Number('') == 0
'' == []; // true, Number('') == ToPrimitive([])
0 == []; // true, 0 == ToPrimitive([])
4.6 抽象关系比较
比较双方首先调用ToPrimitive,如果出现非字符串,就根据ToNumber规则将双方转换为数字来比较。如果比较双方都是字符串,就按字母顺序来逐位比较。 需要注意的是,a <= b在JS中被处理成!(b < a)。
第五章 语法
5.1 语句和表达式
JS中,表达式可以返回一个结果值。
5.1.1 语句的结果值
语句都有一个结果值(undefined也算)。 对于代码块,其结果值就如同一个隐式的返回,即返回最后一个语句的结果值。
5.1.2 表达式的副作用
语句系列逗号运算符:在()中写入多个语句,用逗号','分隔,返回最后一个语句的结果值。 比如b = (a++, a);可以返回a++之后的a。
5.2 运算符优先级
&&高于||。
JavaScript数据类型和语法的更多相关文章
- JavaScript数据类型 —— 基础语法(2)
JavaScript基础语法(2) 数据类型 js中有六种数据类型,包括五种基本数据类型(Number,String,Boolean,Undefined,Null),和一种复杂数据类型(Object) ...
- Javascript:Javascript数据类型详解
要成为一个优秀的前端工程师,系统的学习Javascript,有夯实的Javascript基础,以及对语言本身的深刻的理解,是基本功.从Javascript数据类型开始,我将对Javascript知识体 ...
- javascript的基本语法、数据结构
本篇学习资料主要讲解javascript的基本语法.数据结构 无论是传统的编程语言,还是脚本语言,都具有数据类型.常量和变量.运算符.表达式.注释语句.流程控制语句等基本元素构成,这些基本元 ...
- JavaScript编程:javaScript核心基础语法
1.javaScript核心基础语法: javaScript技术体系包含了5个内容: 1.核心语言定义: 2.原生对象和雷子对象: 3.浏览器对象 ...
- javascript 数据类型 -- 检测
一.前言 在上一篇博文中 Javascript 数据类型 -- 分类 中,我们梳理了 javascript 的基本类型和引用类型,并提到了一些冷知识.大概的知识框架如下: 这篇博文就讲一下在写代码的过 ...
- JavaScript数据类型-2---Undefined、 Null、 Boolean、 Number、 String.
学习目标 1.掌握JavaScript的数据类型 2.掌握typeof操作符 3.掌握Undefined 4.掌握null JavaScript的数据类型 ECMAScript中有5种简单数据类型(也 ...
- JavaScript核心基础语法
1 什么是JavaScript? 是一种嵌入在网页中的程序段. 是一种解释型语言,被浏览器解释执行. 由Netscape发明,ECMA(欧洲计算机制造商协会)将其标准化. JavaScript借用了J ...
- (2)javascript的基本语法、数据结构、变量
本篇学习资料主要讲解javascript的基本语法.数据结构.变量 无论是传统的编程语言,还是脚本语言,都具有数据类型.常量和变量.运算符.表达式.注释语句.流程控制语句等基本元素构成,这些 ...
- JavaScript的基础语法及DOM元素和事件
一,JavaScript是什么? 1,JavaScript简称:js,是一种浏览器解释型语言,嵌套在HTML文件中交给浏览器解释执行.主要用来实现网页的动态效果,用户交互及前后端的数据传输等. 2,J ...
随机推荐
- 12-C#笔记-可空类型
区别于C++,C#定义的NULL和0不同.更严格. C#的基本类型,区分为可空和不可空 主要涉及两个符号 单问号? 双问号?? 示例如下: using System; namespace Calcul ...
- Generating YouTube-like IDs in Postgres using PL/V8 and Hashids
转自:https://blog.abevoelker.com/2017-01-03/generating-youtube-like-ids-in-postgres-using-plv8-and-has ...
- STL——list用法总结
头文件 #include<list> 声明一个int型的list:list<int> a: 1.list的构造函数 list<int>a{1,2,3} list&l ...
- c04--数组
0.展示PTA总分 1.本章学习内容总结 1.1学习内容总结 数组查找: 1.遍历法查找:从头遍历数组找对应数据. 2.二分法查找:适用于按顺序排列的整形数组. 插入数据: 先找到该数据,对数组进行移 ...
- quick如何打开工程或者示例
quick如何打开工程或者示例 1. 那里打开工程 cc.ui.UIPushButton.new(images, {scale9 = true}) :setButtonSize(buttonWidth ...
- ReentrantLock源码简析
概念 ReentrantLock,可重入锁.在多线程中,可以通过加锁保证线程安全. 加锁和解锁 加锁: public void lock() { sync.lock(); } 解锁 public vo ...
- 第8课 常量表达式(constexpr)
一. const 和constexpr的区别 (一)修饰变量时,const为“运行期常量”,即运行期数据是只读的.而constexpr为“编译期”常量,这是const无法保证的.两者都是对象和函数接口 ...
- Qt应用程序主窗口之二:拖放操作与打印文档
一.拖放操作 对于一个实用的应用程序,不仅希望能从文件菜单中打开一个文件,更希望可以通过拖动直接将桌面上的文件拖入程序界面上来打开,就像可以将.pro文件拖入Creator中来打开整个项目一样.Qt中 ...
- 小心!做 UI 自动化一定要跨过这些坑
一 .引子 UI自动化,在移动互联网时代的今天,一直都是在各大测试社区最为火爆的一个TOPIC.甚至在测试同行面前一提起自动化,大家就会自然而然的问:“恩,你们是用的什么框架?appium?还是rob ...
- 显示屏display的API
display是代表25个led阵列显示屏的对象,包括以下的功能方法 # 获取(x,y)灯的亮度. 从 0 (不亮) to 9 (最亮). display.get_pixel(x, y) # 设置(x ...