JavaScript
JavaScript
编写位置
1 |
|
基础语法
- 严格区分大小写
- 每一条语句已分号结尾
- 声明变量: var、let
- 数据类型(typeof var 可输出变量类型)
- String
- 使用双引号或者单引号都可以
- 使用 \ 进行转义
1
var str = "hello";
- Number
- 包括整数和浮点数
- Number.MAX_VALUE 表示 js 中的最大值
- 如果数字超过了最大值,则会返回 Infinitely
- NoN 也是 Number 类型
- Boolean
- true、false
- Null
- Null 类型的值只有一个,就是null(专门用于表示空对象)
- 一般用于垃圾处理,不使用的对象手动赋值为 null
1
2var a = null;
typeof a; // 会返回 Object 类型
- Undefined
- Undefined 类型的值只有一个,就是undefined(声明变量但是不赋值)
1
var a;
- Undefined 类型的值只有一个,就是undefined(声明变量但是不赋值)
- Object
- String
- 强制类型转换
- 转换为 String
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17// 方式一:调用 toString() 方法
var a = 123;
a = a.toString(); // Number 转换为 String
a = true;
a = a.toString(); // Boolean 转换为 String
a = null;
a = a.toString(); // error
a = undefined;
a = a.toString(); // error (null 和 undefined 没有toString()方法)
// 方式二:调用 String() 函数
a = 123;
a = String(a);
a = null;
a = String(a); // 正确的, 变成 "null"
a = undefined;
a = String(a); // 正确的, 变成 "undefined" - 转化为 Number
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24var a = "123"
// 方式一:使用 Number() 函数
a = Numner(a);
// 如果字符串中有非数字,则转化为 NaN
var a = "abc"
a = Number(a); // a 变成 NaN
// 如果字符串是空串或者全是空格,则转化为 0
var a = "";
a = Number(a); // a 变成 0
// Boolean 只会变成 0 或 1
var a = true;
a = Number(a); // a 变成 1
var a = false;
a = Number(a); // a 变成 0
// null 会变成 0
var a = null;
a = Number(a); // a 变成 0
// undefined 会变成 NaN
var a = undefined;
a = Number(a); // a 变成 NaN
// 方式二:parseInt()、parseFloat() 这两个函数可以将一个字符串中的有效数字取出来
var a = "123px"
a = parseInt(a); // a = 123 - 转化为 Boolean
1
2
3
4
5
6
7
8// 调用 Boolean() 函数
// 数字转 Boolean, 除了 0 和 NaN,其余都是 true
// 字符串转 Boolean,除了空串都是 true
// null 转换为 Boolean 是 false
// undefined 转换为 Boolean 是 false
// 对象也会转换为 true
var a = 123;
a = Boolean(a); // a = true;
- 转换为 String
- 算数运算符
- 当对非 Number 类型的值进行运算时,会将这些值转换为 Number 再运算
- 任何值和 NaN 运算,结果都是 NaN
- 两个字符串相加,会把两个字符串拼起来
- 任何值和字符串做加法运算,都会先转换为字符串,然后再和字符串做拼串操作
- 可以利用这一特点,将任意数据类型转换为 String,直接 + 一个 “”, 即可转换
1
2
3result = 1 + 2 + "3"; // "33" 从左往右算
result = "1" + 2 + 3; // "123"
result = 100 - "1"; // 99 只有加法才会优先转为 String,其他都是转为 Number
- 可以利用这一特点,将任意数据类型转换为 String,直接 + 一个 “”, 即可转换
- 一元运算符
- 正号不会对数字产生任何影响
- 负号可以对数字进行取反
- 对于非 Number 类型的值,会先转化为 Number,再运算
- 逻辑运算符
- !
- &&
1
2
3var a = 5 && 6; // a = 6;
var a = 0 && 2; // a = 0;
var a = 2 && 0; // a = 0; - ||
1
2
3var a = 2 || 1; // a = 2;
var a = 1 || 0; // a = 1;
var a = 0 || 1; // a = 1;
- 相等运算符
- == 会做自动类型转换,=== 不会
- 代码块
- js 的代码块只具有分组作用(方便看,以及用于 if 语句),没有其他用途,代码块内部的内容,代码块外部是全部可见的
- if 语句
1
2
3
4
5
6
7
8
9if (条件) {
}
else if {
}
else {
} - while 语句
1
2
3
4
5
6
7while (条件) {
}
do {
} while (条件); - for 语句
1
2
3for (var i = 0; i < 10; ++i) {
}
对象(一切皆是对象)
分类
- 内建对象:Math、String、Number…
- 宿主对象:有 js 运行环境提供,只要指由浏览器提供的对象(BOM、DOM)
- 自定义对象
基本操作
1 | var obj = new Object(); |
- 全局变量是全局对象 window 的属性
- 创建的函数都会成为 window 的方法
1
2
3
4
5
6
7
8
9var a = 1;
console.log(a);
console.log(window.a);
function func() {
alert();
}
func();
window.func(); - 使用 var 关键字声明的变量,会在所有的代码执行之前被声明,但是不会赋值
- 使用函数声明形式创建的函数 function 函数(){} 会在所有的代码执行之前就被创建,所以可以在函数声明前调用函数
- 使用函数表达式创建的函数,var func = function(){} 不会被声明提前,所以不能在声明前调用
函数
构造函数创建函数对象
1 | var func = new Function(); |
使用函数声明来创建函数
- 语法:function 函数名(形参1、形参2、形参3…) { 函数体 }
1
2
3
4function func() {
alert('hello');
}
func()
使用函数表达式创建函数
- 语法:var 函数名 = function(形参1、形参2、形参3…) { 函数体 }
1
2
3
4var func = function() {
alert("hello");
}
func();
函数的参数
- 调用函数时解析器不会检查实参的类型
- 调用函数时解析器不会检查实参的数量,多余的实参不会被赋值
- 如果实参的数量少于形参的数量,则没有对应实参的形参是 undefined
1
2
3
4
5function func(a, b) {
console.log(a + b);
}
func(1, 2);
func(1, 2, 3); // 3 没用 - 实参也可以是一个函数
1
2// 这经常使用,将一个匿名函数传递给一个函数
func(function(){alert("hello");})
函数的返回值
- 使用 return var;
1
2
3function func(a, b) {
return a + b;
} - 函数不 return,则会返回 undefined
立即执行函数
- 函数定义完,立即被调用
1
2
3(function(){
alert('hello');
})();
解析器在调用函数时,每次都会向函数内部传递一个隐含的参数 this
- 以函数的形式调用时,this 永远都是 window
- 以方法的形式调用时,this 就是调用方法的那个对象
工厂函数构建对象
1 | function createObj(name, age) { |
构造函数
- 构造函数就是普通函数,不同的是习惯上首字母大写,且构造函数需要使用 new 关键字调用
1
2
3
4
5function Person(name, age) {
this.name = name;
this.age = age;
}
var per = new Person("yu", 18);
构造函数执行流程
- 立即创建一个新的对象
- 将新建的对象设置为函数中的 this,在构造函数中可以使用 this 来引用新建的对象
- 逐行执行函数中的代码
- 将新建的对象作为返回值返回
使用instanceof 可以检查一个对象是否是一个类的实例
1 | console.log(per instanceof Person); // 返回 true |
- 所有对象都是 Object 的后代,所有任何对象 instanceof Object 都返回 true
对象方法的创建
- 直接在构造函数中定义方法,会导致每次 new 一个对象时,都会创建方法,浪费~
1
2
3
4
5
6
7function Person(name, age) {
this.name = name;
this.age = age;
this.func = function() {
this.alert('hello');
}
} - 引用全局函数
1
2
3
4
5
6
7
8var func = function() {
this.alert('hello');
}
function Person(name, age) {
this.name = name;
this.age = age;
this.func = func;
} - 引用全局函数当作对象方法会污染全局空间
- 所创建的每一个函数,解析器都会向函数中添加一个属性 prototype,这个属性对应这一个对象,这个对象就是原型对象
- 当函数以构造函数的形式调用时,它所创建的对象中都会有一个隐含的属性,指向该构造函数的原型对象,可以通过 proto 来访问该属性
1
2
3
4
5
6
7
8
9
10
11var func = function() {
this.alert('hello');
}
function Person(name, age) {
this.name = name;
this.age = age;
this.func = func;
}
console.log(Person.prototype);
var per = new Person("yu", 18);
console.log(per.__proto__); // 和 Person.prototype 的值相同 - 原型对象就相当于一个公共的区域,所有同一个类的实例都可以访问到这个原型对象
- 可以将对象中的共有内容,统一设置到原型对象中
1
2
3
4
5
6function Person(name, age) {
this.name = name;
this.age = age;
this.func = func;
}
Person.prototype.a = 123; // 向 Person 类的原型对象中添加属性 a
- 可以将对象中的共有内容,统一设置到原型对象中
- 创建构造函数时,可以将这些对象共有的属性和方法,统一添加到构造函数的原型对象中,不用分别为每一个对象添加,也不会影响到全局作用域
- 原型对象也是对象,所以它也有原型
- Object 是所有对象的原型
- 当我们在页面中直接打印一个对象时,实际上是输出对象的 toString() 方法的返回值
函数的方法
- call() 和 apply()
- 这两个方法都是函数对象的方法,需要通过函数对象来调用
- 当对函数调用 call() 和 apply() 都会调用函数执行
- 在调用 call() 和 apply() 可以将一个对象指定为第一个参数,此时这个对象将会成为函数执行的this
- this 的情况
- 以函数形式调用时,this 永远都是 window
- 以方法的形式调用时,this 是调用方法的对象
- 以构造函数的形式调用时,this 是新建的那个对象
- 使用 call() 和 apply() 调用时,this 是指定的那个对象
函数隐含参数
- 在调用函数时,浏览器每次都会传递两个隐含的参数
- 函数的上下文对象 this
- 封装实参的对象 arguments
- arguments 是一个类数组对象,它可以通过索引来操作数据(arguments[0],arguments[1],…),也可以获取长度(arguments.length)
- 在调用函数时,所传的实参都会在 arguments 中保存
数组 (Array)
数组也是一个对象
1
2
3
4
5
6var arr = new Array();
// var arr = []; // 也可以
// 添加元素
arr[0] = 0;
arr[1] = 1;
arr[10] = 10;读取索引范围外会返回 undefined
使用 arr.length 获取元素个数
- 对于连续的数组,length 得到数组的长度
- 对于非连续的数组,length 得到数组最大的索引 + 1
- 创建非连续的数组,浪费空间,尽量创建连续数组
修改 length 的值会截断数组的值(多了截断,少了填充)
像数组最后一个位置添加元素
1
arr[arr.length] = 值
使用字面量创建数组,可以在创建时指定数组中的元素
1
2
3
4
5var arr = [1, 2, 3];
var arr = new Array(1, 2, 3);
var arr = [10]; // 创建只有一个元素的数组
var arr = new Array(10); // 创建 10 个元素的数组数组中的元素可以是任意类型
1
var arr = [1, "hello", [1,2,3]];
push 方法向数组末尾添加一个或多个元素,返回数组的新长度
unshift 方法向数组开头添加一个或多个元素,返回数组的新长度
pop 方法删除数组最后一个元素,并将删除的元素返回
shift 方法删除数组第一个元素,并将删除的元素返回
forEach() 方法便利数组,需要一个函数作为参数(IE8 以上的浏览器才支持)
- 第一个参数:当前正在遍历的元素
- 第二个参数:正在遍历的元素的索引
- 第三个参数:正在遍历的数组
1
2
3arr.forEach(function(value, index, obj){
console.log(a);
})
arr.slice(start, end): 从数组提取指定元素
- 左闭右开
- end 可以省略不写,默认是末尾
- 索引可以传递负值
arr.splice(start, end, arg1, arg2,…): 删除数组中的指定元素,还可以添加一些新元素(插入 start 位置),并将被删的元素返回
arr.concat(arr1, arr2, arr3,…): 连接两个数组,并将新数组返回,不会对原数组产生影响
arr.join(连接符): 将数组转化为字符串,不会影响原数组
arr.reverse(): 反转数组,直接修改原数组
arr.sort(): 影响原数组
- 默认从小到大,可以传入函数自定义(返回大于 0,则交换位置;返回小于等于0,不交换位置)
Date 对象
1 | var d = new Date(); |
Math
- Math 和其他的对象不同,它不是一个构造函数
- 属于一个工具类,不用创建对象
1
2console.log(Math.PI);
console.log(Math.random());
字符串的方法
…
正则表达式
1 | // 创建正则表达式对象 |
字符串与正则表达式
…
DOM(Document Object Model)
- js 中通过 DOM 来对 html 文档进行操作
事件
- 用户和浏览器之间的交互行为:点击按钮、鼠标移动、关闭窗口…
- 可以在事件对应的属性中设置一些 js 代码,这样当事件被触发时,这些代码会执行
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<html>
<head>
<meta charset="utf-8">
<title>yzy</title>
</head>
<body>
<!-- <button id="btn" onclick="alert('hello');">我是一个按钮</button> -->
<button id="btn">我是一个按钮</button>
</body>
<script type="text/javascript">
var btn = document.getElementById("btn");
btn.onclick = function() {
alert('yu');
}
</script>
</html>
鼠标
- 元素.onmousemove = function(event){}
- 当事件的响应函数被触发时,浏览器每次都会将一个事件对象作为实参传递进响应函数
- event.clientX \ event.clientY (鼠标坐标位置)
事件的冒泡
- 指事件的向上传导,当后代元素上的事件被触发时,其祖先的相同事件也会触发
- 可以将事件对象的cancelBubble 设置为 true,可以取消冒泡
键盘
- document.onkeydown = function(event){}
- document.onkeyup = function(event){}
文档的加载
- 浏览器加载一个页面时,是按照自上向下的顺序加载的,读取一行就执行一行
- onload 事件会在这个页面加载完成之后触发(window.onload = function(){})
选择元素
- document.getElementById(“…”)…
- document.querySelector(“…”) 可以根据 css 选择器进行选择
- 使用该方法总会返回唯一的一个元素,如果满足条件的元素有多个,那么它只会返回第一个
- document.querySelectorAll(“…”)可以选择所有并装到数组中
DOM 增删改
增
- var p = documents.createElement(“p”)
- 创建一个元素节点对象,需要一个标签名作为参数
- var text = documents.createTextNode(“text”)
- 创建一个文本节点对象,需要一个文本内容作为参数
- p.appendChild(text)
- 向一个父节点加一个子节点
- 最后还需要把创建的节点插入到已有的 html 节点中
删
- removeChild()
改
- replaceChild()
BOM(Brower Object Model)
- BOM 使我们可以通过 js 操作浏览器
- Window
- 代表整个浏览器的窗口,同时 window 也是网页中的全局对象
- 其他 BOM 对象在浏览器中都是作为 window 对象的属性保存的,可以通过 window 对象来使用,也可以直接使用
- Navigator
- 代表当前浏览器的信息,通过该对象可以识别不同的浏览器
- console.log(navigator.userAgent)
- 代表当前浏览器的信息,通过该对象可以识别不同的浏览器
- Location
- 代表当前浏览器的地址信息,可以获取浏览器地址信息或者操作浏览器跳转页面
- History
- 代表浏览器的历史记录,可以通过该对象来操作浏览器的历史记录
- 由于隐私原因,该对象不能获取具体的历史记录,只能操作浏览器向前或者向后
- 且该操作只在当次访问有效
- 代表浏览器的历史记录,可以通过该对象来操作浏览器的历史记录
- Screen
- 代表用户的屏幕信息,通过该对象可以获取到用户的显示器的相关信息
- Window
- 定时调用:setInterval(function(){}, timeValue)
- 延时调用:setTimeout(function(){}, timeValue) 只会调用一次
json(javascript objet notation, js 对象表示法)
- json 和 js 对象的格式一样,只不过 json 字符串中的属性必须加双引号
- json –> js 对象
- var obj = JSON.parse(json)
- js 对象 –> json
- var s = JSON.stringify(obj)
- eval() 这个函数可以用来执行一段字符串形式的 js 代码,并将执行结果返回
关于引用变量赋值的问题
- 2 个引用变量指向同一个对象,通过一个变量修改对象内部的数据,另一个变量看到的是修改之后的数据
- 2 个引用变量指向同一个对象,让其中一个引用变量指向另一个对象,另一个引用变量依然指向前一个对象