第一章 类型

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()修复:

  1. NaN不等于NaN。
  2. +0等于-0

ES5规范11.9.3.4-5定义:

  1. 如果Type(x)是数字,Type(y)是字符串,则返回 x == ToNumber(y) 的结果。
  2. 如果Type(x)是字符串,Type(y)是数字,则返回 ToNumber(x) == y 的结果。

ES5规范11.9.3.6-7定义:

  1. 如果Type(x)是布尔类型,则返回 ToNumber(x) == y 的结果。
  2. 如果Type(y)是布尔类型,则返回 x == ToNumber(y) 的结果。

可以使用a == null来替代a === undefined || a === null。 ES5规范11.9.3.2-3定义:

  1. 如果x为null,y为undefined,返回true。
  2. 如果x为undefined,y为null,返回true。

ES5规范11.9.3.8-9定义:

  1. 如果Type(x)是字符串或数字,Type(y)是对象,则返回 x == ToPrimitive(y)的结果。
  2. 如果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数据类型和语法的更多相关文章

  1. JavaScript数据类型 —— 基础语法(2)

    JavaScript基础语法(2) 数据类型 js中有六种数据类型,包括五种基本数据类型(Number,String,Boolean,Undefined,Null),和一种复杂数据类型(Object) ...

  2. Javascript:Javascript数据类型详解

    要成为一个优秀的前端工程师,系统的学习Javascript,有夯实的Javascript基础,以及对语言本身的深刻的理解,是基本功.从Javascript数据类型开始,我将对Javascript知识体 ...

  3. javascript的基本语法、数据结构

    本篇学习资料主要讲解javascript的基本语法.数据结构      无论是传统的编程语言,还是脚本语言,都具有数据类型.常量和变量.运算符.表达式.注释语句.流程控制语句等基本元素构成,这些基本元 ...

  4. JavaScript编程:javaScript核心基础语法

    1.javaScript核心基础语法: javaScript技术体系包含了5个内容:          1.核心语言定义:          2.原生对象和雷子对象:          3.浏览器对象 ...

  5. javascript 数据类型 -- 检测

    一.前言 在上一篇博文中 Javascript 数据类型 -- 分类 中,我们梳理了 javascript 的基本类型和引用类型,并提到了一些冷知识.大概的知识框架如下: 这篇博文就讲一下在写代码的过 ...

  6. JavaScript数据类型-2---Undefined、 Null、 Boolean、 Number、 String.

    学习目标 1.掌握JavaScript的数据类型 2.掌握typeof操作符 3.掌握Undefined 4.掌握null JavaScript的数据类型 ECMAScript中有5种简单数据类型(也 ...

  7. JavaScript核心基础语法

    1 什么是JavaScript? 是一种嵌入在网页中的程序段. 是一种解释型语言,被浏览器解释执行. 由Netscape发明,ECMA(欧洲计算机制造商协会)将其标准化. JavaScript借用了J ...

  8. (2)javascript的基本语法、数据结构、变量

    本篇学习资料主要讲解javascript的基本语法.数据结构.变量      无论是传统的编程语言,还是脚本语言,都具有数据类型.常量和变量.运算符.表达式.注释语句.流程控制语句等基本元素构成,这些 ...

  9. JavaScript的基础语法及DOM元素和事件

    一,JavaScript是什么? 1,JavaScript简称:js,是一种浏览器解释型语言,嵌套在HTML文件中交给浏览器解释执行.主要用来实现网页的动态效果,用户交互及前后端的数据传输等. 2,J ...

随机推荐

  1. 12-C#笔记-可空类型

    区别于C++,C#定义的NULL和0不同.更严格. C#的基本类型,区分为可空和不可空 主要涉及两个符号 单问号? 双问号?? 示例如下: using System; namespace Calcul ...

  2. 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 ...

  3. STL——list用法总结

    头文件 #include<list> 声明一个int型的list:list<int> a: 1.list的构造函数 list<int>a{1,2,3} list&l ...

  4. c04--数组

    0.展示PTA总分 1.本章学习内容总结 1.1学习内容总结 数组查找: 1.遍历法查找:从头遍历数组找对应数据. 2.二分法查找:适用于按顺序排列的整形数组. 插入数据: 先找到该数据,对数组进行移 ...

  5. quick如何打开工程或者示例

    quick如何打开工程或者示例 1. 那里打开工程 cc.ui.UIPushButton.new(images, {scale9 = true}) :setButtonSize(buttonWidth ...

  6. ReentrantLock源码简析

    概念 ReentrantLock,可重入锁.在多线程中,可以通过加锁保证线程安全. 加锁和解锁 加锁: public void lock() { sync.lock(); } 解锁 public vo ...

  7. 第8课 常量表达式(constexpr)

    一. const 和constexpr的区别 (一)修饰变量时,const为“运行期常量”,即运行期数据是只读的.而constexpr为“编译期”常量,这是const无法保证的.两者都是对象和函数接口 ...

  8. Qt应用程序主窗口之二:拖放操作与打印文档

    一.拖放操作 对于一个实用的应用程序,不仅希望能从文件菜单中打开一个文件,更希望可以通过拖动直接将桌面上的文件拖入程序界面上来打开,就像可以将.pro文件拖入Creator中来打开整个项目一样.Qt中 ...

  9. 小心!做 UI 自动化一定要跨过这些坑

    一 .引子 UI自动化,在移动互联网时代的今天,一直都是在各大测试社区最为火爆的一个TOPIC.甚至在测试同行面前一提起自动化,大家就会自然而然的问:“恩,你们是用的什么框架?appium?还是rob ...

  10. 显示屏display的API

    display是代表25个led阵列显示屏的对象,包括以下的功能方法 # 获取(x,y)灯的亮度. 从 0 (不亮) to 9 (最亮). display.get_pixel(x, y) # 设置(x ...