万字JavaScript自学总结

199 阅读13分钟

前言

自己学习学习的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

那我们怎么看字符串长度呢?

  1. 不带转义字符的字符 如:abc ,!x=/ ,其长度为 9 (注意有空格)
  2. 带转义字符的字符 如: abc !,\n ,其中的\n为转义字符(换行符),计算字符串长度时只能计作一个字符,所以该字符串的长度为 7
  3. 特殊转义符的字符串 如:abcd\0ef ,其中转义字符 \0 是字符串结束符,所以在计算长度时为 4
  4. 反斜杠 如: abc !,\\n , 因为反斜杠不能作为任何合法的字符,所以是转义符\\加上n长度为 8

2.5、 不可变性

字符串是不可变的,如果对字符串的某个索引赋值,不会有任何错误,但是,也没有任何效果

3、布尔值

一个布尔值只有truefalse两种值 ; ||运算是或运算 ; !运算是非运算 ; &&运算是与运算

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(27); // 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 = {1234null,ture,'hello'}//推荐
new Array = (1234null,ture,'hello')//创建了数组[1,2,3,4,null,ture,'hello']

arr[0]; // 返回索引为0的元素,即1
arr[5]; // 返回索引为5的元素,即true
arr[6]; // 索引超出了范围,返回undefined

1、取得Array的长度

.length 可以得到并改变数组长度,变长加空数组,变短会使元素丢失

直接给Arraylength赋一个新的值会导致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 = ["尚学堂"100true];
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']来访问xiaohongname属性,不过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

SetMap类似,也是一组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可以采用下标循环,遍历MapSet就无法使用下标。为了统一集合类型,ES6标准引入了新的iterable类型,ArrayMapSet都属于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标准引入的 只需要获得Arrayelement

var a = ['A', 'B', 'C'];
a.forEach(function (element) {
   console.log(element);
});

Map的回调函数参数依次为valuekeymap本身

var m = new Map([[1, 'x'], [2, 'y'], [3, 'z']]);
m.forEach(function (value, key, map) {
    console.log(value);
});

SetArray类似,但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一XXXalert(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: 2000age: 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, -15) // 5
Math.min(2, -15) // -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的原型是谁?我们把这种链状关系叫原型链 image.png

深入原型链

image.png

八、浏览器

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树),就是由各种不同类型的节点组成。 每个节点可以看作是文档树的一片叶子

image.png

节点类型

  • Document: 整个文档树的顶层节点
  • DocumentType: doctype标签
  • Element: 网页的各种HTML标签
  • Attribute: 网页元素的属性(比如class="right")
  • Text: 标签之间或标签包含的文本
  • Comment: 注释
  • DocumentFragment:文档的片段(不常用)

要操作一个Dom节点,就必须要先获得这个Dom节点,获取方式对应 css选择器,比如标签选择器、idclass

  <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

innerTextnnerHTML 类似,不同的是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事件处理

image.png HTML事件:缺点: HTML和JS没有分开

4.2、DOMO级事件处理

image.png DOM0事件:优点: HTML 和IS是分离的

缺点:无法同时添加多个事件

4.3、DOM2级事件处理

image.png 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获得对应的用户输入值,并且还适用于textpasswordhidden以及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的官网下载,会弹出链接,右击链接另存为就可以,然后复制到你的项目里就完成了本地导入

image.png

你的项目下面就会出现一个jquery的js文件

image.png

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 &amp; JavaScript</li>
</ul>

分别获取文本和HTML:

$('#test-ul li[name=book]').text(); // 'Java & JavaScript'
$('#test-ul li[name=book]').html(); // 'Java &amp; 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

  1. 在项目库下新建文件夹(名字随意,以 my_babel 为例),启用终端,安装bable
cnpm install --save-dev @babel/core
  1. 配置文件.babelrc Babel的配置文件是.babelrc,存放在项目的根目录下。使用Babel的第一步, 就是配置这个文件。该文件用来设置转码规则和插件,基本格式如下
{
"presets": [],
"plugins": []
}
  1. 转码规则 presets字段设定转码规则,官方提供以下的规则集,你可以根据需要安装
cnpm install --save-dev @babel/preset-env
  1. 加入规则
     {
    "presets": [
        "@babel/env"
    ],
    "plugins": []
    }
  1. 转码
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, ...[234],5)
//12345

替代函数的apply方法 由于扩展运算符可以展开数组,所以不再需要apply方法,将数组转为函数的参数了

// ES5的写法
Math . max . apply(nu11,[14377])
// ES6的写法
Math . max(...[14377] )
//等同于
Math . max(14377);

合并数组 扩展运算符提供了数组合并的新写法

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

例如:

  1. 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);

  1. 元素集合
let titles = document.querySelectorAll("h3");
      console.log(titles);
  1. 类似数组的对象
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]

箭头函数

与原始写法的对应关系

image.png

不同情况下 image.png

其实看起来就是用箭头代替了function这个词汇

image.png

使用注意点

对于普通函数来说,内部的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,然后按照读取的顺序输出结果。

总结

如果有误,欢迎指错纠正

参考文档

廖雪峰--JavaScript教程

jQuery文档