《深入理解JavaScript》笔记

《深入理解JavaScript》笔记

    • 1、基础JavaScript
      • 1.1、背景
        • 1.1.1、JavaScript与ECMAScript
        • 1.1.2、JavaScript的影响和本质
      • 1.2、语法
        • 1.2.1、语法概述
        • 1.2.2、语句和表达式
        • 1.2.3、分号
        • 1.2.4、注释
      • 1.3、变量和赋值
        • 1.3.1、赋值
        • 1.3.2、复合赋值运算符
        • 1.3.3、标识符与变量名
      • 1.4、值
        • 1.4.1、原始值和对象
        • 1.4.2、原始值(primitives)
        • 1.4.3、对象
        • 1.4.4、undefined和null
        • 1.4.5、使用 typeof 和 instanceof 对值分类
      • 1.5 布尔值 true false
        • 1.5.1 真值与假值
        • 1.5.2、二元逻辑运算符
        • 1.5.3、等式运算符
      • 1.6、数字
      • 1.7、运算符
        • 1.8字符串
        • 1.8.1 字符串运算符
        • 1.8.2、字符串方法
      • 1.9、语句
        • 1.9.1、条件语句
        • 1.9.2、循环语句
      • 1.10、函数
        • 1.10.1、函数声明的提升特性
        • 1.10.2、特殊的变量arguments
        • 1.10.3、参数太多或太少
        • 1.10.4、可选参数
        • 1.10.5、强制参数长度
        • 1.10.6、将arguments转换为数组
        • 1.11、异常捕获
      • 1.12、严格模式
      • 1.13、变量作用域和闭包
        • 1.13.1、变量是函数作用域的
        • 1.13.2、变量的提升特性
        • 1.13.3、闭包
        • 1.13.4、IIFE模式:引入一个新的作用域
      • 1.14、对象和构造函数
        • 1.14.1、单一对象
        • 1.14.2、任意属性名
        • 1.14.3、提取方法
        • 1.14.4、方法中的函数
        • 1.14.5、构造函数:对象工厂
      • 1.15、数组
        • 1.15.1、数组字面量
        • 1.15.2、数组方法
        • 1.15.3、遍历数组
      • 1.16、正则表达式
        • 1.16.1、test()方法:匹配吗
        • 1.16.2、exec()方法:匹配以及捕获分组
        • 1.16.3、replace()方法:搜索和替换
      • 1.17、Math
      • 1.8、标准库的其他功能
    • 2、背景
      • 2.1、JavaScript可以自由使用吗
      • 2.2、JavaScript优雅吗
      • 2.3、JavaScript有用吗
        • 2.3.1、图形用户界面
        • 2.3.2、其他技术补充完善JavaScript
      • 2.4、JavaScript有什么好用的工具吗
      • 2.5、JavaScript是否足够快
      • 2.6、JavsScript是广泛使用的吗
      • 2.7、JavaScript有前途吗
    • 3、JavaScript的性质
      • 3.1、古怪和非官方特性
      • 3.2、优雅部分
      • 3.3、影响
    • 4、JavaScript是如何创造出来的
    • 5、标准化ECMAScript
    • 6、JavaScript的历史里程碑
  • 3、深入JavaScript
    • 7、JavaScript的语法
      • 7.1、语法概览
      • 7.2、注释
      • 7.3、表达式与语句
      • 7.4、控制流语句和块
      • 7.5、使用分号的规则
        • 7.5.1、以块结束的语句后面没有分号
        • 7.5.2、空语句
        • 7.5.3、自动分号插入
      • 7.6、合法标识符
      • 7.7、数字字面量的方法调用
      • 7.8、严格模式
        • 7.8.1、启用严格模式
        • 7.8.2、严格模式:建议与注意事项
        • 7.8.3、严格模式中,变量必须被声明
        • 7.8.4、严格模式下的函数
      • 7.8.5、严格模式中,设置或者删除不可改变的属性会抛出异常
        • 7.8.6、严格模式中的不合格标识符不能删除
        • 7.8.7、严格模式中,eval更加简洁
        • 7.8.8、严格模式中禁用的特性
    • 8、值
      • 8.1、JavaScript中的类型体系
        • 8.1.1、JavaScript类型
        • 8.1.2、静态与动态
        • 8.1.3、静态类型与动态类型
        • 8.1.4、静态类型检查和动态类型检查
        • 8.1.5、强制转换
      • 8.2、原始值和对象
        • 8.2.1、原始值
        • 8.2.2、对象
      • 8.3、undefined和null
        • 8.3.1、undefined和null的出现场景
        • 8.3.2、检测undefined和null
        • 8.3.3、undefined和null的历史
        • 8.3.4、修改undefined
      • 8.4、原始值的包装对象
        • 8.4.1、包装对象不同于原始值
        • 8.4.2、原始值的包装与去包装
        • 8.4.3、原始值从包装器借调方法
      • 8.5、强制类型转换
        • 8.5.1、强制类型转换会隐藏bug
        • 8.5.2、转换成布尔值、数字、字符串和对象的函数
        • 8.5.3、算法:ToPrimitive()----将值转换为原始值
    • 9、运算符
      • 9.1、运算符和对象
      • 9.2、赋值运算符
      • 9.3、等号运算符:= = = 和 = =
        • 9.3.1、严格相等(= = = 和 != =)
        • 9.3.2、普通(宽松)相等(==,!=)
        • 9.3.3、没有针对==的有效用例
      • 9.4、排序运算符
      • 9.5、加号运算符(+)
      • 9.6、布尔运算符和数字运算符
      • 9.7、条件运算符
        • 9.7.1、条件运算符(?:)
        • 9.7.2、逗号运算符
        • 9.7.3、void运算符
      • 9.8、通过typeof和instanceof判断值类型
        • 9.8.1、typeof:判断原始值
        • 9.8.2、instanceof:检测对象是否给定构造函数的实例
      • 9.9、对象运算符
    • 10、布尔类型
      • 10.1、转换成布尔值
        • 10.1.2、真值和假值
      • 10.2、逻辑运算符
        • 10.2.1、二元逻辑运算符:与(&&)和或(||)
        • 10.2.2、逻辑与(&&)
        • 10.2.3、逻辑或(||)
        • 10.2.4、逻辑非(!)
      • 10.3、等号运算符、排序运算符
      • 10.4、Boolean函数
    • 11、数字
      • 11.1、数字字面量
        • 11.1.1、说明
        • 11.1.2、在字面量上调用方法
      • 11.2、转换成数字
        • 11.2.1、手动转换为数字
        • 11.2.2、parseFloat()
      • 11.3、特殊的数字值
        • 11.3.1、NaN
        • 11.3.2、Infinity
        • 11.3.3、两个0
      • 11.4、数字的内部表示
      • 11.5、处理舍入错误
      • 1.6、JavaScript中的整形
        • 11.6.1、整型的范围
        • 11.6.2、将整型表示位浮点数字

