前言

本章节是对前面从章节2-章节12的一个梳理,将里面经常提到的一些常见问题,写法做一个说明和总结。

# 1、对象的方法

# ① 对象属性输出

对象属性输出 [见章节6]

# ② 对象方法(函数)调用

对象方法(函数)调用 [见章节6]

# ③ 枚举对象属性和值(键值对)---for...in(遍历对象)

枚举对象属性和值(键值对)---for...in(遍历对象) [见章节6]

# ④ 删除对象的属性

删除对象的属性 [见章节6]

# ⑤ 对象方法:Object.assign() -- 合并一个或多个对象中的属性,并返回合并后的对象

let obj1 = {
    name:'迪丽热巴',
    age:31,
    sex:'女'
}
let obj2 = {
    love:'喝咖啡',
    sport:'篮球',
    name:'古力娜扎'
}
//console.log(Object.assign(obj1,obj2));
//{name: '古力娜扎', age: 31, sex: '女', love: '喝咖啡', sport: '篮球'}
console.log(Object.assign(obj2,obj1));
//{love: '喝咖啡', sport: '篮球', name: '迪丽热巴', age: 31, sex: '女'}

# ⑥ 对象方法:Object.create() -- 创建一个新对象,基于参数对象的prototype

具体面向对象与原型在讲

let girl = {
    age:20,
    info:function(){
        return `我是${this.name},年龄:${this.age}`;
    }
};
console.log(girl.info());//我是undefined,年龄:20岁
girl.name = '大美丽';
console.log(girl.info());//我是大美丽,年龄:20岁

let n = Object.create(girl);
n.name = '车模';
n.age = 28;
console.log(n.info());//我是车模,年龄:28岁

# ⑦ 对象方法:Object.freeze() -- 冻结对象,冻结后的对象不能再进行修改

let obj = {
    name:'黑丝空姐'
};
Object.freeze(obj);
obj.name = '性感车模';
console.log(obj.name);//黑丝空姐

# ⑧ 对象方法:Object.keys() -- 以数组的形式返回对象所有的属性

let girl = {
    age:20,
    name:'性感车模',
    info:function(){
        return `我是${this.name},年龄:${this.age}`;
    }
};
console.log(Object.keys(girl));//['age', 'name', 'info']

# ⑨ 对象方法:Object.values() -- 以数组的形式返回对象所有的值

let girl = {
    age:20,
    name:'性感车模',
    info:function(){
        return `我是${this.name},年龄:${this.age}`;
    }
};
console.log(Object.values(girl));//[20, '性感车模', ƒ]

# ⑩ 对象方法:Object.entries() -- 以数组的形式返回对象所有的键和值

let girl = {
    age:20,
    name:'性感车模',
    info:function(){
        return `我是${this.name},年龄:${this.age}`;
    }
};
console.log(Object.entries(girl));//[ ['age', 20], ['name', '性感车模'], ['info', ƒ] ]

# 2、数组解构

# ① 数组解构基础用法

let text = ['迪丽热巴',31,'55kg'];
//希望取出数组前两个元素的值
let [ a , b ] = text;
console.log('解构a的值:' + a);//解构a的值:迪丽热巴
console.log('解构b的值:' + b);//解构b的值:31

# ② 数组解构省略元素

let text = ['迪丽热巴',31,'55kg'];
//想省略掉数组第二个元素,只想结构出:'迪丽热巴' 和 '55kg'
let [ a , , b ] = text;//中间元素用逗号空出来
console.log('解构a的值:' + a);//解构a的值:迪丽热巴
console.log('解构b的值:' + b);//解构b的值:55kg

# ③ 数组解构设置数组元素默认值

let text = ['迪丽热巴',31,'55kg'];
let [ a,b,c,d] = text;
console.log(a);//'迪丽热巴'
console.log(b);//31
console.log(c);//'55kg'
console.log(d);//undefined
//由于数组只有三个元素,我们解构了4个值,所以最后一个值因为不存在就是undefined,默认值
//如果希望第四个不存在的元素,默认值不是undefined,可以这么写
let [ a1,b1,c1,d1='大漂亮'] = text;
console.log(a1);//'迪丽热巴'
console.log(b1);//31
console.log(c1);//'55kg'
console.log(d1);//'大漂亮'

//当然如果有这个元素,那么默认值就失效了
let text = ['迪丽热巴',31,'55kg','性感'];
let [ a1,b1,c1,d1='大漂亮'] = text;
console.log(a1);//'迪丽热巴'
console.log(b1);//31
console.log(c1);//'55kg'
console.log(d1);//'性感'

# ④ 数组解构嵌套数组(多维数组)的结构赋值

