JavaScript学习笔记-ES5(一)

2020年07月28日

https://wangdoc.com/javascript/basic/grammar.html
简介:本文内容主要基于 ECMAScript 5.1 版本

概述

1.变量声明:var
2.变量没有赋值,则为undefined
3.变量/函数声明 自动提升
4.控制台输出:console.log()
5.大小写敏感
6.注释: //,/**/,
7.条件语句:if ,switch;
8.switch(param){case “111”: break;default:print(“end”)}
9.三元运算符 ?: 公式: (条件) ? 表达式1 : 表达式2; 解释:如果条件true,返回表达式1,否则返回表达式2
10.循环:while,for,do…while
11.标签:通常和break和continue配合使用,跳出特定的循环
12.typeof 返回数据类型,数组和对象都返回object
13.instanceof 区分数组和对象,null返回object

null,undefined和布尔值

14.null和undefined的区别:null是一个表示“空”的对象,转为数值时为0;undefined是一个表示”此处无定义”的原始值,转为数值时为NaN。
15.undefined,null,false,0,NaN,””,’’ 转换为布尔值都是false
16.默认情况下,JavaScript 内部会自动将八进制、十六进制、二进制转为十进制。

数值

17.强制转换:parseInt() 只会返回数字或NaN ,parseFloat() 只会返回浮点数和NaN,空字符串也是NaN
18.isNaN() 只对数值有效,传入字符串,对象,数组会先被转换为数值再判断,即Number(字符串/对象/数组)
19.isFinite() 判断某个值是否为正常的数值

字符串

20.字符串可以被视为字符数组(即使用下标定位),但是不能改变!
21.JavaScript 对 UTF-16 的支持是不完整的,由于历史原因,只支持两字节的字符

对象

22.键名可以不加引号,E36支持symbol值作为键名
23.括号里面 只能是表达式,大括号里面只能解释为代码块
24.读取/赋值对象的属性,有两种方法,一种是使用点运算符,还有一种是使用方括号运算符。
25.Object.keys()可以获取对象的所有属性
26.delete 删除对象属性,不存在的属性也不报错!
27.Object.defineProperty 和 继承的属性无法删除
28.in 检查键名是否存在,但是不判断是否继承
29.hasOwnProperty 判断是否为对象自身的属性
30.for…in循环遍历对象属性
31.with语句 它的作用是操作同一个对象的多个属性时,提供一些书写的方便。

函数