1、基础JavaScript

1.1、背景

1.1.1、JavaScript与ECMAScript

JavaScript是编程语言
ECAMScript是这种语言规范

1.1.2、JavaScript的影响和本质

在其他语言,我们学的是语言特性,而在JavaScript中,我们常学的却是模式。

1.2、语法

1.2.1、语法概述

一个单独的等于号(=),用于为变量赋值。
三个连续的等于号(===),用于比较两个值。

1.2.2、语句和表达式

语句“做事情”。
表达式产生值。
JavaScript两种方式实现if-then-else
语句方式:

var x;
if(y >= 0){
	x = y;
} else {
	x = -y;
}

表达式方式:

var x = y >= 0 ? y : -y;

后面这种方式可以用于函数的参数(而前者不行)

myFunction(y >= 0 ? y:-y)

表达式语句

1.2.3、分号

分号用于结束语句,而不是结束块。有一种情况会看到分号出现在块之后:函数表达式作为一个表达式时。

var x = 3 * 7;
var f = function() {};
1.2.4、注释

单行注释
多行注释

x++; // single-line comment 
/* this is
   a multiline
   comment.
*/

1.3、变量和赋值

变量在声明后使用

var foo; // declare variable 'foo'

foo = fuck oriented object
foo是"你要让它是什么就是什么"。

1.3.1、赋值

变量声明和赋值可以同时进行

var foo = 6;

也可以为一个已有变量进行赋值

foo = 4;  //change variable 'foo'
1.3.2、复合赋值运算符
x += 1;
x = x + 1;
1.3.3、标识符与变量名

