一、基础
1.函数的arguments
其实Javascript并没有重载函数的功能,但是Arguments对象能够模拟重载。Javascrip中每个函数都会有一个Arguments对象实例arguments,它引用着函数的实参,可以用数组下标的方式"[]"引用arguments的元素。arguments.length为函数实参个数,arguments.callee引用函数自身。
arguments特性:
1.arguments对象和Function是分不开的。
2.因为arguments这个对象不能显式创建。
3.arguments对象只有函数开始时才可用。
使用方法:
虽然arguments对象并不是一个数组,但是访问单个参数的方式与访问数组元素的方式相同
2.预解析
变量和函数进行代码提升。 使用let就不存在变量提升。
源代码:
f1();
console.log(c);
console.log(b);
console.log(a);
function f1(){
var a = b = c = 9;
console.log(a);
console.log(b);
console.log(c);
}
预解析:
function f1(){
// 批量声明: var a = 9, b =9, c=9; 相当于 var a = 9; var b = 9; var c = 9; a,b ,c是局部变量。
// var a = b = c = 9; 相当于 var a = 9; b = 9; c = 9; b 和 c相当于全局变量(没有声明的变量)。
var a = b = c = 9;
console.log(a);
console.log(b);
console.log(c);
}
f1();
console.log(c);
console.log(b);
console.log(a);
输出结果: 9,9,9,9,9,a is not defined.
补充
1.var 与 let
-
let
、const
暂时性死区TDC:必须在声明之后使用变量,避免的变量的提升。 - 当使用
var
忘记声明的时候,会造成全局污染,可以使用use strict
模式。 -
var
声明的变量是保存在window
对象中的,当被var
修饰的变量与window
中的属性相同时候,会污染window
属性。而let
不存在这个情况。 -
var
允许重复声明,let
、const
在同一个作用域则不允许。 -
var
没有块作用域,let
有块作用域;在let
出现之前没有块作用域,只有函数作用域。
块作用域示例:
<script>
var i=99;
for(var i=0;i<5;i++){
console.log(i)
}
console.log('i:'+i)
var j=99;
for(let j=0;j<5;j++){
console.log(j)
}
console.log('j:'+j)
{
var a=1;
let b=2;
}
console.log('a:'+a)
console.log('b:'+b)
</script>