let girls = ['迪丽热巴',['古力娜扎','杨超越'],'梁咏琪'];
let [a,[b]] = girls;
console.log(a);//'迪丽热巴'
console.log(b);//'古力娜扎'
//如果希望在嵌套数组(多维数组)中,想省略某些值
//比如在内层数组['古力娜扎','杨超越'] 只想结构出 '杨超越'怎么写
let [a1,[,b1]] = girls;
console.log(a1);//'迪丽热巴'
console.log(b1);//'杨超越'

# ⑤ 数组解构不定元素的解构赋值

let text = ['迪丽热巴',31,'55kg','大漂亮'];
//将第一个元素后面不确定的所有元素放入b中,可以使用展开运算符:获取数组当中剩余的元素
let [a,...b] = text;
console.log(a);//'迪丽热巴'
console.log(b);// [31, '55kg', '大漂亮']

# 3、对象解构

//普通例子
const girl = {
    name:'迪丽热巴',
    age:31,
    loves:{
        sport:'篮球',
        food:'武昌鱼',
        art:'弹钢琴'
    }
}
function getInfo(girl){
    console.log('姓名:' + girl.name);
    console.log('运动爱好:' + girl.loves.sport);
    console.log('喜欢的食物:' + girl.loves.food);
    console.log('艺术爱好:'+girl.loves.art);
}
getInfo(girl);
//虽然上面的例子可以实现,但是我们发现loves对象是嵌套在girl对象里面的,所以当我们访问loves对象里面的数据时候
//访问链就会写的很长,容易产生拼写错误,为此es6新语法给我们提供了一种解构写法

# ① 对象解构基础用法

let info = {
    nickname:'迪丽热巴',
    love:'弹钢琴',
    age:31
}
let { nickname, age }  = info;
console.log(nickname);// '迪丽热巴'
console.log(age);// 31

//如果解构当中的变量不和对象的变量一样,就会是undefined
let {nickname1,age1} = info;
console.log(nickname1);// undefined
console.log(age1);// undefined
//但如果我希望解构的变量能换个名字,怎么做,就涉及到解构重命名问题

# ② 对象解构重命名解构变量

let info = {
    nickname:'迪丽热巴',
    love:'弹钢琴',
    age:31
}
let { nickname:nickname1, age:age1 }  = info;
console.log(nickname1);// '迪丽热巴'
console.log(age1);// 31

# ③ 对象解构时的默认值

let info = {
    nickname:'迪丽热巴',
    love:'弹钢琴',
    age:31
}
//let {nickname,love, height} = info;
//如果我们希望解构的时候,对于没有的属性名解构默认值不是undefined,是我们自定义的值怎么写
// let {nickname,love, height='172cm'} = info;
//换个变量名
let {nickname,love, height:hg='172cm'} = info;
console.log(nickname);//'迪丽热巴'
console.log(love);//'弹钢琴'
//console.log(height);//undefined  '172cm'
console.log(hg);//'172cm'

//同样原对象里面有这个属性,默认属性就没有效果了
let { age=12 } = info;
console.log(age);//31

# 4、var和let、const的区别

重点理解var 和 let的区别,const是常量(不能修改的变量)

# ① var是window的属性声明的变量是全局变量(导致污染全局的问题)

var text = '迪丽热巴';
console.log(window.text);//'迪丽热巴'
let text1 = '迪丽热巴';
console.log(window.text1);//undefined
//即:在全局作用域下,var变量会挂载到window上,而let变量是不会挂载到window对象上的

# ② 在块级作用域方面的区别

function testVar(){
    if(true){
        var x = 10;
        let y = 10;
    }
    console.log(x);//输出 10
    //可以看到var的作用域是函数作用域,而不是块级作用域

    console.log(y);//y is not defined  访问不到
    //let作用域可以看成是块级作用域

    //因此我们在开发中,应该使用let而不是var,因为let的作用域更加严格,直观
}
testVar();

# ③ 重复声明变量的区别

var a = 10;
var a;//不会引发错误
console.log(a);//10

var a = 20;//重新赋值
console.log(a);//20
//即同一个作用域内,var可以重复声明同一个变量,不会报错
//原理:var声明的变量挂载到了window上,相当于重复声明就是重复给window.text赋值
// var a = 10; 相当于 window.a = 10;
// var a = 20; 可以理解成 window.a = 20;

//但是let不行
let b = 10;
let b = 20;//报错:不能重复声明

# ④ 变量提升方面的区别

console.log(a);//undefined
var a = 10;
console.log(a);//10
//var声明的变量会提升到作用域的顶部,但是不会提升它的赋值,相当于
//所以console.log(a); 理解成:
var a; 
console.log(a);//undefined


//但是let不同,let存在一个暂时性死区的概念:
//let声明的变量也会被提升到作用域的顶部,但是它不会被初始化
//所以我们在let声明之前访问这个变量,会报错
//我们一般称:从作用域开始到变量声明的这个位置叫做暂时性死区,
//在这期间这个let变量它是存在的,但是我们无法访问