保留字(不能用于变量名、函数名、参数名)
arguments break case catch class const continue debugger default delete do else enum export extends false finally for function if implements import in instanceof interface let new null package private protected public return static super switch this throw true try typeof var void while
infinity NaN undefined

1.4、值

布尔值、数字、字符串、数组等。在JavaScript值所有的值都有属性。每一个属性都有一个key(或者是name)和一个value。属性就像是一条记录的字段。通过点(.)操作符可以读取属性。

value.propKey

字符串‘abc’有length这个属性

var str = 'abc';
str.length

也可以写为

'abc'.length

点操作同样可以用于给属性赋值

var obj = {};    // empty object
obj.foo = 123;    // create property 'foo', set it  to 123
console.log(obj.foo)

也可以通过点操作来调用方法:

'hello'.toUpperCase()    // 大写
'HELLO'
1.4.1、原始值和对象

原始值包括布尔值、数字、字符串、null和undefined
其他的值都是对象
这两者之前最主要的区别在于它们的比较方式;每个对象都有唯一的标识且只等于自己。

var obj1 = {};
var obj2 = {};
obj1 === obj2    // false
obj1 === obj1    //true

所有的原始值,只要编码值相同,则被认为相等

var prim1 = 123;
var prim2 = 123;
prim1 === prim2    // true
1.4.2、原始值(primitives)

布尔值:true、false
数字:20156、1.351
字符串:‘dh’、“abc”
两个“空值”: undefined、null
特点:
(1)按值进行比较
内容比较:

3 === 3    // true
'abc' === 'abc'    // true

(2)不可改变
其属性不能被改变、添加或移除:

var str = 'abc';
str.length = 1;    // try to change property 'length'
str.length    // => no efffect    3
str.foo = 3;     // try to create property 'foo'
str.foo    // => no effect, unknown property  undefined
1.4.3、对象
  • 简单对象,可以通过对象字面量来创建
{
	firstName: 'Jane',
	lastName: 'Doe'
}
  • 数组,可以通过数组字面量来创建
['apple', 'banana', 'cherry']

可以通过数字索引来访问它们

  • 正则表达式,可以通过正则表达式字面量来创建
/^a+b+$/

对象具有一下特点:
(1)按引用进行比较
比较身份标识:每个值都有各自的身份标识

{} === {}    // two different empty objects    false
var obj1 = {};
var obj2 = obj1;
obj1 === obj2    // true

(2)默认可变
对象属性可以很自由地被改变、添加和移除

var obj1 = {}
var obj2 = 123;   // add property 'foo'
console.log(obj1.foo)    // 123
1.4.4、undefined和null

“空值”

  • undefined的意思是“没有值”。
    未被初始化的变量即为undefined;
var foo;
console.log(foo)    // undefined

丢失的参数也会是undefined

function f(x) { return x }
console.log(f())    // undefined

访问不存在的属性,也会得到undefined

var obj = {};    // empty object
console.log(obj.foo)    // undefined
  • null的意思是“没有对象”。在用到对象的时候它表示空值(例如参数、对象链中的最后一个元素等)。
    undefined和null没有属性,甚至连toString()这种标准方法都没有。

检查undefined 或 null
函数允许透过undefined或null来表示缺失的值。可以通过以下显示的检查来做到同样的事情:

if(x === undefined || x === null){
	...
}

也可以利用 undefined 或 null 都可被视为 false 这一事实来处理:

if(!x){
	...
}

false, 0, NaN 和 ‘’ 都可被视为false

1.4.5、使用 typeof 和 instanceof 对值分类

typeof用于原始值
instanceof用于对象

  • typeof用法返回值是一个表示这个值“类型”的字符串。
typeof value
typeof true    // 'boolean'
typeof 'abc'    // 'string'
typeof {}    // empty object literal  'object'
typeof []    // empty object literal  'object'
操作数 结果
undefined ‘undefined’
null object
布尔值 boolean
数字 number
字符串 string
函数 function
所有其他的常规值 object
引擎创建的值 JavaScript引擎可以被允许去创建一些值,且typeof的结果可以返回任意字符串(可以与列表值列出的结果都不一样)

typeof null 返回object是一个不能修正的bug,因为这会破坏现有的代码。但这并不表示null是一个对象

  • instanceof用法:
value instanceof Constr

如果value是一个通过Constr构造器创建的对象,则返回true

