前言
自己学习学习的JavaScript基础,并记录成笔记!
如何引入JavaScirpt
JavaScript代码可以直接嵌在网页的任何地方
内部引入:是由<script>...</script>包含的代码就是JavaScript代码,它将直接被浏览器执行。
外部引入:是把JavaScript代码放到一个单独的.js文件,然后在HTML中通过<script src="..."></script>引入这个文件。
代码示例
//内部引入
< script >< /script>
// 外部引入
<head>
<script src="/static/js/abc.js"></script>
</head>
建议: 把js放在html代码结束处,这样可以让页面先渲染再跑js,可以避免页面卡住
很多语法和Java差不多,比如循环等
一、基本语法
//定义变量
var x = 1;
let num1 = 10 ;
'Hello, world';
var x = 1; var y = 2; // 不建议一行写多个语句!
//循环
if(){}
for(){}
while(){}
do{}while()
//常用输出语句
alert();
console.log();
1、Number
JavaScript不区分整数和浮点数,统一用Number表示;可以直接做四则运算,规则和数学一致
123; // 整数123
0.456; // 浮点数0.456
1.2345e3; // 科学计数法表示1.2345x1000,等同于1234.5
-99; // 负数
NaN; // NaN表示Not a Number,当无法计算结果时用NaN表示
Infinity; /*Infinity表示无限大,
当数值超过了JavaScript的Number所能表示的最大值时,就表示为Infinity*/
2、字符串
2.1、转义字符
JavaScript的字符串就是用 '' 或 "" 括起来的字符表示。
如果字符串内部既包含 ' 又包含 " 怎么办?
比如:
'I'm "OK"!';
可以使用 转义字符
转义字符可以转义很多字符,
\n表示换行\'表示'\t表示制表符\\表示的字符就是\- ASCII字符可以以
\x##形式的十六进制表示 \u####表示一个Unicode字符
2.2、多行字符串
js里可以使用单引号表示多行字符串
//单引号在Tab按键的上方
`这是一个
多行
字符串`;
2.3、模板字符串
JS里可以使用${}快速拼接字符串与变量
// 设置变量age
//在Java中:
"小明"+age+"岁了"
// 在JS中也可以这样写,但还可以实现多行字符串编写和模板字符串
`小明${age}岁了`
2.4、字符串长度
用 .length 来获取字符串长度
var s = 'Hello, world!';
s.length; // 13
那我们怎么看字符串长度呢?
- 不带转义字符的字符
如:
abc ,!x=/,其长度为 9 (注意有空格) - 带转义字符的字符
如:
abc !,\n,其中的\n为转义字符(换行符),计算字符串长度时只能计作一个字符,所以该字符串的长度为 7 - 特殊转义符的字符串
如:
abcd\0ef,其中转义字符\0是字符串结束符,所以在计算长度时为 4 - 反斜杠
如:
abc !,\\n, 因为反斜杠不能作为任何合法的字符,所以是转义符\\加上n长度为 8
2.5、 不可变性
字符串是不可变的,如果对字符串的某个索引赋值,不会有任何错误,但是,也没有任何效果
3、布尔值
一个布尔值只有true、false两种值 ; ||运算是或运算 ; !运算是非运算 ;
&&运算是与运算
4、比较运算符
在JS里 不要 使用==比较 ,使用===比较
= //赋值
== //类型不一样,值一样,也就是比较类型
=== // 和Java的 == 一样
NaN这个特殊的Number与所有其他值都不相等 , 包括它自己;
唯一能判断NaN的方法是通过isNaN()判断是否为true
NaN === NaN; // false
isNaN(NaN); // true
尽量避免使用浮点数进行运算,存在精度问题 , 只能计算它们之差的绝对值,看是否小于某个阈值
console.log((1/3) === (1-2/3)) //false3
Math.abs(1 / 3 - (1 - 2 / 3)) < 0.0000001; // true
5、null和undefined
null表示一个 空 的值,它和0以及空字符串''不同,0是一个数值,''表示长度为0的字符串,而null表示 什么都没有;
而undefined表示值未定义,仅仅在判断函数参数是否传递的情况下有用
6、strict模式
因为JS比较随意,容易出现bug,所以可以在第一行写 'user strict;' ,开启严格检查模式,这样会避免很多问题
二、操作字符串
1、返回指定位置的字符
charAt() 返回指定位置的字符,参数是从0开始编号的
var s = new String( 'litbaizhan');
s.charAt(1) // "t"
s.charAt(s.1ength - 1) // "n",返回最后一位
如果参数为负数,或大于等于字符串的长度,charAt 返回空字符串
2、连接字符串
concat() 用于连接两个字符串,返回一个新字符串,不改变原字符串(其实用+链接更方便)
var s1 = 'itbaizhan';
vars2='sxt';
s1. concat(s2) // "itbaizhansxt"
s1 // "itbaizhan"
//该方法可以接受多个参数
'sxt'.concat('itbaizhan', 'bjsxt') // "sxtitbaizhanbjsxt"
如果参数不是字符串,concat方法会将其先转为字符串,然后再连接
var one = 1;
var two = 2;
var three = '3';
''.concat(one, two, three) // "123"
3、大小写转换
.toUpperCase() 全部转化为大写 , .toLowerCase 全部转化为小写
4、索引
.indexOf(),判断字符串中是否存在某个词汇
var s = 'hello, world';
s.indexOf('world'); // 返回 7
s.indexOf('World'); // 没有找到指定的子串(大写W),返回-1
indexOf 方法还可以接受第二个参数,表示从该位置开始向后匹配
'he11o world'.indexof('o', 6) // 7 也就是跳过了第一个o从6开始到了第二个o的位置
5、返回指定索引区间的子串
substring() 返回指定索引区间的子串 ,一定第二个参数大于第一个参数
var s = 'hello, world'
s.substring(0, 5); // 从索引0开始到5(不包括5),返回'hello'
s.substring(7); // 从索引7开始到结束,返回'world'
substr() 方法的第一个参数是子字符串的开始位置(从0开始计算),第二个参数是子字符串的长度
'itbaizhan'.substr(2,7); // baizhan
如果省略第二个参数,则表示子字符串一直到原字符串的结束
'itbaizhan'.substr(2); // "baizhan'
如果第一个参数是负数,表示倒数计算的字符位置。如果第二个参数是负数,将被自动转为0,因此会返回空字符串
'itbaizhan'.substr(-7) // "baizhan"
'itbaizhan'. substr(4, -1) // ""
6、除字符串两端的空格
trim用于去除字符串两端(不能去除中间)的空格,返回一个新字符串,不改变原字符串
'he1lo world'.trim()// "he1loworld"
该方法去除的不仅是空格,还包括制表符(\t、\v)、换行符(\n)和回车符(\r)
'\r\nitbaizhan \t' . trim() //'itbaizhan'
ES6扩展方法,trimEnd()和trimstar()方法
" itbaizhan ".trimEnd(); //" itbaizhan" 除去头部空格
" itbaizhan ".trimStart(); // "itbaizhan "除去尾部空格
7、分割字符串
split() 方法按照给定规则分割字符串,返回一个由分割出来的子字符串组成的数组
'it|sxt |baizhan'.split('I') // ["it", "sxt", "baizhan"]
如果分割规则为空字符串,则返回数组的成员是原字符串的每一个字符。
'alblc'.split('') // ["a", "I","b","I", "c"]
如果省略参数,则返回数组的唯一成员就是原字符串
'it|sxt|bz'.sp1it() // [it|sxt|bz]
split方法还可以接受第二个参数,限定返回数组的最大成员数。
'it|sxt|bz'.split('I', 0) // []
'it|sxt|bz' .split('I',1) // ["it"]
'itlsxt|bz'.split('l', 2) // ["it", "sxt'"]
三、数组
数组用[]表示,元素之间用,分隔
var arr = {1,2,3,4,null,ture,'hello'}//推荐
new Array = (1,2,3,4,null,ture,'hello')//创建了数组[1,2,3,4,null,ture,'hello']
arr[0]; // 返回索引为0的元素,即1
arr[5]; // 返回索引为5的元素,即true
arr[6]; // 索引超出了范围,返回undefined
1、取得Array的长度
.length 可以得到并改变数组长度,变长加空数组,变短会使元素丢失
直接给Array的length赋一个新的值会导致Array大小的变化
var arr = [1, 2, 3.14, 'Hello', null, true];
arr.length; // 6
arr.length = 8;//数组越界
arr; // arr变为[1, 2, 3.14, 'Hello', null, true, undefined, undefined]
arr.length = 2;
arr; // arr变为[1, 2]
2、下标索引赋值
Array可以通过索引把对应的元素修改为新的值
var arr = ['A', 'B', 'C'];
arr[1] = 99;
arr; // arr现在变为['A', 99, 'C']
arr[5] = 'x';
arr; // arr变为['A', 99, 'C', undefined, undefined, 'x']
Array也可以通过indexOf()来搜索一个指定的元素的位置
arr.indexOf(99); // 元素99的索引为1
arr.indexOf(30); // 元素30没有找到,返回-1
3、截取数组
slice()就是对应String的substring()版本,它截取Array的部分元素,然后返回一个新的Array:
4、数组增删
.push() 数组尾部增加 , .pop() 数组尾部弹出一个元素 ; .unshift() 压入头部 ,.shift() 弹出头部的一个元素。加入循环可以清空一个数组。
splice() 方法是修改Array的“万能方法”,它可以从指定的索引开始删除若干元素,然后再从该位置添加若干元素
var arr = [1, 2];
arr.push('A', 'B'); // 返回Array新的长度: 4
arr; // [1, 2, 'A', 'B']
arr.pop(); // pop()返回'B'
arr; // [1, 2, 'A']
arr.pop(); arr.pop(); arr.pop(); // 连续pop 3次
arr; // []
arr.pop(); // 空数组继续pop不会报错,而是返回undefined
arr; // []
//splice
var arr = ['Microsoft', 'Apple', 'Yahoo', 'AOL', 'Excite', 'Oracle'];
// 从索引2开始删除3个元素,然后再添加两个元素:
arr.splice(2, 3, 'Google', 'Facebook'); // 返回删除的元素 ['Yahoo', 'AOL', 'Excite']
arr; // ['Microsoft', 'Apple', 'Google', 'Facebook', 'Oracle']
// 只删除,不添加:
arr.splice(2, 2); // ['Google', 'Facebook']
arr; // ['Microsoft', 'Apple', 'Oracle']
// 只添加,不删除:
arr.splice(2, 0, 'Google', 'Facebook'); // 返回[],因为没有删除任何元素
arr; // ['Microsoft', 'Apple', 'Google', 'Facebook', 'Oracle']
5、数组排序
它会直接修改当前Array的元素位置,直接调用时,按照默认顺序排序,可以在函数里定义排列顺序
.sort() ["c","b","a"] --> ["a","b","c"]
6、反转
reverse()把整个Array的元素给调个个,也就是反转
.reverse() ["a","b","c"]-->{["c","b","a"]
7、数组拼接
.concat() 直接将其拼入数组尾部,但不改变原数组,常用于上拉加载合并数据。
var arr = ['A', 'B', 'C'];
var added = arr.concat([1, 2, 3]);
added; // ['A', 'B', 'C', 1, 2, 3]
arr; // ['A', 'B', 'C']
8、连接符
.join() arr=["a","b","c"] arr.join(-) --> "a-b-c"
var arr = ['A', 'B', 'C', 1, 2, 3];
arr.join('-'); // 'A-B-C-1-2-3'
9、多维数组
如果数组的某个元素又是一个Array,则可以形成多维数组
arr=[[1,2,a],[3,4,b],[5,6,c]]
上述Array包含3个元素,其中头两个元素本身也是Array
10、数组组判断
AraysAray方法返回-一个布尔值,表示参数是否为数组。它可以弥补typeof运算符的不足
var arr = ["尚学堂", 100,true];
console.1og(typeof arr); // object
var arr = ['sxt', 'baizhan', 'it'];
Array. isArray(arr) // true
四、对象
用一个{...}表示一个对象,键值对以xxx: xxx形式申明,用,隔开 ; 属性:属性值,值得注意的是,如果对象里面还有一个对象,那么就形成了链式调用,类似包名
var person = {
name: 'Bob',
age: 20,
tags: ['js', 'web', 'mobile'],
city: 'Beijing',
hasCar: true,
zipcode: null
};
1、获取属性
要获取一个对象的属性,我们用对象变量.属性名的方式 , 也可以用xiaohong['name']来访问xiaohong的name属性,不过xiaohong.name的写法更简洁,访问一个不存在的属性会返回undefined
var person = {
name: 'Bob',
age: 20,
tags: ['js', 'web', 'mobile']
};
person.name; // 'Bob'
person.city; // undefined
2、属性删减
由于JavaScript的对象是动态类型,你可以自由地给一个对象添加或删除属性
delete xiaoming.age; // 删除age属性,返回`true`
3、判断属性值是否存在
用in操作符:xxx in xxx ,注意! 如果in判断一个属性存在,这个属性不一定是person的,它可能是person继承得到的
'name' in person; // true
'grade' in person; // false
//注意
'toString' in person; // true
因为toString定义在object对象中,所以person也拥有toString属性
可以用 hasOwnProperty() 判断属性是否自身拥有
person.hasOwnProperty(toString) //返回false
五、条件判断和循环
因为和Java基本一致就不再赘述,详细见
1、Map和Set
JavaScript的对象有个小问题,就是键必须是字符串。但实际上Number或者其他数据类型作为键也是非常合理的。为了解决这个问题,最新的ES6规范引入了新的数据类型Map
1.1、Map
//ES6 Map
//学生的成绩,学生的名字
// var names = ["tom","jack","haha"];
// var scores = [100,90,80];
var map = new Map([['tom' ,100] ,['jack' , 90],['haha', 80]]);
var name = map. get('tom'); //通过key获得va1ue
map.set('admin' ,123456); //增加修改
map.delete("tom") //删除
由于一个key只能对应一个value,所以,多次对一个key放入value,后面的值会把前面的值冲掉
var m = new Map();
m.set('Adam', 67);
m.set('Adam', 88);
m.get('Adam'); // 88
1.2、Set
Set和Map类似,也是一组key的集合,但不存储value,所以key不能重复
var s = new set();
s.add(2); //添加
s.delete(1); //删除
console.log(s.has(3)); //是否包含某个元素
//重复元素在Set中自动被过滤
var s1 = new Set([1, 2, 3, 3, '3']);
console.log(s1); // Set {1, 2, 3, "3"} , 3被过滤
2、iterator
遍历Array可以采用下标循环,遍历Map和Set就无法使用下标。为了统一集合类型,ES6标准引入了新的iterable类型,Array、Map和Set都属于iterable类型。具有iterable类型的集合可以通过新的for ... of循环来遍历。
2.1、for ... of和for ... in
遍历集合:
var a = ['A', 'B', 'C'];
var s = new Set(['A', 'B', 'C']);
var m = new Map([[1, 'x'], [2, 'y'], [3, 'z']]);
for (var x of a) { // 遍历Array
console.log(x);
}
for (var x of s) { // 遍历Set
console.log(x);
}
for (var x of m) { // 遍历Map
console.log(x[0] + '=' + x[1]);
}
for ... of循环和for ... in循环的区别:for ... in它遍历的实际上是对象的属性名称,for ... of它只循环集合本身的元素
var a = ['A', 'B', 'C'];
a.name = 'Hello';
for (var x in a) {
console.log(x); // '0', '1', '2', 'name'
}
2.2、forEach
forEach()方法是ES5.1标准引入的
只需要获得Array的element
var a = ['A', 'B', 'C'];
a.forEach(function (element) {
console.log(element);
});
Map的回调函数参数依次为value、key和map本身
var m = new Map([[1, 'x'], [2, 'y'], [3, 'z']]);
m.forEach(function (value, key, map) {
console.log(value);
});
Set与Array类似,但Set没有索引,因此回调函数的前两个参数都是元素本身
var s = new Set(['A', 'B', 'C']);
s.forEach(function (element, sameElement, set) {
console.log(element);
});
set 可以认为是去除了value的map , 他的存储模式是和map一样的, 数组+链表 or 红黑树的方式。而 array是单纯的数组.
六、函数
函数就是最基本的一种代码抽象的方式
1、函数的定义和调用
函数提升:可以先调用再定义
1.1、函数的定义
定义函数的方式如下:
//方式一
//abs()函数实际上是一个函数对象,而函数名`abs`可以视为指向该函数的变量
function abs(x) {
if (x >= 0) {
return x;
} else {
return -x;
}
}
//方式二
//是一个匿名函数,它没有函数名
var abs = function (x) {
if (x >= 0) {
return x;
} else {
return -x;
}
};
function指出这是一个函数定义; abs是函数的名称;函数体内部的语句在执行时。一旦执行到return时,函数就执行完毕,并将结果返回;如果没有return语句返回undefined
上述两种定义完全等价
调用函数时,按顺序传入参数即可
abs(10); // 返回10
abs(-9); // 返回9
abs(); //此时`abs(x)`函数的参数`x`将收到`undefined`, 返回NaN
通俗点说,函数就是抽象封装的东西,用来提高代码的复用性
1.2、arguments
它只在函数内部起作用,并且永远指向当前函数的调用者传入的所有参数。 利用arguments,你可以获得调用者传入的所有参数。也就是说,即使函数不定义任何参数,还是可以拿到参数的值;常用于判断传入参数的个数
1.3、rest参数
以前:
if (arguments.1ength > 2) {
for (var i = 2; i < arguments.length; i++) {
//。。。。
}
}
2、变量的作用域
变量的作用域在javascript中,var定义变量实际是有作用域的。假设在函数体中声明,则在函数体外不可以使用~!(闭包)
function qj() {
varX = 1;
X = X + 1;
}
x = x + 2; //Uncaught ReferenceError: x is not defined
如果两个函数使用了相同的变量名,只要在函数内部,就不冲突;内部函数可以访问外部函数的成员,反之则不行
假如内部函数变量和外部函数的变量,重名
function qj() {
varx = 1;
function qj2 () {
varx = ' A';
console.1og('inner' + x); // outer1
}
console.1og('outer' + x); //innerA
qj2()
}
qj()
假设在JavaScript中函数查找变量从自身函数开始~,由内向外查找.假设外部存在这个同名 的函数变量,则内部函数会屏蔽外部函数的变量。
2.1、提升变量作用域
function qj() {
var x = "x”+y;
console.1og(x);
vary='y';
}
// 结果 x undefined
说明; js执行引擎,自动提升了y的声明,但是不会提升变量y的赋值';
function qj2() {
var y;
varx="x"+y;
console.1og(x);
y ='y ';
}
这个是在JavaScript建立之初就存在的特性。养成规范:所有的变量定义都放在函数的头部,不要乱放,便于代码维护;
function qj2() {
varx = 1,
y = x + 1,
z,i,a; //undefined
//之后随意用
}
2.2、全局函数
//全局变量
x = 1;
function f() {
console.1og(x);
f();
console.1og(x);
2.3、全局对象window
varX一XXX,alert(x);
alert(window.x); //默认所有的全局变量,都会自动绑定在window对象下;
alert()这个函数本身也是一个window变量;
varx = ' xXx';
window.alert(x);
var o1d_ alert = window.alert;
//o1d_ alert(x);
window.alert = function() {};
//发现alert() 失效了
window.alert(123);
//恢复
window.alert = o1d_ alert;
window.alert(456);
Javascript实际上只有一个全局作用域,任何变量 (函数也可以视为变量), 假设没有在函数作用
范围内找到,就会向外查找,如果在全局作用域都没有找到,报错
RefrenceError
2.4、规范
由于我们所有的全局变量都会绑定到我们的window.上。如果不同的js文件,使用了相同的全局变 量,冲突~>如果能够减少冲突?
//唯一全局变量
var KuangApp = {};
//定义全局变量
KuangApp. name =' kuangshen
KuangApp.add = function (a,b) {
return a + b;
}
把自己的代码全部放入自己定义的唯一空间名字中,降低全局命名冲突的问题~ jQuery --> $()
2.5、局部作用域let
function aaa() {
for (vari = 0; i < 100; i++) {
console.1og(i) console.1og(i + 1); //问题? i 出了这个作用域还可以使用
}
解决局部作用域冲突问题,建议用let定义局部作用域变量
2.6、常量const
在ES6之前建议使用大写字母来定义的变量作为常量,建议不要修改,ES6之后引入了常量关键字const
const PI = '3.14'; //只读变量
console.1og(PI);
PI = ' 123'; // TypeError: Assi gnment to constant variable.
console.1og(PI);
3、方法
把函数放在对象里面,只有属性和方法
var kuangshen = {
name: '秦 疆'bitrh: 2000,
// 方法
age: function() {
//今年一出生的年
var now = new Date().getFu11Year();
return now - this.bitrh;
}
//属性
kuangshen.name
//方法,一定要带()
kuangshen.age()
this代表什么?拆开代码看看
function getAge() {
//今年-出生的年
var now = new Date().getFul1Year();
return now - this.bitrh;
}
var kuangshen = {
name: '秦疆',bitrh: 2000,age: getAge
// kuangshen.age() ok
// getAge() NaN window
可以看出调用getAge()方法失败,因为window里没有this.birth所以调用失败
apply
在js中可以控制this的指向
function getAge() {
//今年-出生的年
var now = new Date().getFullYear();
return now - this.bitrh;
}
var kuangshen = {
name: '秦疆',bitrh: 2000,
age: getAge
};
// kuangshen.age() ok
getAge.app1y(kuangshen, []); // this, 指向了kuangshen这个对象, 参数为空
apply可以让方法里的this指向某个对象,获取改对象的属性和属性值,即调用可以成功
七、简单对象
1、Date
JavaScript的Date对象月份值从0开始,牢记0=1月,1=2月,2=3月,……,11=12月。
let now = new Date(); / /Sat Jan 04 2020 10:4/ :06 GMT+0800 ( 中国标准时间)
now. getFul1year(); //年
now. getMonth(); //月 0~11 代表月
now. getDate(); //日
now. getDay(); //星期几
now. getHours(); // 时
now. getMinutes(); //分
now. getSeconds(); //秒
now. getTime(); //时间戳全世界统-一1970 1.1 0:00:00毫秒数
let d = new Date(1435146562875);
d; // Wed Jun 24 2015 19:49:22 GMT+0800 (CST)//时间戳转 为时间
d.getMonth(); // 5
now.toLocalestring() //获得本地时间
now.toGMTString() //获得GMT时间
如果要创建一个指定日期和时间的Date对象,可以用:
let d = new Date(2020, 5, 19, 20, 15, 30, 123);// 年,月,日,时,分,秒,毫秒
2、JSON
JSON是超轻量级的数据交换格式,能有效的提升网络传输效率
var user = {
name: "qinjiang",
age: 3,
sex: '男'
}
//对象转化为json字符串{"name" : "qinjiang","age":3, "sex":"男"}
var jsonUser = JSON.stringify(user);
//json字符串转化为对象参数为json字符串
var obj = JSON.parse('{"name":"qinjiang", "age":3,"sex":"男"}');
3、Math
3.1、Math.abs()返回参数值的绝对值
Math . abs(1) //1
Math . abs(-1) //1
3.2、Math.max(), Math.min()
Math.max方法返回参数之中最大的那个值,Math.min 返回最小的那个值。如果参数为空,Math.min 返回Infinity,Math.max返回-Infinity。
Math. max(2, -1,5) // 5
Math.min(2, -1,5) // -1
Math.min() // Infinity
Math.max() // -Infinity
3.3、Math.random()
Math.random()返回0到1之间的-一个伪随机数,可能等于0,但是-定小于1
Math. random( ) // 0.28525367438365223
任意范围(main——max)的随机数生成函数如下
function getRandomArbitrary(min, max) {
return Math. random() * (max - min) + min;
}
getRandomArbitrary(5,10)
3.4、Math.floor(), Math.ceil()
Math.loor方法返回小于参数值的最大整数
Math. f1oor(3.2) // 3
Math. f1oor(-3.2) // -4
Math.ceil方法返回大于参数值的最小整数
Math.cei1(3.2) // 4
Math.ceil(-3.2) // -3
七、面向对象
1、原型继承
通过.__proto__继承后,被继承的对象类似于父类
var student = {
name: "qinjiang",
age: 3, run: function() {
console.log(this.name + " run....");
}
};
//xiaoming里没有age属性,没有run方法
var xiaoming = {
name: "xiaoming"
};
//xiaoming相当于继承了对象student,会run有年龄有名字
xiaoming.__proto__ = student;
// 如果再次继承则会覆盖,以最后的一次继承的对象为父类
var Bird = {
fly: function() {
console.1og(this.name + "fl....");
}
};
//小明的原型是student,现在xiaoming只会fly和有名字
xiaoming._ proto__ = Bird;
2、class继承
class和Java是面向对象非常相似,extends继承也和Java很像
//定义一个学生的类
class Student {
//构造器
constructor(name) {
this.name = name;
}
//都是无返回值的方法
he11o() {
alert('he11o')
}
}
//实例化
var xiaoming = new Student("xiaoming");
var xiaohong = new Student("xiaohong");
//继承后super调用
class xiaostudent extends Student {
constructor(name, grade) {
super(name);
this.grade = grade;
}
//自己的方法
myGrade() {
alert('我是一名小学生')
}
}
var xiao = new xiaostudent("xiaostudent",3);
我们打印xiao可以发现xiaostudent的原型是Student,而Student的原型是Object,那Object的原型是谁?我们把这种链状关系叫原型链
八、浏览器
1、操作BOM对象
BOM就是浏览器模型
- Window:浏览器窗口
window.alert(1)
undefined
window.innerHeight
258
wi ndow.innerwidth
919
window.outerHeight
994
wi n dow.outerWidth
919
//还有很多,可以自己再浏览器尝试
- Navigater:封装了浏览器信息,但不建议使用
- Screen:屏幕尺寸
screen.width
1920 px
screen.height
1080 px
- location:当前页面url信息
- host:主机
- href:当前指向位置
- protocol:协议
- reload:方法; f reloadl:刷新
- location:assign('url'):设置新地址
host: "www.baidu.com
href: "https://www.baidu.com/"
protoco1: "https:"
reload: f reload() // 刷新网页
//设置新的地址
location.assi gn('https://b7og.kuangstudy.com/')
-
document:代表当前页面;HTML DOM文档树,可以获取,删除,增加文档树节点,还可以获取cookie等,后面细讲
-
history:浏览器历史记录,不建议使用
history. back() //后退
history. forward() //前进
2、操作DOM
DOM是JavaScript操作网页的接口,全称为"文档对象模型"(Document Object Model)。它的作用是将网 页转为一个JavaScript对象,从而可以用脚本进行各种操作(比如对元素增删内容)
浏览器会根据DOM模型,将结构化文档HTML解析成一系列的节点, 再由这些节点组成一个树状结构(DOM Tree)。所有的 节点和最终的树状结构,都有规范的对外接口
浏览器网页就是DOM树结构
- 更新:更新Dom节点
- 遍历dom节点:得到Dom节点
- 删除:删除一个Dom节点
- 添加:添加一个新的节点
2.1、获得节点
DOM的最小组成单位叫做节点(node) 。文档的树形结构(DOM树),就是由各种不同类型的节点组成。 每个节点可以看作是文档树的一片叶子
节点类型
- Document: 整个文档树的顶层节点
- DocumentType: doctype标签
- Element: 网页的各种HTML标签
- Attribute: 网页元素的属性(比如class="right")
- Text: 标签之间或标签包含的文本
- Comment: 注释
- DocumentFragment:文档的片段(不常用)
要操作一个Dom节点,就必须要先获得这个Dom节点,获取方式对应 css选择器,比如标签选择器、id、class等
<div id="father">
<h1>标题一</h1>
<p id="p1">p1</p>
<p class="p2">p2</p>
<p name="p3">p3</p>
</div>
2.1.1、标签获取
//如果有多个相应标签可以在后面通过添加[]来选取对应的标签
var h1 = document.getElementsByTagName('h1' );
document.getElementsByTagName方法搜索HTML标签名,返回符合条件的元素。它的返回值是一个类似数组对象 ( HTMColelon实例),可以实时反映HTML文档的变化。如果没有任何匹配的元素,就返回一个空集
var paras = document. getElementsByTagName('p');
如果传入。,就可以返回文档中所有HTML元素
var a11Elements = document.getElementsByTagName('*');
2.1.2、类获取
var p2 = document.getElementsByClassName('p2');
2.1.3、id获取
var p1 = document.getElementById('p1');
2.1.4、name获取
//使用率低
var h1 = document.getElementsByName('p3' );
2.1.5、关系获取
var father = document.getElementById( 'father');
var childrens = father.children; //获取父节点下的所有子节点
father.firstChild //子节点的第一个节点
father.LastChild //子节点的最后一个节点
father.Next //子节点的下一个节点
2.1.6、document.querySelector()
document.uerSelecor方法接受一个CSS选择器作为参数,返回匹配该选择器的元素节点。如果有多个节点满足 匹配条件,则返回第一个匹配的节点。如果没有发现匹配的节点,则返回null
var e11 = document . querySelector('.myclass');
2.1.7、document.querySelectorAll()
document. qesSelectoll方法与queysSelector用法类似,区别是返回一个NodeList对象,包含所有匹配给定选择器的 节点
var elementList = document. queryselectorA11(' .myclass');
以上都是原生代码,后面推荐使用jQuery
2.2、更新节点
//id1 是获取的到的节点
id1.innerText='456' //文本的值
id1.innerHTML='<strong> 123</strong>' //以解析HTML文本标签
id1.sty1e.color = 'yel1ow'; //属性使用字符串包裹
id1.style.fontSize=' 20px'; // 一转驼峰命名问题
id1.sty1e.padding = '2em'
2.3、删除节点
要通过父节点获取子节点来删除子节点
<body>
<div id="father">
<h1>标题一-</h1>
<p id="p1">p1</p>
<p class="p2">p2</p>
</div>
<script>
var se1f = document.getElementById('p1');
var father = p1.parentElement;
father.removeChild(sejf)
//动态过程,主要索引的下标变化
father.removeChi 1d(father.chi1dren [0])
father.removeChi 1d(father.chi1dren [1])
</script>
注意:删除多个节点的时候,children 是在时刻变化的,
2.4、插入节点
<p id="js"> Javascript</p>
<div id="list">
<p id="se">JavaSE</p>
<p id="ee">JavaEE</p>
<p id="me">JavaME</p>
</div>
var js = document.getElementById('js');
var 1ist = document.getElementById('list');
1ist.appendChild(js);//追加到后面
//通过JS创建一个新的节点
//例如: <p id="root">我是文本</p>
//方法一
var newP = document.createElement('p');//创建一个p标签
newP.id ='root';
newP.innerText = '我是文本'; //设置标签内容
//方法二
var text = document.createElement("p");//创建一个p标签
var content = document.createTextNode("我是文本")//创建文本
var id = document.createAttribute("id" )//创建id属性
id.value = "root"//id值
//appendChild: 将内容或者子元素放到容器中,也即是追加
text.appendChild(content);
text.setAttributeNode(id);
//如何渲染到页面呢?——> 对页面上的某标签里使用appendChild追加到里面即可
//创建一一个标签节点.
// 例如: <script type="text/javascript"></script>
var myScript = document.createElement('script' );
myScript.setAttribute('type','text/javascript');
2.5、Element属性
Element对象对应网页的HTML元素。每一个HTML元素,在DOM树上都会转化成一个Element节点对象(以下简称元素节点)
2.5.1、Element.id
Elementid属性返回指定元素的id属性,该属性可读写
// HTML代码为<p id="foo">
var p = document.querySelector('p');
p.id //'foo'
2.5.2、Element.className
className属性用来读写当前元素节点的class属性。它的值是一个字符串,每个class之间用空格分割
// HTML代码<div class="one two three" id="myDiv"></div>
var div = document. getElementById( myDiv');
div.c1assName
2.5.3、Element.classList
classList对象有下列方法
- add():增加一个class。
- remove():移除一个class。
- contains() :检查当前元素是否包含某个class。
- toggle():将某个class移入或移出当前元素。
var div = document.getElementById('myDiv');
div.classList.add('myCssClass');
div.classList.add('foo','bar');
div.classList.remove('myCssClass');
div.classList.toggle('myCssClass'); //如果myCssClass不存在就加入,否则移除
div.classList.contains('myCssClass'); //返回true或者false
2.5.4、Element.innerHTML
ElementinerHTML属性返回一个字符串,等同于该元素包含的所有HTML代码。该属性可读写,常用来设置某个节点的内容。它能改写所有元素节点的内容,包括<HTML> 和<body>元素
e1. innerHTML = '';
2.5.5、Element.innerText
innerText和nnerHTML 类似,不同的是innerText无法识别元素,会直接渲染成字符串
2.6、Element获取元素位置
| 属性 | 描述 |
|---|---|
| clientHeight | 获取元素高度包括padding部分,但是不包括border、margin |
| document.documentElement.clientHeight | 获取视口高度(屏幕高度) |
| doucument.body.clientHeight | 获取页面的高度 |
| clientWidth | 获取元素宽度包括padding部分,但是不包括border、margin |
| scrollHeight | 元素总高度,它包括padding ,但是不包括border、margin 包括溢出的不可见内容 |
| scrollWidth | 元素总宽度,它包括padding,但是不包括border、margin包括溢出的不可见内容 |
| scrollLeft | 元素的水平滚动条向右滚动的像素数量 |
| scrollTop | 元素的垂直滚动条向下滚动的像素数量 |
| offsetHeight | 元素的CSS垂直高度(单位像素),包括元素本身的高度、padding 和border |
| offsetWidth | 元素的CSS水平宽度(单位像素),包括元素本身的高度、 padding 和border |
| offsetLeft | 到定位父级左边界的间距 |
| offsetTop | 到定位父级上边界的间距 |
3、操作CSS样式
3.1、HTML元素的style属性
操作CSS样式最简单的方法,就是使用网页元素节点的setAtribute方法直接操作网页元素的style属性
div.setAttribute(
'style',//参数一
' background-color:red;' + 'border:1px solid black;'//参数二
);
3.2、元素节点的style属性
var divstyle = document.querySelector('div').style;
divsty1e.backgroundcolor = 'red' ;
divStyle.border = '1px solid black';
divStyle.width = ' 100px' ;
divStyle.height = ' 100px';
divStyle. fontSize =' 10em';
3.3、cssText属性
var divstyle = document.querySelector('div').style;
divSty1e. cssText = ' background-co1or: red;'
+ 'border: 1px solid black;'
+ 'height: 100px;'
+ 'width: 100px;' ;
4、事件处理
事件处理程序分为:
- HTML事件处理
- DOMO级事件处理
- DOM2级事件处理
4.1、HTML事件处理
HTML事件:缺点: HTML和JS没有分开
4.2、DOMO级事件处理
DOM0事件:优点: HTML 和IS是分离的
缺点:无法同时添加多个事件
4.3、DOM2级事件处理
DOM2事件:优点:事件不会被覆盖
缺点:写起来麻烦
5、鼠标事件
鼠标事件指与鼠标相关的事件,具体的事件主要有以下一些
| 事件 | 说明 |
|---|---|
| click | 按下鼠标时触发 |
| dblclick | 在同一个元素上双击鼠标时触发 |
| mousedown | 按下鼠标键时触发 |
| mouseup | 释放按下的鼠标键时触发 |
| mousemove | 当鼠标在节点内部移动时触发。当鼠标持续移动时,该事件会连触发。 |
| mouseenter | 鼠标进入一个节点时触发,进入子节点不会触发这个事件 |
| mouseleave | 鼠标离开一个节点时触发,离开父节点不会触发这个事件 |
| mouseover | 鼠标进入-个节点时触发,进入子节点会再一次触发这个事件 |
| mouseout | 鼠标离开一个节点时触发,离开父节点也会触发这个事件 |
| wheel | 滚动鼠标的滚轮时触发 |
6、Event事件
事件发生以后,会产生一个事件对象,作为参数传给监听函数
Event对象属性
- Event.Target
- Event.type
6.1、Event.target
Event.target属性返回事件当前所在的节点(点击谁就返回)
// HTML代码为
// <p id="para">Hello</p>
function setCo1or(e) {
console.log(this === e.target);
e.target.style.color ='red' ;
}
para. addEventListener('click', setCo1or);
6.2、Event.type
Event.type属性返回一一个字符串,表示事件类型。事件的类型是在生成事件的时候。该属性只读
7、Event对象万法
- Event.preventDefault()
- Event.stopPropagation()
7.1、Event.preventDefault
Event.preventDefault方法取消浏览器对当前事件的默认行为。比如点击链接后,浏览器默认会跳转到另一个页面,使用这个方法以后,就不会跳转了
btn. onclick = function(e){
e.preventDefault(); //阻止默认事件
console.1og("点击A标签");
}
7.2、Event.stopPropagation()
stopPropagation方法阻止事件在DOM中继续传播,防止再触发定义在别的节点上的监听函数, 但是不包括在当前节点上其他的事件监听函数
btn. onclick = function(e){
e. stopPropagation(); // 阻止事件冒泡
console.1og("btn");
}
简单点说,事件冒泡就是事件从子级传递到了父级;也就是子级事件发生了,父级就算没有该事件但是也会发生(父子之间相互嵌套)
8、键盘事件
键盘事件由用户击打键盘触发,主要有keydown ,keypress ,keyup三个事件
- keydown:按下键盘时触发。
- keypress: 按下有值的键时触发,即按下Ctrl. Alt、 Shift、 Meta 这样无值的键,这个事件不会触发。对于有值的键, 按下时先触发keydown事件,再触发这个事件。
- keyup:松开键盘时触发该事件
8.1、keydown
username.onkeypress = function(e){
console. 1og("keypress事件");
/ /也可以获取到该元素的值
console.log(e.target.value);
}
8.2、keyCode;唯一标识
每个键盘案件都有唯一标识用e.keyCode获取
var username = document.getElementById"username");
username . onkeydown = function(e){
if(e. keyCode === 13){
console.1og("回车");
}
}
9、表单事件
表单事件是在使用表单元素及输入框元素可以监听的一系列事件
- input事件
- select事件
- Change事件
- reset事件
- submit事件
9.1、input事件
input事件当<input>. <select>. <textarea> 的值发生变化时触发。对于复选框( <input type=checkbox> )或单选框( <input type=radio>),用户改变选项时,也会触发这个事件
input事件的一个特点,就是会连续触发,比如用户每按下一次按键, 就会触发一次input事件。
var username = document.getElementById("username") ;
username.oninput = function(e){
console.1og(e.target.value) ;//读取数据
}
9.2、select事件
select事件当在<input.textarea> 里面选中文本时触发
// HTML代码如下
// <input id="test" type="text" value="Select me!" />
var elem = document. getElementById('test');
elem. addEventL istener('select', function (e) {
console.1og(e. type); // "select"
},false);
9.3、Change事件
Change事件当<input>. <select>. <textarea>的值发生变化时触发。它与input事件的最大不同,就是不会连续触发,只有当全部修改完成时才会触发
var email = document . getElementById("email");
email . onchange = function(e){
console.1og(e. target. value);
}
9.4、reset事件, submit 事件
这两个事件发生在表单对象<form>上,而不是发生在表单的成员上。
- reset事件当表单重置(所有表单成员变回默认值)时触发。
- submit事件当表单数据向服务器提交时触发。注意, submit事件的发生对象是
<orm>元素,而不是<button>元素,因为提交的是表单,而不是按钮
<form id="myForm" onsubmi t="submi tHand1e">
<button oncli ck="resetHandle">重置数据</button>
<button>提交</button>
</form>
var myForm = document. getE1 ementById("myForm")
function resetHandle(){
myForm. reset() ;
function submi tHandle(){
console.1og("提交");
}
10、操作表单
操作表单就是form DOM树,他有
- 文本框,对应的
<input type="text">,用于输入文本; - 口令框,对应的
<input type="password">,用于输入口令; - 单选框,对应的
<input type="radio">,用于选择一项; - 复选框,对应的
<input type="checkbox">,用于选择多项; - 下拉框,对应的
<select>,用于选择一项; - 隐藏文本,对应的
<input type="hidden">,用户不可见,但表单提交时会把隐藏文本发送到服务器。
10.1、获得表单信息
如果我们获得了一个<input>节点的引用,就可以直接调用value获得对应的用户输入值,并且还适用于text、password、hidden以及select
// <input type="text" id="email">
var input = document.getElementById('email');
input.value; // '用户输入的值'
也可以自己设置值
input.value = 'test@example.com'; // 文本框的内容已更新
对于单选框和复选框,value属性返回的永远是HTML预设的值,而我们需要获得的实际是用户是否“勾上了”选项,所以应该用checked判断:
// <label><input type="radio" name="weekday" id="monday" value="1"> Monday</label>
// <label><input type="radio" name="weekday" id="tuesday" value="2"> Tuesday</label>
var mon = document.getElementById('monday');
var tue = document.getElementById('tuesday');
mon.value; // '1'
tue.value; // '2'
mon.checked; // true或者false
tue.checked; // true或者false
10.2、提交表单
浏览器默认点击<button type="submit">时提交表单,或者用户在最后一个输入框按回车键。因此,可以在提交form时作修改:
<!-- HTML -->
<form id="test-form" onsubmit="return checkForm()">
<input type="text" name="test">
<button type="submit">Submit</button>
</form>
<script>
function checkForm() {
var form = document.getElementById('test-form');
// 可以在此修改form的input...
// 继续下一步:
return true; //告诉浏览器继续提交
}
</script>
可以利用<input type="hidden">实现提交表单时不传输明文口令
<!-- HTML -->
<form id="login-form" method="post" onsubmit="return checkForm()">
<!--用户名-->
<input type="text" id="username" name="username">
<!--用户输入的密码,因为没有name使用密码不会被提交-->
<input type="password" id="input-password">
<input type="hidden" id="md5-password" name="password">
<button type="submit">Submit</button>
</form>
<script>
function checkForm() {
var input_pwd = document.getElementById('input-password');
var md5_pwd = document.getElementById('md5-password');
// 把用户输入的明文变为MD5:
md5_pwd.value = toMD5(input_pwd.value);
// 继续下一步:
return true;
}
</script>
11、事件代理(事件委托)
前面已经说过什么是事件冒泡,那么现在由于事件会在冒泡阶段向上传播到父节点,因此可以把子节点的监听函数定义在父节点上,由父节点的监听函数统一处理多个子元素的事件。这种方法叫做事件的代理(delegation)
以无序列表为例
var ul = document . querySelector('ul'); //父级
ul. addEventListener('click', function (event) {
//获取li标签具体内容
if (event.target.tagName.toLowercase() === 'li') {
console.log( event. target. innerHTML);
//some code
}
}
12、定时器
JavaScript 提供定时执行代码的功能,叫做定时器(timer), 主要 由setTimeout()和setinterva() 这两个函数来完成。.它们向任务队列添加定时任务
12.1、setTimeout
setTimeout函数用来指定某个函数或某段代码,在多少毫秒之后执行。它返回一个整数,表示定时器的编号,以后可以用来取消这个定时器。
var timerId = setTimeout(func|code, delay);
setTimeout函数接受两个参数,第一个参数funclode是将要推迟执行的函数名或者一段代码, 第二个参数delay是推迟执行的毫秒数
setTimeout(function(){
console.1og("定时器")
},1000)
定时器可以进行取消
var id = setTimeout(f,1000) ;
clearTimeout(id) ;
注意: 在定时器里的this关键字指向全局环境
12.2、setInterval
setInterval函数的用法与setTimeout完全-致, 区别仅仅在于setnterval指定某个任务每隔一段时间就执行一次, 也就是无限次的定时执行
var timer = setInterval(function() {
console.1og(2);
},1000)
13、浏览器优化
1、防抖
对于短时间内连续触发的事件(上面的滚动事件),防抖的含义就是让某个时间期限(如上面的1000毫秒)内,事件处理函数只执行一次
function debounce(fn, delay){
var timer = null ;
return function(){
if(timer){
clearTimeout (timer)
timer = setTimeout( fn, delay)
}
//滚动事件
window.onscroll = debounce(scrollHandle , 200)
function scrollHandle(){
var scrollTop = document . documentElement . scrollTop ;
console. log(scrol1Top);
弊端:如果鼠标一直拖着滚动条则不会触发
2、节流
和防抖类似,可以说是防抖的改进版,鼠标一直拖着滚动条可以触发
function throttle(fn,dalay){
var valid = true;
// valid为true的时候改为false
if(!valid){
return false;
}
valid = false;
//定时把valid改成true
setTimeout(function(){
fn();
valid = true;
},dalay)
}
//滚动事件
window.onscroll = throttle(scrollHandle , 200)
function scrollHandle(){
var scrollTop = document . documentElement . scrollTop ;
console. log(scrol1Top);
应用场景
- 搜索框input事件,例如要支持输小实时搜索可以使用节流方案(间隔一 -段时间就必须查询相关内容),或者实现输入间隔大于某个值(如500ms) ,就当做用户输入完成,然后开始搜索,具体使用哪种方案要看业务需求
- 页面resize事件,常见于需要做页面适配的时候。需要根据最终呈现的页面情况进行dom渲染(这种情形般是使用防抖,因为只需要判断最后一 次的变化情况)
九、jQurey
1、jQurey引入
在jQurey的官网下载,会弹出链接,右击链接另存为就可以,然后复制到你的项目里就完成了本地导入
你的项目下面就会出现一个jquery的js文件
2、基本语法
$(选择器).action()
<a href="" id="test -jquery" >点我</a>
//选择器就是css的选择器
$('#test-jquery').click(function () {
alert( 'he1lo, jQuery' );
})
//原生js,选择器少,麻烦不好记
//标签
document . getElementsByTagName();
//id
document . getElementById();
//类
document . getElementsByClassName();
$('p').click(); //标签选择器
$('#id1').click(); //id选择器
$('.class1').click() //class选择器
3、事件
3.1、鼠标事件
- click: 鼠标单击时触发;
- dblclick:鼠标双击时触发;
- mouseenter:鼠标进入时触发;
- mouseleave:鼠标移出时触发;
- mousemove:鼠标在DOM内部移动时触发;
- hover:鼠标进入和退出时触发两个函数,相当于mouseenter加上mouseleave。
3.2、键盘事件
键盘事件仅作用在当前焦点的DOM上,通常是<input>和<textarea>。
- keydown:键盘按下时触发;
- keyup:键盘松开时触发;
- keypress:按一次键后触发。
3.3、其他事件
- focus:当DOM获得焦点时触发;
- blur:当DOM失去焦点时触发;
- change:当
<input>、<select>或<textarea>的内容改变时触发; - submit:当
<form>提交时触发; - ready:当页面被载入并且DOM树完成初始化后触发。
操作DOM元素
jQuery对象的text()和html()方法分别获取节点的文本和原始HTML文本
<!-- HTML结构 -->
<ul id="test-ul">
<li class="js">JavaScript</li>
<li name="book">Java & JavaScript</li>
</ul>
分别获取文本和HTML:
$('#test-ul li[name=book]').text(); // 'Java & JavaScript'
$('#test-ul li[name=book]').html(); // 'Java & JavaScript'
节点文本操作
$(' #test-u11i [name=python]'). text(); //获得值
$(' #test-u1 1i [name=python]'). text('设置值'); //设置值
$(' #test-u1').htm1(); //获得值
$( ' #test-u1').htm7('<strong>123</strong>'); //设置值
CSS的操作
$(' #test-u1 1i [name=python]'). css({"color","red"})
元素的显示和隐藏:本质display :none
$(' #test-u11i [name=python] ').show()
$( ' #test-u1 1i [name=python]').hide()
ES6新特性
ECMAScript和JavaScript的关系是,前者是后者的规格,后者是前者的一种实现,常场合,这两个词是可以.互换的。
1、cmd命令
- 选择盘符:盘符名加冒号
E: - 查看盘符及目录下文件与文件夹:
dir - 清空命令行信息:
cls - 进入文件夹或目录:
cd文件夹名称 - 返回到上一-级目录:
cd - 快速补全目录或文件夹名称:
tab - 创建文件夹:
mkdir文件夹名称 - 查看历史输入过的命令:
上下按键
2、Bable安装
babel是es6的转码器可以将es6 转为es5
- 在项目库下新建文件夹(名字随意,以 my_babel 为例),启用终端,安装bable
cnpm install --save-dev @babel/core
- 配置文件
.babelrcBabel的配置文件是.babelrc,存放在项目的根目录下。使用Babel的第一步, 就是配置这个文件。该文件用来设置转码规则和插件,基本格式如下
{
"presets": [],
"plugins": []
}
- 转码规则 presets字段设定转码规则,官方提供以下的规则集,你可以根据需要安装
cnpm install --save-dev @babel/preset-env
- 加入规则
{
"presets": [
"@babel/env"
],
"plugins": []
}
- 转码
cnpm install --save-dev @babel/cli
例如 在my_bable下新建文件如:es6Demo,输入一个简单的es6代码
input.map(item => item+1);
转为js为
input.map(function (item) {
return item + 1;
});
常用bable指令
#转码结果输出到标准输出
$ npx babel example.js
#转码结果写入一个文件
#--out-file或-o参数指定输出文件
$ npx babel examp1e.js --out-file compiled.js
#或者
$ npx babel example.js -o compiled.js
#整个目录转码
# --out-dir或-d参数指定输出目录
$ npx babel src --out-dir lib
#或者
$ npx babel src -dlib
3、解构赋值
可以用于对象,就是把对象给拆解了,方便调用
比如
//定义对象
var user = {
name : "breeze"
age : 19
}
console.lon(user.name)
console.lon(user.age)
//解构赋值
const {name,age} = user
console.log(name)
console.lon(age)
4、字符串新增方法
类似于字符串间的比较
-
includes():返回布尔值,表示是否找到了参数字符串
-
startsWith():返回布尔值,表示参数字符串是否在原字符串的头部
-
endsWith():返回布尔值,表示参数字符串是否在原字符串的尾部
-
repeat():返回一个新字符串,表示将原字符串重复n次。
'x'.repeat(3) // "xxx"
'he11o'.repeat(2) // "he11ohe11o"
'na'. repeat(0) // ""
- padStart(),padEnd() ES2017引入了字符串补全长度的功能。如果某个字符串不够指定长度,会在头部或尾部补全。padStar() 用于头部补全,padEnd() 用于尾部补全。
'x'.padstart(5, 'ab') // ' ababx'
'x'.padstart(4,'ab') // ' abax'
'x'.padEnd(5, 'ab') // ' xabab '
'x'.padEnd(4,' ab') // 'xaba'
- at() at()方法接受一个整数作为参数,返回参数指定位置的字符,支持负索引(即倒数的位置)。
const str = 'hello'
str.at(1) // "e"
str.at(E1) // "o"
5、拓展运算符
扩展运算符(spread) 是三个点(..). 。将一个数组转为用逗号分隔的参数序列.
console.log(...[1,2,3])
//123
console.1og(1, ...[2,3,4],5)
//12345
替代函数的apply方法 由于扩展运算符可以展开数组,所以不再需要apply方法,将数组转为函数的参数了
// ES5的写法
Math . max . apply(nu11,[14, 3,77])
// ES6的写法
Math . max(...[14,3,77] )
//等同于
Math . max(14, 3,77);
合并数组 扩展运算符提供了数组合并的新写法
const arr1=['a','b'];
const arr2 = ['c'];
const arr3 = ['d', 'e'];
// ES5的合并数组
arr1. concat(arr2,arr3) ;
// ['a','b','c','d', 'e' ]
//ES6的合并数组
[...arr1,...arr2,...arr3]
// [ 'a','b','c','d','e' ]
6、数组新增方法
Array.from方法用于将类数组转为真正的数组
常见的类数组有三类:
- arguments
- 元素集合
- 类似数组的对象
类数组,伪数组,只能使用数组的读取方式和length属性,不能使用数组方法:push
例如:
- arguments 可以用来读取可变参数
function add() {
console.log(arguments); //读取到10 20 30
console.log(arguments[0]);
console.log(arguments[1]);
console.log(arguments[2]);
}
add(10, 20, 30);
- 元素集合
let titles = document.querySelectorAll("h3");
console.log(titles);
- 类似数组的对象
var user = {
0: "iwen",
1: 20,
2: "男",
length: 3,
};
console.log(user.length);
使用Array.from()转化为数组
function add() {
console.log(arguments); //读取到10 20 30
console.log(Array.from(add));
}
add(10, 20, 30);
let titles = document.querySelectorAll("h3");
console.log(Array.from(titles));
var user = {
0: "iwen",
1: 20,
2: "男",
length: 3,
};
console.log(Array.from(user));
Array.of()用于转化一组值为数组
例如:
console.log(Array.of(1,2,3,4)) //[1,2,3,4]
箭头函数
与原始写法的对应关系
不同情况下
其实看起来就是用箭头代替了function这个词汇
使用注意点
对于普通函数来说,内部的this指向函数运行时所在的对象,但是这一点对箭头函数不成立。 它没有自己的this对象 ,内部的this就是定义时上层作用域中的this
Promise对象
基本概念
Promise是异步编程的一种解决方案,比传统的解决方案——回调函数和事件一更合理和更强大。 它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法, 原生提供了Promise 对象
所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作) 的结果。从语法上说,Promise 是一个对象, 从它可以获取异步操作的消息。Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理
有了Promise对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。此外,Promise 对象提供统-的接口,使得控制异步操作更加容易,
基本用法
promisse是一个构造函数,用来生成promise实例
const promise = new Promi se( function(resolve,reject) {
// some code
if (/*异步操作成功*/){
resolve(value);
} else {
reject(error);
}
});
Promise实例生成以后,可以用then方法分别指定resolved状态和rejected状态的回调函数。
promise.then (function (fvalue) {
//success
},function(error) {
// failure
});
例子:加载图片
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div id="box">图片加载中</div>
<script>
var box = document.getElementById("box");
function loadImageAsync(url) {
const promise = new Promise(function (resolve, reject) {
// 异步处理消耗时间的代码
const image = new Image(); //创建image对象
image.src = url;
image.onload = function () {
resolve(image);
};
image.onerror = function () {
reject(new Error(`可能没有在该${url}地址加载图片`));
};
});
return promise;
}
const promise = loadImageAsync(
"https://w.wallhaven.cc/full/9m/wallhaven-9mjoy1.png"
);
promise.then(
function (data) {
//success
box.appendChild(data);
box.innerHTML = "图片加载成功";
},
function (data) {
//fail
box.innerHTML = "图片加载失败";
console.log(error);
}
);
</script>
</body>
</html>
async函数
实际开发中,经常遇到一组异步操作,需要按照顺序完成。比如,依次远程读取一组 URL,然后按照读取的顺序输出结果。
总结
如果有误,欢迎指错纠正