console.log(b);
let b = 10;
console.log(b);
//暂时性死区,虽然b变量存在,但是我们无法访问它,就报错了

总结:我们在开发中,应该用let声明变量,const声明常量

# 5、函数参数默认值

# ① 函数参数默认值基础

function text(a,b=2,c=3){
   console.log('a:'+a);
   console.log('b:'+b);
   console.log('c:'+c);
}
text(); // undefined  2 3
//注意:什么时候使用参数默认值,一定是传递的是undefined才会使用
text(1,null,undefined); // 1   null   3


function love(a,b=2,c){
    console.log('a:'+a);
    console.log('b:'+b);
    console.log('c:'+c);
}
love();// undefined 2 undefined
//参数顺序不能跳跃传递,一定是按顺序的
love(1,3);//1 3 undefined 
//传递的是undefined才会使用默认参数
love(1,undefined,3);// 1 2 3

# ② 参数默认值对arguments的影响了解

function text(a,b){
   // 'use strict'
   console.log(arguments.length); // 2 
   console.log(a === arguments[0]); // true
   console.log(b === arguments[1]); // true
   a = 3;
   b = 4;
   console.log(arguments);
   console.log(a === arguments[0]); // true  false
   console.log(b === arguments[1]); // true  false
}
text(1,2);
//在我们前面讲的课程,这样的结果确实没什么问题,但是随着开发的深入,
//当我们在函数里面重新修改参数的时候,arguments也跟着修改是非常不合理的,会出问题
//官方也发现有问题,于是在es5的时候,出了一个严格模式 'use strict'
//使用严格模式之后,ab和arguments就不是对应的了
//就是ab可以改,但是arguments里面的东西不变
//这是严格模式下的正确做法,实际开发就应该按照严格模式进行

//那么跟参数默认值有什么关系呢?
//当使用参数默认值的时候,我们函数内部就是使用的严格模式
function text(a,b = 2){
    console.log(arguments.length); // 2 
    console.log(a === arguments[0]); // true
    console.log(b === arguments[1]); // true
    a = 3;
    b = 4;
    console.log(arguments);
    console.log(a === arguments[0]); // false
    console.log(b === arguments[1]); // false
 }
 text(1,2);
 //上面这个问题容易出面试题,开发中也会碰到

# ③ 参数默认值对函数length的影响了解

function text(a,b,c){

}
//length表示我们函数行参的数量
console.log(text.length);//3
//当时,当函数里面有参数默认值的时候就有变化
function love(a,b=2,c){

}
console.log(love.length);//1
//当有参数默认值的时候,就会认为这个函数可以只传前面第一个参数a,b参数就用默认值2
//计算形参数量的时候,就只会计算到参数默认值之前的数量,就是1个了

# ④ 函数默认表达式了解

let n=1;
function text(){
    return n++;
}
//给函数赋默认值,可以赋字面量如:123  '迪丽热巴'  true  {name:'迪丽热巴'}
//还可以是表达式:1+1
//问题在于表达式什么情况下进行运算,是先声明这个函数的时候就把它算出来
//还是调用函数love的时候,在去运行表达式,我们这里用函数text,执行这个函数text将表达式结果返回
//问题就是这个text()函数什么时候运行:
//结论:一定是在调用的时候运行的
function love(a,b=text()){
   console.log(a);
   console.log(b);
}
//调用运行
//当有参数传递的时候,1传给a,5传给b,不需要默认值,不用调用text()函数
love(1,5);// 1 5
//当只传了一个参数,就要用默认值了
//第一次调用的时候得到n的值,然后把n+1,所以第一次调用的时候 b的值为1,返回n的值,调用结束之后,n变成了2
love(1);//1 1 n=2
love(1);//1 2 n=3
love(1);//1 3 n=4
love(1);//1 4 n=5
//结论:参数默认值是可以给表达式的

# ⑤ 参数默认值的暂时性死区

//关于let,const的暂时性死区,我们上节课讲var和let,const区别的时候已经讲过了
//我们这里参数默认值也有暂时性死区
function text(a){
   return a * 2;
}
function love(a,b=text(a)){
    console.log(a);
    console.log(b);
}
love(1);// 1 2
//可以这么理解:
//let a = 1; let b = text(a) = 2;

love(2);// 2 4

//接下来,我们改一下传参
function box(a = text(b), b){
    console.log(a);
    console.log(b);
}
box(undefined,1);//报错
box(undefined,2);//报错
//分析:第一次参数undefined,让a使用默认值 text(b),第二个参数传1
//可以理解成:
//let a = text(b); 
//let b = 1;
//出现了暂时性死区,因为在let a = text(b); 的时候,b虽然有变量提升,b是存在但是b在暂时性死区里面,不能访问,所以报错了