var b = new Bar();    // object created by constructor Bar
b instanceof Bar    // true
{} instanceof Object    // true
[] instanceof Object    // true
[] instanceof Object    // Array is a subconstructor of Object    true
undefined instanceof Object    // false
null instanceof Object    // false

1.5 布尔值 true false

以下运算会产生布尔值

  • 二元逻辑运算符: &&(与),|| (或)
  • 前置逻辑运算符:!(非)
  • 比较运算符:
    相等运算符:
    排序运算符(针对字符串及数字):>, >=, <, <=
1.5.1 真值与假值

以下值会被解释成false

  • undefined、null
  • 布尔值:false
  • 数字:-0、NaN
  • 字符串:‘’
    其他所有的值(包括所有的对象)都会被当成true。
    Boolean()作为函数调用时,会将传入的参数转换为一个布尔值。
Boolean(undefined)    // false
Boolean(0)    // false
Boolean(3)    //true
Boolean({})    // empty object    true
Boolean([])    // empty array     true
1.5.2、二元逻辑运算符

二元逻辑运算符是短路的。因为如果第一个运算数就足以确定结果的话,则不会对第二个运算数做评估。
以下表达式,其中的foo()函数永远不会被调用:

false && foo()
true || foo()

二元逻辑运算符会返回运算数值得一个----可能是一个布尔值,也可能不是。
(1)与(&&)
如果第一个运算数是假值,返回它。否则,返回第二个运算数。

NaN && 'abc'    // NaN
123 && 'abc'    // 'abc'

(2)或(||)
如果第一个运算数是真值,返回它。否则,返回第二个运算数。

'abc' || 123    // 'abc'
'' || 123    // 123
1.5.3、等式运算符

两种类型相等

  • 常规的,或“宽松的”相等(或不相等):== 和 !=。
  • 严格的相等(或不相等):=== 和 !==
    常规相等,更多考虑值是否相等。

1.6、数字

js中所有的数字都是浮点数

1 === 1.0    // true

也包含一些特殊的数字:
NaN(“not a number”) 一个错误的值

Number('xyz')    // 'xyz' can't be converted to a number
NaN

Infinity多数情况下也是一个错误的值:

3/0    // Infinity
Math.pow(2, 1024)    // number too large Infinity

Infinity比任何一个数都要大(NaN除外)
-Infinity比任何一个数都要小(NaN除外)

1.7、运算符

  • 加法: 数字1 + 数字2
  • 减法: 数字1 - 数字2
  • 乘法: 数字1 * 数字2
  • 除法: 数字1 / 数字2
  • 取模: 数字1 % 数字2
  • 增量:++变量,变量–
  • 减量:–变量,变量–
  • 负数:-值
  • 转变成数字: +值
1.8字符串

单引号 双引号之内。反斜杠(\)用于转义字符及产生一些控制字符。

'abc'
"abc"

'Did she say "Hello"?'
"Did she say \"Hello\"?"

'That\'s nice!'
"That's nice!"

'Line 1\nLine2'    // newline
'Backlash: \\'

可以通过方括号来访问字符串中的单个字符:

var str = 'abc'
str[1]    // 'b'

字符串的length属性可以对字符的个数进行计数:

'abc'.length    // 3

像所有的原始值一样,字符串是不可变的;如果要改变一个已有的字符串,必须创建一个新的才行。

1.8.1 字符串运算符

字符串可以通过加号(+)进行连接,如果其中一个运算数是字符串的话,另一个运算数将被转换为字符串:

var messageCount = 3;
console.log('You have' + messageCount + 'messages')    // 'You have 3 messages'

在多个步骤转换连接字符串,可以使用+=运算符:

var str = '';
str += 'Multiple ';
str += 'pieces ';
str += 'are concatenated.';
console.log(str)    // 'Multiple pieces are concatenated.'
1.8.2、字符串方法
'abc'.slice(1)    // copy a substring    'bc'
'abc'.slice(1,2)    // 'b'

'\t xyz   '.trim()    // trim whitespace    'xyz'

'mjolnr'.toUpperCase()    // 'MJOLNR'

'abc'.indexOf('b')    // find a string    1
'abc'.indexOf('x')    // -1