32.函数声明:function命令,函数表达式,Function构造函数
33.函数声明会被提升,所以当一个函数多次声明,后面的会覆盖前面的
34.return 不是必须的,函数可以调用自身
35.使用函数表达式声明函数,只会提升变量声明
36.函数属性:name 函数名,length 参数个数,toString() 返回字符串,函数源码
37.作用域: ES5只有全局作用域和函数作用域
38.函数参数不是必需的,JavaScript 允许省略参数。可以不用赋值。如x=””
39.arguments对象 表示函数的所有参数,arguments[0]就是第一个参数;
40.非严格模式,argument可以修改传入参数;严格模式,argument修改并不会影响到实际的参数;
41.闭包:函数内部的函数
42.立即调用的函数表达式:(function(){/* code */}();
43.凡是使用别名执行eval,eval内部一律是全局作用域。

数组

44.允许空位存在,length不过滤空位 ,如s=[1,,2],length为3
45.使用数组的forEach方法、for…in结构、以及Object.keys方法进行遍历,空位都会被跳过。

数据类型的转换

46.支持自动转换(和java一样,python不支持且必须手动强制转换)
47.强制转换:Number(),String(),Boolean()

错误处理机制

48.SyntaxError 语法错误; ReferenceError 变量不存在;RangeError 超出范围;TypeError 变量或参数类型错误;URIError URI相关函数参数不正确;EvalError eval函数没有正确执行
49.自定义错误:需要继承Error对象
50.手动中断程序抛异常:throw
51.try…catch finally

console对象与控制台

52.log() 输出信息,自动添加换行符,相当于java system.out.println(); 支持占位符
53.CSS格式字符串占位符: %c
54.warn() 输出警告信息,在最前面加黄色三角
55.error() 输出错误信息,在最前面加红色叉叉
56.table() 输出转换为表格展示
57.count() 用于计数,输出它被调用了多少次
58.assert(条件,’条件不成立’) 用于断言,如果断言失败,不会中断程序;
59.group(),groupEnd(),groupCollapsed() 分组显示信息
60.clear() 清除控制台所有输出

控制台命令行API

61.$_ 返回上一个表达式的值
62.$0 - $4
63.$(selector) 等于document.querySelector() 返回第一个匹配的元素
64.$$(selector) 等于document.querySelectorAll() 返回选中的DOM对象
65.$x(path) 返回一个数组
66.monitorEvents(object[, events]) ,unmonitorEvents(object[, events]) 监听和取消监听
67.debugger 作用是断点

标准库

68.Object

实例方法:
68.1 valueOf() 返回当前对象对应的值,默认返回对象本身(obj.valueOf() 等于 obj);
68.2 toString() 返回一个对象的字符串形式,默认情况下返回[object Object],数组/字符串/函数/Date对象都定义了自己的toString()方法,可重写;
toString 应用: Object.prototype.toString.call(obj) 可用来判断一个值的类型(和typeof不一样!);
68.3 toLocaleString() 返回本地化的字符串形式,Array,Number,Date 都重写了该方法;
68.4 hasOwnProperty(str) 返回布尔值,表示该对象是否含有’str’属性;

69.属性描述对象

69.1 Object.getOwnPropertyDescriptor() 获取属性描述对象
69.2 Object.getOwnPropertyNames() 获取参数对象自身的所有属性的属性名,无论是否可遍历;
69.3 Object.defineProperty(object, propertyName, attributesObject) 允许通过属性描述对象定义或修改一个属性,然后返回修改后的对象;
69.4 Object.propertyIsEnumerable() 用来判断某个属性是否可遍历
69.5 元属性(即属性描述对象):
value 目标属性的值;
writable 布尔值,决定了目标属性的值是否可改变,若是强行改变,严格模式下会报错;
enumerable 可遍历性;for..in循环,Object.keys方法,JSON.stringify方法 不会取到设置为不可遍历的属性;
configurable 可配置性;决定是否可修改属性描述对象 以及 是否可删除目标属性;
69.6 控制对象状态: 冻结对象读写状态

70.Array

70.1. Array.isArray() 判断是否为数组;
70.2 valueOf() 返回数组本身,toString() 返回数组的字符串形式;
70.3 push() 数组末端增加元素,并返回增加后的数组长度,pop() 删除数组的最后一个元素,并返回该数组;
70.4 shift() 删除第一个元素,并返回该元素; unshift() 在数组的第一个位置添加元素;
70.5 join() 以指定参数作为分隔符,将所有数组成员连接为一个字符串返回,不提供参数,默认为逗号;
70.6 concat() 用于多个数组的合并,返回一个新的数组
70.7 reverse() 颠倒数组顺序,返回该数组
70.8 slice(start,end) 提取目标数组的一部分,返回新的数组;
70.9 arr.splice(start, count, addElement1, addElement2, …); 删除数组的一部分成员并可以在删除的位置添加新的元素,返回被删除的元素;原数组被改变;
70.10 sort() 按字典顺序排序
。。。等

71.包装对象

72.Boolean 对象

注: 双重否运算符(!)也可以将任意值转为布尔值
Boolean(1) // true
Boolean(‘false’) // true
Boolean([]) // true
Boolean({}) // true
Boolean(function () {}) // true
Boolean(/foo/) // true

73.Number对象

73.1 静态属性
Number.POSITIVE_INFINITY:正的无限,指向Infinity。
Number.NEGATIVE_INFINITY:负的无限,指向-Infinity。
Number.NaN:表示非数值,指向NaN。
Number.MIN_VALUE:表示最小的正数(即最接近0的正数,在64位浮点数体系中为5e-324),相应的,最接近0的负数为-Number.MIN_VALUE。
Number.MAX_SAFE_INTEGER:表示能够精确表示的最大整数,即9007199254740991。
Number.MIN_SAFE_INTEGER:表示能够精确表示的最小整数,即-9007199254740991。
73.2 实例方法
toString() 转换为字符串输出
toFixed() 转换为指定位数的小数,四舍五入不固定!
toExponential() 转为科学计数法形式
toLocaleString() 接收一个地区码作为参数,返回当前数字在该地区的当地书写形式;可以设置为percent或currency

74.this 详解

a.this 就是属性或方法’当前‘所在的对象;
b.this是动态变化的;
c.this是被设计为在函数体内部,指代函数当前运行环境;
d.避免多层this,第二层this指向全局对象window;(解决方法,在第一层使用变量固定this的值,在第二层调用变量);严格模式下,内部this指向顶层对象,报错;
e.避免回调函数中的this;
f.绑定this的方法:call(thisValue,arg1,agr2,…) 第一个参数是this所指向的哪个对象,后面的参数是函数调用时需要的参数;
g.绑定this的方法:apply(thisValue,[arg1,arg2,…]),和call()类似,区别是参数为数组;
h.bind() 用于将函数体内的this绑定到某个对象,返回新的函数,不会改变原来的函数;
其他扩展查看原文(比如获取数组中最大值);

75.对象的继承

概念:JavaScript 继承机制的设计思想就是,原型对象的所有属性和方法,都能被实例对象共享。
a.构造函数
b.prototype属性:函数的默认属性,指向一个对象;对于构造函数来说,生成实例时,该属性自动成为实例对象的原型;
c.constructor属性,prototype的属性,可以知道某个实例对象是哪个构造函数产生的;还可以通过实例对象.constructor()实例化一个新对象;

76.模块

a.方法1: 把模块写成一个对象 ; 缺点: 会暴露所有模块成员,外部可以改写;
b.方法2: 使用构造函数封装私有变量; 缺点: 耗内存;违背构造函数和实例对象在数据上分离的原则(即实例对象的数据,不应该保存在实例对象以外);
c.方法3: 使用立即执行函数封装私有变量;——基本写法!

var module1 = (function () {
 var _count = 0;
 var m1 = function () {
  //...
 };
 var m2 = function () {
  //...
 };
 return {
  m1 : m1,
  m2 : m2
 };
})();

d.放大模式: 一个模块很大或者一个模块需要继承另一个模块的情况;

var module1 = (function (mod){
 mod.m3 = function () {
  //...
 };
 return mod;
})(module1);

e.宽放大模式: 防止加载一个不存在空对象;

var module1 = (function (mod) {
 //...
 return mod;
})(window.module1 || {});

f.模块特点: 独立性;为了在模块内部调用全局变量,必须显式地将其他变量输入模块。

g.继承

function sub(){
Super.call(this)
}

76.严格模式

'user strict';
a. 只允许在全局作用域声明函数
b.新增了一些保留字(implements、interface、let、package、private、protected、public、static、yield等)

77.异步操作

概念
a. 单线程模型:js同时只能执行一个任务;但js引擎有多个线程,单个脚本只能在一个(主)线程上运行,其他线程在后台配合;
b.Web Worker 标准:允许 JavaScript 脚本创建多个线程,但是子线程完全受主线程控制,且不得操作 DOM。所以,这个新标准并没有改变 JavaScript 单线程的本质。
c.任务队列和事件循环:js引擎除了有一个主线程,还有多个任务队列负责处理异步任务;js引擎负责循环检查任务队列的异步任务是否满足进入主线程执行的条件(有回调函数)

异步操作的模式:
a.回调函数

function f1(callback) {
// ...
callback();
}

function f2() {
// ...
}

f1(f2);

优点:简单,容易实现和理解;
缺点:不利于阅读和维护,代码高度耦合,结构混乱;

b.事件监听
f1.on('done', f2); //当f1发生done事件,就执行f2
优点:可以绑定多个事件
缺点:事件驱动,流程不清晰;

c.发布/订阅 = 观察者模式
jQuery.subscribe('done', f2);

异步操作的流程控制:
a.串行执行:一个任务完成后,再执行另一个;

var items = [ 1, 2, 3, 4, 5, 6 ];
var results = [];

function async(arg, callback) {
console.log('参数为 ' + arg +' , 1秒后返回结果');
setTimeout(function () { callback(arg * 2); }, 1000);
}

function final(value) {
console.log('完成: ', value);
}

function series(item) {
if(item) {
async( item, function(result) {
results.push(result);
return series(items.shift());
});
} else {
return final(results[results.length - 1]);
}
}

series(items.shift());

b.并行执行,利用forEach

// forEach() 方法用于调用数组的每个元素,并将元素传递给回调函数。
//注意: forEach() 对于空数组是不会执行回调函数的
var items = [ 1, 2, 3, 4, 5, 6 ];
items.forEach(function(item) {
console.log(item)
});

//并行执行
var items = [ 1, 2, 3, 4, 5, 6 ];
var results = [];

function async(arg, callback) {
console.log('参数为 ' + arg +' , 1秒后返回结果');
setTimeout(function () { callback(arg * 2); }, 1000);
}

function final(value) {
console.log('完成: ', value);
}

items.forEach(function(item) {
async(item, function(result){
results.push(result);
if(results.length === items.length) {
final(results[results.length - 1]);
}
})
});

c.并行和串行的结合:设置门槛,几个任务一起执行

var items = [ 1, 2, 3, 4, 5, 6,8,9,10,11,12,14 ];
var results = [];
var running = 0;
var limit = 3; //设置限制limit个任务一起执行

function async(arg, callback) {
console.log('参数为 ' + arg +' , 1秒后返回结果');
setTimeout(function () { callback(arg * 2); }, 1000);
}

function final(value) {
console.log('完成: ', value);
}

function launcher() {
while(running < limit && items.length > 0) {
var item = items.shift();
async(item, function(result) {
results.push(result);
running--;
if(items.length > 0) {
launcher();
} else if(running == 0) {
final(results);
}
});
running++;
}
}

launcher();

Promise对象

a.状态: pending,(fulfiled,rejected) === resolved
b.new Promise(function(resolve,reject){//………});
resolve 将pending改为fulfilled传递出去
reject 将pending改为rejected传递出去
c.then(func,func)可以接受两个函数,第一个是操作成功调用的函数,第二个是操作失败调用的函数
多个then方法,操作成功只会执行最后一个步骤的返回值,但是操作失败会把所有的步骤失败结果都打印!
d.Promise 的缺点是,编写的难度比传统写法高,而且阅读代码也不是一眼可以看懂。你只会看到一堆then,必须自己在then的回调函数里面理清逻辑。

e.优点: 无论何时访问,都可以获取promise的状态
[jekyll]: http://jekyllrb.com
[jekyll-gh]: https://github.com/jekyll/jekyll
[jekyll-help]: https://github.com/jekyll/jekyll-help


知识共享许可协议
Dolores的博客Dolores 创作,采用 知识共享 署名-非商业性使用 4.0 国际 许可协议进行许可。
© 2011-2021. All rights reserved by Dolores. Powerd by Jekyll & LinAnYa's Theme