# 6、函数剩余参数

//写一个函数,求出函数所有参数数字之和
// addSum(1);
// addSum(1,3);
// addSum(1,5,10,15);
// addSum(1,5,10,15,20);
//请开始你的表演:[有同学会想到章节9函数进阶—arguments写的阶乘递归函数]
function addSum(){
   let sum = 0;
   for(let i=0;i<arguments.length;i++){
      sum += arguments[i];
   }
   return sum;
}
console.log(addSum(1));
console.log(addSum(1,3));
console.log(addSum(1,5,10,15));
console.log(addSum(1,5,10,15,20));
//如果你能自己写出来,说明你前面学得还不错

//接下来我们要说的,是我们正在开发中,碰到的问题,以上的写法没有问题,但是有一个致命问题
//就是你无法通过函数名字和参数列表,无法看出这个函数到底要传几个参数,因为我们调用函数的时候
//是不会看它里面是怎么实现的,因为我们将来开发会用到很多第三方库,那里面会出现各种各样的函数
//你不知道它里面怎么写的,当然它咋写的不重要,但是要调用它,你只需要看它的函数名、返回结果及参数列表即可
//但是我们上面的做法在参数列表这里是空的,我在调用的时候,就很难知道要传几个参数,应该怎么传递
//当然在一个函数里面你可以清楚的看到,将来在工作当中用到的函数没有几十万个也有几万个,你还能清楚知道每个函数传几个参数吗
//这就是形参不明确导致的问题,在比如将来需要要改,第一个参数是一个字符串
//addSum('alert',1,5,10,15,20);addSum('log',1,5,10,15,20);
//那上面的函数又要改写,因为arguments接收的是所有参数,arguments[0]就是字符串,计算肯定出问题了
//为了解决这个问题,官方为我们提供了剩余参数的这个功能
function addSum1(type,...nums){
    // let sum = 0;
    // for(let i=0;i<arguments.length;i++){
    //    sum += arguments[i];
    // }
    // return sum;
    console.log(type);//'alert'
    console.log(nums);//[1,5,10,15,20]
    let sum = 0;
    for(let i=0;i<nums.length;i++){
       sum += nums[i];
    }
    return sum;
}
addSum1('alert',1,5,10,15,20);
//上面...nums表示剩余参数,改写之后函数非常明确,第一个参数传类型,第二个是一个剩余参数
//剩余参数就是我可以传1个参数,也可以传无限个参数,他们都放在一个数组里面了,就非常明确了
console.log(addSum1('alert',1,5,10,15,20));
console.log(addSum1('log',1,5,10,15));

//其实我们在现在学习中见过剩余参数的,比如console.log(...data) 括号里面就可以填剩余参数
function text(a=1,b=2,c=3){
    console.log(a);
    console.log(b);
    console.log(c);
    console.log(a,b,c);
}
text();
//在比如前面我们学习Math.max()求一组数据中的最大值 提示:Math.max(...values:number[])
//就是剩余参数,看这个提示就知道我们要传一组数据,都是数字,可以传一个1参数,可以传很多参数
//我们的浏览器将来用的第三方库,很多用到剩余参数,不在使用arguments了,arguments现在基本不用了

# ① 函数里面的剩余参数只能出现一个

 //报错
 function text(...a,...b){

 }
 //原因:
 text(1,2,4,5,6,90,15);
 //请问哪部分是第一个剩余参数,哪部分是第二个剩余参数
 //可以看出语义不明确,所以规定剩余参数只能有一个

# ② 函数里面的剩余参数只能放在最后

//报错
function text(a,...b,c){

}
//原因:
text(1,2,4,5,6,90,15);//依旧是语义不明确

function text(a,...b){

}

//注意:有同学会把剩余参数和我们前面讲数组对象解构的时候,扩展运算符(展开运算符)搞混了
//我们下节课讲一下展开运算符

# 7、展开运算符(扩展运算符)

const nums = [1,2,4,5,6,90,15];
//如果利用Math.max()求出最大值
console.log(Math.max.apply(null,nums));//90

//虽然说可以做出来,但是我让你求最大值,你搞个函数冒充,所以现在我们可以通过展开运算符解决

# ① 将数组元素展开成一组数据

const nums = [1,2,4,5,6,90,15];
//如果利用Math.max()求出最大值
//无非就是将数组里面的每个元素,依次展开放进括号里面
console.log(...nums);//1 2 4 5 6 90 15
console.log(Math.max(...nums));//90
//...nums叫展开运算符,可以把nums里面的数据依次展开放进相应的数据类型中

# ② 浅层克隆数组

const nums = [1,2,4,5,6,90,15];
const new_arr = [...nums];
console.log(new_arr);//[1, 2, 4, 5, 6, 90, 15]