str.slice(start, end) 提取字符串某个部分,start(包含),end(不包含)。
str.trim() 删除字符串的头尾空白符,空白符包括:空格、制表符tab、换行符等其他空白符等。不会更改原始字符串。
str.toUpperCase()将字符串转换为大写字母,不会更改原始字符串。

1.9、语句

1.9.1、条件语句

if语句有一个then从句以及一个可选的else从句

if(myvar === 0){
	// then
}

if(myvar === 0){
	// then
} else {
	// else	
}

if(myvar === 0){
	// then
} else if(myvar === 1){
	// else-if
} else if(myvar === 2){
	// else-if
} else {
	// else
}

从句仅有一个单独的语句(对 for 和 while 语句同样适用):

if(x < 0) return -x;

switch语句:
fruit的值会决定要执行哪个case:

switch(fruit){
	case 'banana':
		//...
		break;
	case 'apple':
		//...
		break;
	default: //all other cases
		//...
}

case 之后跟的“运算数”可以是任意表达式;在switch里的参数会通过===来进行比较。

1.9.2、循环语句

for(init; condition; post_iteration){
statement
}
初始化会在循环开始前执行。
条件会在每次循环迭代之前做检查,如果是false则终止循环。
后迭代会在每次循环迭代后执行。

for(var i=0; i < arr.length; i++){
	console.log(arr[i])
}

while循环语句会在条件成立的时候会持续循环

// Same as for loop above
var i = 0;
while(i < arr.length) {
	console.log(arr[i])
	i++;
}

do-while循环语句在条件成立时会持续循环。由于条件会跟在代码体之后,所以,这些代码体至少会执行一次:

do{
	// ...
} while (condition);

有两条语句适用于所有的循环方式:

  • break可以跳离循环
  • continue会开始一个新的循环迭代

1.10、函数

函数声明

function add(param1, param2) {
	return param1 + param2;
}

函数表达式

var add = function(param1, param2){
	return param1 + param2;
};

函数表达式会产生一个值,因此可以将函数作为参数直接传递给另外的函数:

someOtherFunction(function(p1, p2){ ... })
1.10.1、函数声明的提升特性

函数声明具有提升特性----它们的实体会被移动到所在作用域的开始处。这使得我们可以引用后面声明的函数。

function foo(){
	bar();    //OK,bar is hoisted
	function bar() {
		...
	}
}

var声明也具有提升的特性,但通过它们执行的赋值却不具备该特性。

function foo() {
	bar();  // Not OK, bar is still undefined
	var bar = function(){
		// ...
	};
}
1.10.2、特殊的变量arguments

函数的所有参数都可以被自由调用,会通过arguments变量来使所有参数可用。
arguments看起来像个数组,但却不具备数组的方法

function f() { return arguments }
var args = f('a', 'b', 'c');
console.log(arrs.length)    // 3
console.log(args[0])    // 'a'
1.10.3、参数太多或太少
function f(x, y){
	console.log(x, y)
	return toArray(arguments);
}
// 额外的参数会被忽略
f('a', 'b', 'c')    //a, b
// 丢失的参数会得到undefined这个值
f('a')    // a, undefined
f()    // undefined, undefined
1.10.4、可选参数

以下是一个给参数赋上默认值的通用模式:

function pair(x, y){
	x = x||0;
	y = y||0;
	return [x,y];
}
1.10.5、强制参数长度

arguments.length

function pair(x, y){
	if(arguments.length !== 2){
		throw new Error('Need exactly 2 arguments');
	}
	...
}
1.10.6、将arguments转换为数组

arguments不是数组,它只是类似于数组。有length属性,可以通过方括号去访问它的元素。不能移除它的元素,也不能对它调用数组的方法。

function toArray(arrayLikeObject){
	return Array.prototype.slice.call(arrayLikeObject)
}
1.11、异常捕获
function getPerson(id) {
	if(id < 0){
		throw new Error('ID must not be negative:'+id);
	}
	return {id: id} // normally: retrieved from database
}

function getPersons(ids){
	var result = [];
	ids.forEach(function(id){
		try{
			var person = getPerson(id);
			result.push(person);
		} catch(exception){
			console.log(exception);
		}
	});
	return result;
}

使用try语句包裹关键代码,如果try语句有异常会被抛出那么catch语句就会执行。

1.12、严格模式

切换严格模式:
在JavaScript文件或者

你可能感兴趣的:(javascript,笔记,前端)