3.对象创建
摘自:https://zhuanlan.zhihu.com/p/128624375
3.1 用字面量法创建对象
const student = {
name: "小明",
age: 8,
sayHi: function() {
console.log("i am " + this.name, "i am " + this.age + " years old");
}
};
console.log(student.name);
console.log(student['age']);
3.2 用工厂模式创建对象
工厂模式解决了复用性和重复的缺点,但是无法识别对象的类型。
function student(name, age) {
let aaa = {};
aaa.name = name;
aaa.age = age;
aaa.sayHi = function() {
console.log("i am " + name + ",i am " + age + " years old");
};
return aaa;
}
student1 = student('小明', 18);
student2 = student('小明', 18);
student3 = student('小红', 20);
student4 = student('小橙', 21);
student5 = student('小黄', 22);
student6 = student('小绿', 23);
student1.sayHi() // i am 小明,i am 18 years old
3.3 用构造函数创建对象
构造函数意味着将来可以将它的实例标识为一种特定的类型;而这正是 构造函数模式胜过工厂模式的地方。
构造函数尽可能使用首字母大写。
function student(name, age) {
this.name = name;
this.age = age;
this.sayHi = function() {
console.log("i am " + name + ",i am " + age + " years old");
};
}
student1 = new student('小明', 18);
student2 = new student('小红', 20);
student3 = new student('小橙', 21);
student4 = new student('小黄', 22);
student5 = new student('小绿', 23);
student1.sayHi()//i am 小明,i am 18 years old
student2.sayHi()//i am 小红,i am 20 years old
student3.sayHi()//i am 小橙,i am 21 years old
student4.sayHi()// i am 小黄,i am 22 years old
student5.sayHi()//i am 小绿,i am 23 years old
3.4 用原型模式创建对象
在js中每个函数被创建的时候,都会带有prototype这个属性。当我们将公用的方法放到构造函数.prototype中的时候,我们new出来的每个实例都无需再创建一次相同的方法。
function student(name, age) {
this.name = name;
this.age = age;
}
student.prototype.sayHi = function() {
console.log("i am " + this.name + ",i am " + this.age + " years old");
};
student1 = new student('小明', 18);
student1.sayHi() //i am 小明,i am 18 years old
3.5 用动态原型创建对象
原型和函数不分离。如果不觉得分离不舒服的话,其实第四种就可以了。
function student(name, age) {
this.name = name;
this.age = age;
if (typeof this.sayHi != "function"){
student.prototype.sayHi = function(){
console.log("i am " + this.name + ",i am " + this.age + " years old");
};
}
}
student1 = new student('小明', 18);
student1.sayHi() //i am 小明,i am 18 years old
3.6 用Object.create(obj)创建对象
要使用这种方法创建对象的话,首先你要有一个现有对象。
3.7 用ES6中的class方法创建对象
es6为了更接近传统语法,引入了Class这个概念,作为对象的模板,可以看作是一个语法糖,本质上是和原型模式创建对象是一样的。
// 原型模式创建对象
function student(name, age) {
this.name = name;
this.age = age;
}
student.prototype.sayHi = function() {
console.log("i am " + this.name + ",i am " + this.age + " years old");
};
student1 = new student('小明', 18);
student1.sayHi() //i am 小明,i am 18 years old
// class创建对象
class Student {
// 构造函数写属性
constructor(name, age) {
this.name = name
this.age = age
}
// 公用方法直接写
sayHi () {
console.log("i am " + this.name + ",i am " + this.age + " years old");
}
}
student1 = new Student ('小明', 18);
student1.sayHi() //i am 小明,i am 18 years old
4、数组
4.1 创建数组
// 字面量方式:
// 这个方法也是我们最常用的,在初始化数组的时候 相当方便
var a = [3, 11, 8]; // [3,11,8];
// 构造器:
// 实际上 new Array === Array,加不加new 一点影响都没有。
var a = Array(); // []
var a = Array(3); // [undefined,undefined,undefined]
var a = Array(3,11,8); // [ 3,11,8 ]
4.2 数组操作
#shift:删除原数组第一项,并返回删除元素的值;如果数组为空则返回undefined
var a = [1,2,3,4,5];
var b = a.shift();
结果 a:[2,3,4,5] b:1
#unshift:将参数添加到原数组开头,并返回数组的长度
var a = [1,2,3,4,5];
var b = a.unshift(-2,-1);
结果 a:[-2,-1,1,2,3,4,5] b:7
#注:在IE6.0下测试返回值总为undefined,FF2.0下测试返回值为7,所以这个方法的返回值不可靠,需要用返回值时可用splice代替本方法来使用。
#pop:删除原数组最后一项,并返回删除元素的值;如果数组为空则返回undefined
var a = [1,2,3,4,5];
var b = a.pop();
结果 a:[1,2,3,4] b:5
#push:将参数添加到原数组末尾,并返回数组的长度
var a = [1,2,3,4,5];
var b = a.push(6,7);
结果a:[1,2,3,4,5,6,7] b:7
#concat:返回一个新数组,是将参数添加到原数组中构成的
var a = [1,2,3,4,5];
var b = a.concat(6,7);
结果 a:[1,2,3,4,5] b:[1,2,3,4,5,6,7]
#splice(start,deleteCount,val1,val2,...):从start位置开始删除deleteCount项,并从该位置起插入val1,val2,...
var a = [1,2,3,4,5];
var b = a.splice(2,2,7,8,9);
结果 a:[1,2,7,8,9,5] b:[3,4]
var b = a.splice(0,1); //同shift
a.splice(0,0,-2,-1); var b = a.length; //同unshift
var b = a.splice(a.length-1,1); //同pop
a.splice(a.length,0,6,7); var b = a.length; //同push
#reverse:将数组反序
var a = [1,2,3,4,5];
var b = a.reverse();
结果 a:[5,4,3,2,1] b:[5,4,3,2,1]
#sort(orderfunction):按指定的参数对数组进行排序
var a = [1,2,3,4,5];
var b = a.sort();
结果 a:[1,2,3,4,5] b:[1,2,3,4,5]
#slice(start,end):返回从原数组中指定开始下标到结束下标之间的项组成的新数组
var a = [1,2,3,4,5];
var b = a.slice(2,5);
结果 a:[1,2,3,4,5] b:[3,4,5]
#join(separator):将数组的元素组起一个字符串,以separator为分隔符,省略的话则用默认用逗号为分隔符
var a = [1,2,3,4,5];
var b = a.join("|");
结果 a:[1,2,3,4,5] b:"1|2|3|4|5"
二、Web API
Web API是浏览器提供的一套操作浏览器功能和页面元素的API(BOM 和 DOM)。
2.1 DOM

2.1.1 DOM获取元素
1.通过ID获取(getElementById)
2.通过name属性(getElementsByName)
3.通过标签名(getElementsByTagName)
4.通过类名(getElementsByClassName)
5.通过选择器获取一个元素(querySelector)
6.通过选择器获取一组元素(querySelectorAll)
7.获取html的方法(document.documentElement)
8.document.documentElement是专门获取html这个标签的
9.获取body的方法(document.body)
10.document.body是专门获取body这个标签的。
2.1.2 DOM操作元素
JavaScript的DOM操作(增删改查)可以改变网页内容、结构和样式。