以上两个方法是扩展运算符用得最多的地方:一个是在函数的参数位置,把一个东西展开作为参数依次传递如例子1;一个是在数组里面,对另一个东西进行展开如例子2

# ③ 展开运算符用法一:针对可迭代对象展开

就是三个点后面跟着的是一个可迭代对象,我们学过的如:arguments类数组对象,Set数据集合对象,伪数组(Dom树节点)等等,我们可以将这些对象转换成数组进行处理

const nums = [1, 2, 4, 5, 6, 90, 15];
const new_arr = [10,...nums,100];
console.log(new_arr);//[10, 1, 2, 4, 5, 6, 90, 15, 100]
const new_arr1 = [10,...nums,...nums,100];
console.log(new_arr1);//[10, 1, 2, 4, 5, 6, 90, 15, 1, 2, 4, 5, 6, 90, 15, 100]

通常用于:数组字面量,或者是函数参数位置进行展开

# ④ 展开运算符用法二:针对使用对象字面量形式的对象,可以采用展开运算符,做对象克隆和对象合并

//对象克隆
let obj1 = {
    name:'迪丽热巴',
    age:31,
    sex:'女'
}
let _obj1 = {...obj1};
//只是要注意,数组展开是将数组元素值一个一个展开,对象展开就是将对象字面量里面的键值对一个一个展开
//console.log(_obj1);//{name: '迪丽热巴', age: 31, sex: '女'}


//对象混入(对象合并)---出现相同属性,后者覆盖前者
let obj2 = {
    love:'喝咖啡',
    sport:'篮球',
    name:'古力娜扎'
}
//console.log(Object.assign(obj1,obj2));
//{name: '古力娜扎', age: 31, sex: '女', love: '喝咖啡', sport: '篮球'}
//还可以这么写
let obj = {
    ...obj1,
    ...obj2
};
//console.log(obj);
//{name: '古力娜扎', age: 31, sex: '女', love: '喝咖啡', sport: '篮球'}

//混入之后,还可以修改属性
let $obj = {
    ...obj1,
    ...obj2,
    age:50,
    sex:'男'
};
console.log($obj);
//{name: '古力娜扎', age: 50, sex: '男', love: '喝咖啡', sport: '篮球'}


//还可以讲数组展开到对象里面
const nums = [1, 2, 4, 5, 6, 90, 15];
const _nums = {
    ...nums
}
console.log(_nums);
//{0: 1, 1: 2, 2: 4, 3: 5, 4: 6, 5: 90, 6: 15}

# ⑤ 展开运算符和函数剩余参数的对比及混用

//对比
//展开运算符
const nums = [1, 2, 4, 5, 6, 90, 15];
const _nums = [1,100,...nums,200];
console.log(_nums);//[1, 100, 1, 2, 4, 5, 6, 90, 15, 200]
//函数剩余参数
function text(...nums){
    let sum = 0;
    for(let i=0;i<nums.length;i++){
        sum += nums[i];
    }
    return sum;
}
console.log(text(1,2,3,4,5));//15

//两者混用
//如果我想将nums数组传给函数求和呢?
console.log(text(...nums));//123







# 课程其它章节

# 章节1.课程介绍

# 章节2.javascript基础

# 1、变量

# 2、关键保留字

# 3、语法构成

# 4、数据类型

# 章节3.javascript运算符

# 1、一元运算符

# 2、算术运算符

# 3、赋值运算符

# 4、关系运算符

# 5、逻辑运算符

# 6、字符串、逗号、三元条件运算符

# 7、运算符优先级

# 章节4.流程控制语句

# 1、if语句

# 2、switch 语句

# 3、循环语句

# 4、for...in 语句 枚举对象的属性

# 5、break 和 continue 语句 退出循环语句

# 6、with语句

# 章节5.javascript函数

# 1、函数声明

# 2、函数 return 返回值

# 3、函数的arguments 对象

# 章节6.javascript对象

# 1、创建对象

# 2、对象属性输出、方法(函数)调用

# 3、对象中的方法及应用

# 章节7.javascript数组

# 1、创建及读取数组

# 2、数组中的属性和内置方法:toLocaleString()、valueOf()和 toString()

# 3、数组中的方法:join()、push()、pop()、shift()、unshift()、reverse()、sort()、concat()、slice()、splice()方法

# 4、数组更多操作方法

# 章节8.Date类型:时间和日期

# 1、Date 类型

# 2、格式化日期和时间

# 章节9.Function类型:函数进阶

# 1、函数的声明

# 2、作为值的函数

# 3、函数内部属性

# 4、函数的属性和方法

# 章节10.内置对象:Global、Math对象,变量、作用域和内存问题

# 1、内置对象: Global对象

# 2、内置对象: Math 对象

