javascript 权威指南第六版
// 提出问题 + 实例 + 练习
第一部分
基础知识
用;来分隔开。如果一条语句单独占一行,可以不用;
数据类型
- (基本数据类型)原始数据类型:数字Number,字符串String,布尔值Boolean,null ,undefined symbol symbol(数据)返回一个唯一的symbol数据类型的值。symbol(‘foo’) !== symbol(‘foo’)可以用来当key值。
- (引用数据类型)对象类型:键值对。
- 特殊对象:全局对象,JavaScript代码中,Window对象充当了全局对象。
- 数组
- 函数:调用函数执行可执行代码,返回运算结果
js变量无类型。变量可以被赋予任何类型的值,
js不区分整型浮点型数值,所有的数组都是浮点类型。整型直接量:es6支持十六、十进制,禁止八进制。
正数溢出结果:infinity
负数溢出结果:0
大整数:又叫高精度数,在这之前你可能更愿意使用大整数进行重要的金融计算,例如,要使用整数“分”而不要使用小数“元”进行基于货币
解决浮点数精度问题的计算:
数据转换
- 转换为布尔值(调用Boolean()方法)
- 转换为数字(调用Number()、parseInt()和parseFloat()方法)
- 转换为字符串(调用.toString()或者String()方法)
null和underfined没有.toString方法
!!会把右边的值转换为布尔值
隐式数据类型转换
+
'+'两侧只要有一侧是字符串,另一侧的数字则会自动转换成字符串,因为其中存在隐式转换
// String + String -> concatenation
'foo' + 'bar' // "foobar"
// Number + String -> concatenation
5 + 'foo' // "5foo"
// String + Boolean -> concatenation
'foo' + false // "foofalse"
-
如果有一边是字符,会把字符转成数字。
var a = '11';
a = a - '';
alert(typeof a);// -->number
数据类型的判断
- typeof,
console.log(typeof 2); // number
console.log(typeof true); // boolean
console.log(typeof 'str'); // string
console.log(typeof []); // object []数组的数据类型在 typeof 中被解释为 object
console.log(typeof function(){}); // function
console.log(typeof {}); // object
console.log(typeof undefined); // undefined
console.log(typeof null); // object null 的数据类型被 typeof 解释为 object
- instanceof,
console.log(2 instanceof Number); // false
console.log(true instanceof Boolean); // false
console.log('str' instanceof String); // false
console.log([] instanceof Array); // true
console.log(function(){} instanceof Function); // true
console.log({} instanceof Object); // true
// console.log(undefined instanceof Undefined);
// console.log(null instanceof Null);
- constructor,
console.log((2).constructor === Number); // true
console.log((true).constructor === Boolean); // true
console.log(('str').constructor === String); // true
console.log(([]).constructor === Array); // true
console.log((function() {}).constructor === Function); // true
console.log(({}).constructor === Object); // true
这里有一个坑,如果我创建一个对象,更改它的原型,constructor就会变得不可靠了
function Fn(){};
Fn.prototype=new Array();
var f=new Fn();
console.log(f.constructor===Fn); // false
console.log(f.constructor===Array); // true
- Object.prototype.toString.call()
var a = Object.prototype.toString;
console.log(a.call(2));// [object Number]
console.log(a.call(true));// [object Boolean]
console.log(a.call('str'));// [object String]
console.log(a.call([]));// [object Array]
console.log(a.call(function(){}));// [object Function]
console.log(a.call({}));// [object Object]
console.log(a.call(undefined));// [object Undefined]
console.log(a.call(null));// [object Null]
a=b=0
实例1
function () {
let a = b = 0
}
为什么 b是一个全局变量??
因为赋值运算是从右往左的。所以该语句实际上是 b = 0 、let a = b
b隐性声明为全局变量。因为声明语句不带关键保留字默认是var声明
js内置对象
全局的对象( global objects )或称标准内置对象,不要和 “全局对象(global object)” 混淆。这里说的全局的对象是说在全局作用域里的对象。全局作用域中的其他对象可以由用户的脚本创建或由宿主程序提供。
标准内置对象的分类
(1)值属性,这些全局属性返回一个简单值,这些值没有自己的属性和方法。
例如 Infinity、NaN、undefined、null 字面量
(2)函数属性,全局函数可以直接调用,不需要在调用时指定所属对象,执行结束后会将结果直接返回给调用者。
例如 eval()、parseFloat()、parseInt() 等
(3)基本对象,基本对象是定义或使用其他对象的基础。基本对象包括一般对象、函数对象和错误对象。
例如 Object、Function、Boolean、Symbol、Error 等
(4)数字和日期对象,用来表示数字、日期和执行数学计算的对象。
例如 Number、Math、Date
(5)字符串,用来表示和操作字符串的对象。
例如 String、RegExp
(6)可索引的集合对象,这些对象表示按照索引值来排序的数据集合,包括数组和类型数组,以及类数组结构的对象。例如 Array
(7)使用键的集合对象,这些集合对象在存储数据时会使用到键,支持按照插入顺序来迭代元素。
例如 Map、Set、WeakMap、WeakSet
(8)矢量集合,SIMD 矢量集合中的数据会被组织为一个数据序列。
例如 SIMD 等
(9)结构化数据,这些对象用来表示和操作结构化的缓冲区数据,或使用 JSON 编码的数据。
例如 JSON 等
(10)控制抽象对象
例如 Promise、Generator 等
(11)反射
例如 Reflect、Proxy
(12)国际化,为了支持多语言处理而加入 ECMAScript 的对象。
例如 Intl、Intl.Collator 等
(13)WebAssembly
(14)其他
例如 arguments
{} 的 valueOf 结果为 {} ,toString 的结果为 "[object Object]"
[] 的 valueOf 结果为 [] ,toString 的结果为 ""
当我们对两种类型使用 typeof 进行判断的时候,Null 类型化会返回 “object”,这是一个历史遗留的问题。当我们使用双等 号对两种类型的值进行比较时会返回 true,使用三个等号时会返回 false。
String对象的属性和方法
// endsWith 是否以指定的字符结尾 return true or false
var str = 'ba'
console.log(str.endsWith('a'))// true
// charAt() 返回一个指定的字符.string.chartAt(number)
const charat = str.charAt(0)
console.log(charat)// b
// charCodeAt() 返回utf16
const charcodeat = str.charCodeAt(str.charAt(1))
console.log(str.charAt(1), ':', charcodeat)
// concat 连接多个字符,返回新的数组
str.concat('11', '22', '333', '44')// ba112233344
str.concat(['11', '22', '333', '44'])// ba11,22,333,44
// includes() 区分大小写
// str.includes(target, 开始搜索的位置index) return true or false
var str = 'To be, or not to be, that is the question.';
console.log(str.includes('To be')); // true
console.log(str.includes('question')); // true
console.log(str.includes('nonexistent')); // false
console.log(str.includes('To be', 1)); // false
console.log(str.includes('TO BE')); // false
// indexOf 返回目标子串在字符串中第一次出现的index,没有的返回-1
str = 'babb'
str.indexOf('a', 1)// 1 found return index
str.indexOf('a', 2)// -1 not found return -1
// lastIndexOf() target appears last index
返回数组最后一次出现的位置
// match(regx||字符串) 返回匹配的字符数组return match array
str = 'Baba1BBaa2bbaa3'
const re = /[a-b]/gi
console.log(re)
str.match(re)
/**
\* [
'B', 'a', 'b', 'a',
'B', 'B', 'a', 'a',
'b', 'b', 'a', 'a'
]
*/
// repeat (time) 字符重复的元素,相当于连接字符串本身
str = '123'
str.repeat(0)// ' '
str.repeat(1)// 123
str.repeat(1.5) // 123
// replace
return new string ,do not change origin string string.replace(reg or string, target)
(function () {
const str = 'arra'
var regx = /a/gi
// 使用gi正则和字符的区别.
console.log(str.replace(regx, 'replace'))// replacerrreplace
console.log(str.replace('a', 'replace'))// replacerra
console.log(str)// arr
})()
// slice
return new ,not change origin slice(startIndex[, endIndex])
// string.split () unsuggest.
不建议是用split来分割字符串
console.log('𝟘𝟙𝟚𝟛'.split(''))
/**
\* [
'�', '�', '�',
'�', '�', '�',
'�', '�'
]
*/
// instead:
解构
function tosplit (str) {
const arr = [...str]
console.log(arr)
}
tosplit('𝟘𝟙𝟚𝟛')// [ '𝟘', '𝟙', '𝟚', '𝟛' ]
// or array.from
(
function () {
console.log(Array.from('𝟘𝟙𝟚𝟛'))// [ '𝟘', '𝟙', '𝟚', '𝟛' ]
console.log(Object.assign([], '𝟘𝟙𝟚𝟛'))
/**
\* [
'�', '�', '�',
'�', '�', '�',
'�', '�'
]
*/
}
)()
// substr
substr(start, length) 和slice的区别???
// slice(start,end) substr(start, length)
str = 'substr'
var num = 123
// num.length // undefined!!
console.log(str.substr(0, 3),
str.length,
num.length,// undefined 数字没有length属性
Object.prototype.toString.call(num.toString())
)// sub 6 undefined [object String]
Array
把可遍历的对象或者伪数组变为数组
参数: // array.from(interate or 伪数组 [,回调[,指定回调的this]])
第二个可选: 对每一个遍历元素执行的回调函数。第三个参数指定回调函数的this 例如:
var arr = [1, 2, 3]
var obj = {
name: 'rong'
}
console.log(Array.from([1, 3, 4],
// x => {
// x + this.name 箭头函数没有this
// },
// function call (x) {
// x + this.name
// },
// x => x + x, // 箭头函数有一个隐式返回return,
function call (x) {
return this.name + x
},
obj))
##### json对象
两个作用
1 有用于解析json数据交换格式子集的parse()方法
2 将对象转换成json的stringify()
除此之外没有其他作用,不能被调用和作为构造函数。
date对象
Date() | 返回当日的日期和时间。 |
---|---|
getDate() | 从 Date 对象返回一个月中的某一天 (1 ~ 31)。 |
getDay() | 从 Date 对象返回一周中的某一天 (0 ~ 6)。 |
getMonth() | 从 Date 对象返回月份 (0 ~ 11)。 |
getFullYear() | 从 Date 对象以四位数字返回年份。 |
getYear() | 请使用 getFullYear() 方法代替。 |
getHours() | 返回 Date 对象的小时 (0 ~ 23)。 |
getMinutes() | 返回 Date 对象的分钟 (0 ~ 59)。 |
getSeconds() | 返回 Date 对象的秒数 (0 ~ 59)。 |
getMilliseconds() | 返回 Date 对象的毫秒(0 ~ 999)。 |
getTime() | 返回 1970 年 1 月 1 日至今的毫秒数。 |
getTimezoneOffset() | 返回本地时间与格林威治标准时间 (GMT) 的分钟差。 |
getUTCDate() | 根据世界时从 Date 对象返回月中的一天 (1 ~ 31)。 |
getUTCDay() | 根据世界时从 Date 对象返回周中的一天 (0 ~ 6)。 |
getUTCMonth() | 根据世界时从 Date 对象返回月份 (0 ~ 11)。 |
getUTCFullYear() | 根据世界时从 Date 对象返回四位数的年份。 |
getUTCHours() | 根据世界时返回 Date 对象的小时 (0 ~ 23)。 |
getUTCMinutes() | 根据世界时返回 Date 对象的分钟 (0 ~ 59)。 |
getUTCSeconds() | 根据世界时返回 Date 对象的秒钟 (0 ~ 59)。 |
getUTCMilliseconds() | 根据世界时返回 Date 对象的毫秒(0 ~ 999)。 |
parse() | 返回1970年1月1日午夜到指定日期(字符串)的毫秒数。 |
setDate() | 设置 Date 对象中月的某一天 (1 ~ 31)。 |
setMonth() | 设置 Date 对象中月份 (0 ~ 11)。 |
setFullYear() | 设置 Date 对象中的年份(四位数字)。 |
setYear() | 请使用 setFullYear() 方法代替。 |
setHours() | 设置 Date 对象中的小时 (0 ~ 23)。 |
setMinutes() | 设置 Date 对象中的分钟 (0 ~ 59)。 |
setSeconds() | 设置 Date 对象中的秒钟 (0 ~ 59)。 |
setMilliseconds() | 设置 Date 对象中的毫秒 (0 ~ 999)。 |
setTime() | 以毫秒设置 Date 对象。 |
setUTCDate() | 根据世界时设置 Date 对象中月份的一天 (1 ~ 31)。 |
setUTCMonth() | 根据世界时设置 Date 对象中的月份 (0 ~ 11)。 |
setUTCFullYear() | 根据世界时设置 Date 对象中的年份(四位数字)。 |
setUTCHours() | 根据世界时设置 Date 对象中的小时 (0 ~ 23)。 |
setUTCMinutes() | 根据世界时设置 Date 对象中的分钟 (0 ~ 59)。 |
setUTCSeconds() | 根据世界时设置 Date 对象中的秒钟 (0 ~ 59)。 |
setUTCMilliseconds() | 根据世界时设置 Date 对象中的毫秒 (0 ~ 999)。 |
toSource() | 返回该对象的源代码。 |
toString() | 把 Date 对象转换为字符串。String(false)==false.toString() =>"false" |
toTimeString() | 把 Date 对象的时间部分转换为字符串。 |
toDateString() | 把 Date 对象的日期部分转换为字符串。 |
toGMTString() | 请使用 toUTCString() 方法代替。 |
toUTCString() | 根据世界时,把 Date 对象转换为字符串。 |
toLocaleString() | 根据本地时间格式,把 Date 对象转换为字符串。 |
toLocaleTimeString() | 根据本地时间格式,把 Date 对象的时间部分转换为字符串。 |
toLocaleDateString() | 根据本地时间格式,把 Date 对象的日期部分转换为字符串。 |
UTC() | 根据世界时返回 1970 年 1 月 1 日 到指定日期的毫秒数。 |
valueOf() | 返回 Date 对象的原始值。 |
RgeExp正则表达式
RgeExp是一种强大和常用的文本处理工具
用\d
可以匹配一个数字,\w
可以匹配一个字母或数字
\s
可以匹配一个空格(也包括Tab等空白符),所以\s+
toString表示至少有一个空格
\d{3,8}
表示3-8个数字
RegExp对象的test()
方法用于测试给定的字符串是否符合条件。
var re = /^\d{3}\-\d{3,8}$/;
re.test('010-12345'); // true
re.test('010-1234x'); // false
re.test('010 12345'); // false
要匹配变长的字符,在正则表达式中,用*
表示任意个字符(包括0个),用+
表示至少一个字符,用?
表示0个或1个字符,用{n}
表示n个字符,用{n,m}
表示n-m个字符:
除了简单地判断是否匹配之外,正则表达式还有提取子串的强大功能。用()
表示的就是要提取的分组(Group)
var re4 = /\d{3}\-\d{0,9}/
// qq邮箱匹配
var re5 = /[1-9][\d{4,}][email protected]/
// 手机号匹配
var re6 =/1[3-8][0-9]{9}/
var re7 =/^1[3-8][0-9]{9}$/
console.log(re4.test('111-349573'))//true
console.log(re5.test('[email protected]'))//true
console.log(re6.test('13302339263'))//true
console.log(re6.test('133023392sdfa'))//false
console.log(re6.test('133023392632'))//true
console.log(re7.test('133023392632'))//false
var test = /^[\w]+\@[\w]+\.(com|org)$/ //或不是用[com|org]而是用(com|org)
console.log('test'+test.test('[email protected]'))//false
null
对null执行typeof预算,结果返回字符串“object”,也就是说,可以将null认为是一个特殊的对象值,含义是“非对象”
undefined
undefined是预定义的全局变量(它和null不一样,它不是关键字),它的值就是“未定义”。用typeof运算符得到undefined的类型,则返回“undefined“
全局对象
当JavaScript解释器启动时(或者任何Web浏览器加载新