2.1.3 DOM中的事件
参考:
https://zhuanlan.zhihu.com/p/51611590
https://www.jianshu.com/p/8c41a302bb17
事件级别(版本?阶段?)
1.DOM级别
一共可以分为四个级别:DOM0级、DOM1级、DOM2级和DOM3级。
DOM0:实际上并不存在 DOM0 标准。具体来说,DOM0 级指的是 IE4.0 和 Netscape Navigator4.0 最初支持的 DHTML
DOM1
DOM1级的目标主要是映射文档的结构。
DOM1 级由两个模块组成:DOM 核心(DOM Core) 、 DOM HTML。
DOM 核心: 规定如何映射基于 XML 的文档结构,以便简化对文档中任意部分的访问和操作。
DOM HTML: 在 DOM 核心的基础上加以扩展,添加了针对 HTML 的对象和方法。
DOM2
DOM2级在原来的 DOM 基础上扩充了鼠标和用户界面事件、范围、遍历(迭代 DOM 文档的方法)等细分模块,而且通过对象接口增加了对 CSS 的支持。
DOM2 引入的新模块:
DOM 视图(DOM Views) 、 DOM 事件(DOM Events) 、 DOM 样式(DOM Style) 、 DOM 遍历和范围(DOM Traversal and Range)。
DOM 视图:定义了跟踪不同文档(例如,应用 CSS 之前和之后的文档)视图的接口。
DOM 事件:定义了事件和事件处理的接口。
DOM 样式:定义了基于 CSS 为元素应用样式的接口。
DOM 遍历跟范围:定义了遍历和操作文档树的接口。
DOM3
DOM3 进一步扩展了 DOM,引入了以统一方式加载和保存文档的方式(在 DOM 加载和保存(DOM Load and Save)模块中定义),
新增了验证文档的方法(在 DOM 验证(DOM Validation)模块中定义),对 DOM 核心进行了扩展,开始支持 XML1.0 规范。
2.DOM事件级别
分为3个级别:DOM 0级事件处理,DOM 2级事件处理和DOM 3级事件处理。
DOM0:处理事件就是将一个函数赋值给一个事件处理属性。
<button id="btn" type="button"></button>
var btn = document.getElementById('btn');
btn.onclick = function() {
console.log('Hello World');
}
DOM1:由于DOM 1级中没有事件的相关内容,所以没有DOM 1级事件。
DOM2:允许给一个程序添加多个处理函数。
<button id="btn" type="button"></button>
var btn = document.getElementById('btn');
function showFn() {
alert('Hello World');
}
btn.addEventListener('click', showFn, false);
// btn.removeEventListener('click', showFn, false); 解绑事件
DOM3:事件是在DOM2级事件的基础上添加很多事件类型。
1.UI事件,当用户与页面上的元素交互时触发,如:load、scroll
2.焦点事件,当元素获得或失去焦点时触发,如:blur、focus
3.鼠标事件,当用户通过鼠标在页面执行操作时触发如:dbclick、mouseup
4.滚轮事件,当使用鼠标滚轮或类似设备时触发,如:mousewheel
5.文本事件,当在文档中输入文本时触发,如:textInput
6.键盘事件,当用户通过键盘在页面上执行操作时触发,如:keydown、keypress
7.合成事件,当为IME(输入法编辑器)输入字符时触发,如:compositionstart
8.变动事件,当底层DOM结构发生变化时触发,如:DOMsubtreeModifie。
事件模型
DOM事件模型分为捕获和冒泡。一个事件发生后,会在子元素和父元素之间传播。这种传播分成三个阶段。
(1)捕获阶段:事件从window对象自上而下向目标节点传播的阶段;
(2)目标阶段:真正的目标节点正在处理事件的阶段;
(3)冒泡阶段:事件从目标节点自下而上向window对象传播的阶段。

由于事件会在冒泡阶段向上传播到父节点,因此可以把子节点的监听函数定义在父节点上,由父节点的监听函数统一处理多个子元素的事件。这种方法叫做事件的代理(delegation)。
事件常用方法
1.event.preventDefault():如果调用这个方法,默认事件行为将不再触发。
2.event.stopPropagation() :方法阻止事件冒泡到父元素,阻止任何父事件处理程序被执行。
3.event.stopImmediatePropagation():既能阻止事件向父元素冒泡,也能阻止元素同事件类型的其它监听器被触发。
2.2 BOM
BOM缺乏标准:JS的语法是ECMA制定;DOM是W3C制定的,BOM最初是Netscape浏览器标准的一部分。
window对象是浏览器的顶级对象,它具有双重角色:
1.它是JS访问浏览器窗口的一个接口。
2.它是一个全局对象,定义在全局作用域中的变量、函数都会变成window对象的属性和方法。


网友评论