# 3、变量

# 4、作用域(执行环境)

# 5、 内存问题

# 章节11.匿名函数和闭包

# 1、匿名函数如何自动执行-()()方式

# 2、通过闭包实现局部变量的累加

# 3、循环里的匿名函数取值问题:任何变量都是最后一个值

# 4、闭包中的this对象问题

# 5、 匿名函数私有化:匿名函数自我执行模仿块级作用域,将变量私有化保护数据

# 章节12.javascript基本包装类型

# 1、Number 类型

# ① Number类型静态属性:MAX_VALUE、MIN_VALUE、NaN、NEGATIVE_INFINITY、POSITIVE_INFINITY、prototype
# ② Number类型方法:toString()、toLocaleString()、toFixed()、toExponential()、toPrecision()

# 2、String类型

# ① String类型属性:length、constructor、prototype
# ② String类型通用方法:valueOf()、toLocaleString()和 toString()方法
# ③ String类型方法:charAt(n)、charCodeAt(n)、数组方式截取字符串、concat(str1...str2)、slice(n,m)、substring、substr、indexOf、lastIndexOf、toLowerCase、toUpperCase、toLocaleLowerCase、toLocaleUpperCase、match、search、replace、replaceAll、split、fromCharCode、localeCompare、startsWith、endsWith、includes、trimStart、trimEnd、trim、repeat、魔法字符串

# 3、Array数组的常用方法

# ① 数组中的属性length,数组内置方法toLocaleString()、valueOf()和 toString()
# ② join、push、pop、shift、unshift、reverse、sort、concat、slice、splice
# ③ includes、reduce、find、findIndex、filter、map、forEach
# ④ indexOf、lastIndexOf、at、fill、copyWithin、isArray、es6的扩展运算符、every、some、for...of遍历、keys()、values()、entries()、reduceRight、flat、flatMap、from、of
# ⑤ 集合类型Set()属性方法:size属性、add、has、delete、clear方法,迭代遍历数据:keys()、values()、entries()、for...of遍历,forEach遍历
# ⑥ 小结拓展:获取两个数组交集、并集、差集,获取数组随机元素(验证码)

# 章节13.函数对象数组小结

# ① 对象的方法:for...in(遍历对象)、Object.assign()、Object.create()、Object.freeze()、Object.keys()、Object.values()、Object.entries()
# ② 数组解构:基础用法、省略元素、设置数组元素默认值、嵌套数组(多维数组)的结构赋值、不定元素的解构赋值
# ③ 对象解构:基础用法、重命名解构变量、对象解构时的默认值
# ④ var和let、const的区别
# ⑤ 函数参数默认值:对arguments的影响、对函数length的影响、函数默认表达式、参数默认值的暂时性死区
# ⑥ 函数剩余参数:剩余参数只能出现一个、剩余参数只能放在最后
# ⑦ 展开运算符:针对可迭代对象展开、字面量形式的对象做对象克隆和对象合并

# 章节14.浏览器对象模型BOM及浏览器检测

# ① window 对象:属性和方法、系统对话框、调出打印机print()、网页新建窗口open()、窗口页面的位置:screenX(screenLeft)和 screenY(screenTop)、窗口页面的大小:innerWidth和 innerHeight,outerWidth 和 outerHeight,document.documentElement.clientWidth和document.documentElement.clientHeight
# ② window对象:超时调用:setTimeout()方法、取消超时调用:clearTimeout()方法、间歇调用:setInterval()方法、取消间歇调用:clearInterval()方法、模拟定时器功能,超时调用模拟间歇
# ③ location 对象:获取网址相关信息、assign()方法跳转到指定页面、reload()方法、repalce()方法、获取网址url参数中的键值对、history 对象 : 属性:length,方法:back()、forward()、go(num)
# ④ 获取浏览器相关信息、浏览器插件检测、MIME 类型检测、判断设备是安卓、苹果、是否在微信上面浏览网页、用户查看网页的设备是电脑设备,还是手机设备

# 章节15.网页文档对象模型DOM

# 1、理解DOM

# ① DOM节点树,节点种类:元素节点、文本节点、属性节点

# 2、查找节点信息方法

# ① getElement系列: getElementById()方法,getElementById()方法获取的元素节点属性:tagName、innerHTML等, 获取及设置元素html属性:id,title,style,className等,getElementsByTagName()方法,getElementsByName()方法,getElementsByClassName()方法
# ② querySelector系列: querySelector()方法,querySelectorAll()方法
# ③ 属性操作系列: getAttribute()方法,setAttribute()方法,removeAttribute()方法
# ④ node节点属性: nodeName、nodeType、nodeValue
# ⑤ 层次节点属性: childNodes属性,firstChild 和 lastChild 属性,ownerDocument 属性,parentNode 属性,previousSibling 属性,nextSibling 属性,忽略空白文本节点,attributes 属性

# 3、操作节点

# ① document.write()方法,createElement()方法,appendChild()方法,createTextNode()方法, insertBefore()方法,模拟在指定节点的后面添加一个节点,repalceChild()方法,cloneNode()方法,removeChild()方法

# 4、DOM 类型、扩展、操作内容

# ① DOM 类型: Document类型补充(获取html节点对象,获取body节点对象,获取文档声明:DOCTYPE对象,document.title,document.images,document.links等),Text类型补充(normalize()方法,splitText(num)方法,deleteData删除字符,insertData插入字符,replaceData替换字符,substringData获取字符)
# ② DOM 扩展: scrollIntoView(), children 属性,contains()方法
# ③ DOM操作网页内容:innerText、innerHTML、outerText、outerHTML

# 5、DOM实战:操作表格

# ① DOM创建表格
# ② HTML DOM 来操作表格: 获取表格元素对象, 获取表格的标题对象<caption>,获取表头表尾<thead>、<tfoot>、<tbody>,获取表格的行数,获取表格主体里的行数,获取表格主体内第一行的单元格数量(tr),获取表格主体内第一行第一个单元格的内容(td),删除标题、表头、表尾、行、单元格,HTML DOM 创建一个表格

# 6、操作CSS样式

# ① 行内样式style的获取、赋值、移除属性removeProperty,计算后的样式获取(行内、内联、外联样式):window 对象下getComputedStyle()方法

# 7、操作页面样式

# ① className关键字设置样式,创建函数:hasClass() 判断是否存在某个类名,addClass() 如果不存在的这个类名,添加这个类名,removeClass() 如果存在的这个类名,删除这个类名

# 8、操作CSS外联样式表.css文件

# ① 获取CSSStyleSheet,外联的css样式表对象

# 9、DOM元素尺寸(元素大小)和位置(元素位置)

# ① 获取元素 CSS 大小回顾:通过 style 内联获取元素大小,通过计算getComputedStyle()方法获取元素大小,通过 CSSStyleSheet 对象中的 cssRules属性获取元素大小(需将网页放到服务器上查看)
# ② 获取元素实际大小:clientWidth 和 clientHeight:获取可视区的元素大小,可以得到元素内容及内边距所占据的空间大小,scrollWidth 和 scrollHeight:获取滚动内容的元素大小,offsetWidth 和 offsetHeight:获取元素大小,包含边框、内边距和滚动条
# ③ 获取元素周边大小位置:clientLeft 和 clientTop:获取元素设置了左边框和上边框的大小;offsetLeft 和 offsetTop:获取当前元素相对于父元素的位置;scrollTop 和 scrollLeft:这组属性可以获取滚动条被隐藏的区域大小(滚动条滚动高度宽度),也可设置定位到该区域(定位滚动条); getBoundingClientRect()方法:返回一个矩形对象,包含四个属性:left、top、right和 bottom,分别表示元素各边与页面上边和左边的距离

# 10、动态加载脚本

# ① 动态加载js文件,动态加载样式表

# 章节16.事件

# 1、事件基础知识

# ① 事件处理函数列表
# ② 内联模型
# ③ 脚本模型

# 2、事件处理函数分类

# ① 鼠标事件:click,dblclick,mousedown,mouseup,mouseover,mouseout,mousemove
# ② 键盘事件:keydown,keypress,keyup
# ③ HTML事件(包括表单事件):load,unload,resize,scroll,select,change,input,submit,reset,focus,blur

# 3、事件对象

# ① this 关键字和上下文
# ② 获取事件对象
# ③ 获取鼠标按钮(左键、右键、中间滚轮)
# ④ 可视区及屏幕坐标:clientX,clientY,screenX,screenY,鼠标点击位置距离页面顶部距离(带滚动条)
# ⑤ 修改键:shiftKey对应Shfit 键,ctrlKey对应 Ctrl 键,altKey 对应 Alt 键,metaKey 对应 windows 键,判断是否按下了它们
# ⑥ 键盘事件:键码(键盘上的任意键)keyCode,字符编码(键盘上可以输出字符的键)charCode
# ⑦ 事件对象的常用属性和方法:target,事件冒泡,取消:e.stopPropagation()
# ⑧ 事件对象其他属性方法:relatedTarget(在 mouseover 和 mouseout 事件中获取),e.preventDefault(),contextmenu取消鼠标右击弹出的菜单,鼠标滚轮:mousewheel

# 4、事件绑定

# ① 剖析传统事件绑定问题:同名事件后者覆盖前者,this 传递问题
# ② 现代事件绑定处理函数:添加事件addEventListener(),删除事件removeEventListener(),设置冒泡和捕获

# 章节17.表单处理及错误处理与调试

# 1、表单基础知识

# ① 获取form对象的方法
# ② 提交表单:默认提交form表单按钮type="submit",js中表单提交及阻止提交,让没有提交功能的按钮(其它元素)完成表单提交使用的是form.submit()方法,实现使用键盘 CTRL + enter(回车键)提交数据
# ③ 预防表单数据重复提交,表单重置:按钮重置type="reset",js重置 form.reset()方法

# 2、使用HTML DOM获取表单控件元素

# ① elements属性获取表单控件元素集合
# ② 多个表单字段都使用同一个 name,如单选框多选框,常用属性
# ③ 表单共有字段方法:foucs(),blur(),表单共有的字段事件:blur,change,input,focus

# 3、表单中的文本框

# ① input.value 和 textarea.value 获取输入的内容,defaultValue获取默认设置的value值
# ② 选择文本:使用 select()方法,可以将文本框里的文本选中,并且将焦点设置到文本框中
# ③ 选择部分文本:setSelectionRange()方法,这个方法接受两个参数:索引和长度
# ④ select 事件,选中文本框文本后触发
# ⑤ 获取选择的文本,两个属性:selectionStart 和 selectionEnd
# ⑥ 文本过滤输入(表单验证,文本验证,输入框验证)
# ⑦ 剪切事件:cut,复制事件:copy,粘贴事件:paste,禁用输入法
# ⑧ 利用正则表达式将用户输入的非数字字符替换成空,只留下数字
# ⑨ 输入框自动切换焦点到下一个输入框(类似Tab键),maxlength属性可输入的最大字符长度

# 4、表单中的下拉列表(选择框)

# ① 获取下拉列表对象
# ② 下拉列表多选属性 multiple="multiple"(按住键盘CTRL键进行多选),size显示的行数
# ③ 属性 options(下拉选项的集合)
# ④ 选择选项:选择一项的使用selectedIndex属性,监听的是下拉列表的change事件
# ⑤ 下拉列表动态添加选择项: 使用Option 构造函数,add方法添加选项
# ⑥ 下拉列表动态移除选择项:三种方式(removeChild移除、remove()方法移除和 null 移除)
# ⑦ 下拉列表动态移动选择项(两个下拉列表选项移动)
# ⑧ 下拉列表动态排序选择项(选项排序):属性index
# ⑨ 获取单选框或者多选框选择的值: 判断checked属性是否为真判断选中的项,defaultChecked判断项目原本设置的默认值

# 5、错误与调试

# ① 浏览器错误报告,错误处理:try-catch 语句,finally 子句,错误类型
# ② try-catch使用场景,抛出错误,错误事件error:处理DOM对象产生错误时候使用,比如加载图片失败,错误处理策略,调试技术和调试工具

# 章节18.数据Cookie、XML、JSON

# 1、Cookie、sessionStorage、localStorage

# ② 封装cookie(创建,获取,删除)
# ③ sessionStorage、localStorage

# 2、XML

# ① 创建 XMLDOM 对象(document.implementaion,DOMParser类型创建XMLSerializer类型进行序列化成字符串),解析错误
# ② 加载读取外部xml文件
# ③ XPath操作XML
# ④ 封装XPath操作xml文件

# 3、JSON

# ①JSON 语法,可以表示三种类型的值
# ② 获取外部json文件
# ③ 解析json字符串(将json字符串转成数组对象——json结构数据):JSON.parse()方法
# ④ js原生值数组、对象转成json字符串--JSON.stringify()
# ⑤ toJSON



# 其它学期课程

# 第一学期(学习顺序:01)

第一学期课程专为零基础的学员定制录制的,纯html+css做企业网站的网页,主讲html和css的相关基础知识,flex布局相关知识,封装css基础样式库,引入字体图标及网页开发基础布局思维,完成企业网站网页的开发过程。

[第一学期学习视频]

# 第二学期【第1季】(学习顺序:02)

主讲JavaScript的基础,建议所有学员观看。
[第1季学习文档] [第1季学习视频]

# 第二学期【第2季】(学习顺序:03)

JavaScript中的面向对象,类,ajax,封装js库过渡到jQuery, vue.js基础配置网站页面,建议所有学员观看。
[第2季学习文档] [第2季学习视频]

# 第二学期【第3季】(学习顺序:04)

egg.js基础,响应式网页布局,Bootstrap框架,响应式后台系统管理,完整企业网站前后台开发,建议所有学员观看。
[第3季学习文档] [第3季学习视频]

# 第二学期【第4季】(学习顺序:05)

主要对第三季,同学们开发的企业网站,进行一个完整的上线运维流程的一个讲解,同学们将网站开发完成之后,如何进行上线运维,将项目交付给客户。
[第4季学习文档] [第4季学习视频]

更新时间: 2024年11月19日星期二中午11点54分