HTML+CSS+JavaScript基础知识总结

咸疏珂
2023-12-01

目录

一、HTML+CSS

1. 如何理解HTML的语义化

2. 从浏览器地址栏输入url回车会发生什么

3. 溢出的文字显示省略号

4. css选择器和优先级

 css选择器

 5. BFC

6. 水平垂直居中的方法

 二、JavaScript

1. 基本数据类型

2. 数组的使用

 一、数组序列化

 二、栈和队列方法

三、排列方法

 四、操作方法

 五、位置方法

 六、迭代方法

 2.1 利用函数求任意个数的最大值

2.2 利用函数翻转任意数组 reverse 翻转

 2.3 利用函数冒泡排序 sort 排序

2.4 利用函数判断闰年

 2.5 利用函数判断闰年

 2.6 利用set方法数组去重

 3. 作用域和作用域链

3.1 预解析

 三、ES6新特性

 1. let和const关键字

2. 原型和原型链

3. 模板字符串

 4. 扩展运算符

 5. 箭头函数

6. 解构赋值

7. Symbol

8. Promise

9.  类的实例属性

 10.  new关键字

后续更新中....


一、HTML+CSS

1. 如何理解HTML的语义化

  • 让人更容易读懂(增加代码可读性)。
  • 让搜索引擎更容易读懂,有助于爬虫抓取更多的有效信息,爬虫依赖于标签来确定上下文和各个关键字的权重(SEO)。
  • 在没有 CSS 样式下,页面也能呈现出很好地内容结构、代码结构。

2. 从浏览器地址栏输入url回车会发生什么

  1. 输入 URL 后解析出协议、主机、端口、路径等信息,并构造一个 HTTP 请求。
  2. DNS 域名解析。
  3. TCP 连接。
  4. http 请求。
  5. 服务器处理请求并返回 HTTP 报文。
  6. 浏览器渲染页面
  7. 断开 TCP 连接。

3. 溢出的文字显示省略号

  • 单行

先强制一行显示`white-space:noweap
超出的部分隐藏`overflow:hidden 
超出的部分用省略号显示`text-overflow:ellipsis  

  • 多行

overflow:hidden;
text-overflow:ellipsis;
display: -webkit-box;弹性伸缩盒子模型显示
-webkit-line-clamp:2;//限制在一个块元素显示的文本行数
-webkit-box-orient:vertical;//设置或检索伸缩对象子元素排序

 

4. css选择器和优先级


大家都知道样式的优先级一般为 !important > style > id > class

 css选择器

选择器示例
|类型选择器 h1 {  } 
通配符选择器* {  }
类选择器.box {  }
ID选择器#unique { }
标签属性选择器a[title] {  }
伪类选择器p:first-child { }
伪类选择器p::first-line { }
后代选择器article p
子代选择器article > p
相邻兄弟选择器h1 + p
通用兄弟选择器选择器h1 ~ p


 5. BFC


   BFC 即块级格式上下文,这是一个独立渲染的区域,规定了内部如何布局,并且这个区域的子元素不会影响到外面的元素,其中比较重要的布局规则有内部box垂直放置,计算BFC高度的时候,浮动元素也参与计算。
BFC 具有一些特性:

  1.  块级元素会在垂直方向一个接一个的排列,和文档流的排列方式一致。
  2. 在 BFC 中上下相邻的两个容器的 `margin`  会重叠,创建新的 BFC 可以避免外边距重叠
  3. 计算 BFC 的高度时,需要计算浮动元素的高度,可以避免高度塌陷。
  4. BFC 区域不会与浮动的容器发生重叠。
  5.  每个元素的左 `margin`  值和容器的左 `border`  相接触。

创建 BFC 的方式:

  •  绝对定位元素(`position` 为 `absolute` 或 `fixed` )。
  • `display` 为 `inline-block; table-cell; table-caption; flex; inline-flex` 。
  •  `overflow` 的值不为 `visible` 。

6. 水平垂直居中的方法


1. 利用绝对定位,设置 `left: 50%`  和 `top: 50%`  现将子元素左上角移到父元素中心位置,然后再通过 `translate`  来调整子元素的中心点到父元素的中心。
2.  利用绝对定位,子元素所有方向都为 `0` ,将 `margin`  设置为 `auto` ,由于宽高固定,对应方向实现平分,该方法必须**盒子有宽高**。
3.  利用绝对定位,设置 `left: 50%` 和 `top: 50%` 现将子元素左上角移到父元素中心位置,然后再通过 `margin-left`  和 `margin-top`  以子元素自己的一半宽高进行负值赋值。该方法**必须定宽高**。


 二、JavaScript


1. 基本数据类型


在 JS 中共有 8 种基础的数据类型,分别为: `Undefined` 、 `Null` 、 `Boolean` 、 `Number` 、 `String` 、 `Object` 、 `Symbol`(ES6新增,表示独一无二的值,最大的用法是用来定义对象的唯一属性名。) 、 `BigInt`(表示任意大小的整数)。


1.1 值类型和引用型数据的理解

  • 值类型是直接存储在**栈**中的简单数据段,占据空间小、大小固定,属于被频繁使用数据,所以放入栈中存储;
  • 引用类型存储在**堆**中的对象,占据空间大、大小不固定。如果存储在栈中,将会影响程序运行的性能;


 1.2 数据类型的判断


 typeof:能判断所有值类型,函数。不可以对 null、对象、数组 进行精确判断,因为都返回 `object` 。

console.log(typeof undefined); // undefined
console.log(typeof 2); // number
console.log(typeof true); // boolean
console.log(typeof "str"); // string
console.log(typeof Symbol("foo")); // symbol
console.log(typeof 2172141653n); // bigint
console.log(typeof function () {}); // function
// 不能判别
console.log(typeof []); // object
console.log(typeof {}); // object
console.log(typeof null); // object


instanceof:能判断**对象**类型,不能判断基本数据类型,其内部运行机制是判断在其原型链中能否找到该类型的原型。
Object.prototype.toString.call():所有原始数据类型都是能判断的,还有 **Error 对象,Date 对象**等。

Object.prototype.toString.call(2); // "[object Number]"
Object.prototype.toString.call(""); // "[object String]"
Object.prototype.toString.call(true); // "[object Boolean]"
Object.prototype.toString.call(undefined); // "[object Undefined]"
Object.prototype.toString.call(null); // "[object Null]"
Object.prototype.toString.call(Math); // "[object Math]"
Object.prototype.toString.call({}); // "[object Object]"
Object.prototype.toString.call([]); // "[object Array]"
Object.prototype.toString.call(function () {}); // "[object Function]"


1.3 如何判断数组

Array.isArray(arr); // true
arr.__proto__ === Array.prototype; // true
arr instanceof Array; // true
Object.prototype.toString.call(arr); // "[object Array]"


2. 数组的使用

 数组API


 一、数组序列化

  1. toString() 在默认情况下都会以逗号分隔字符串的形式返回数组项
  2. join() 使用指定的字符串用来分隔数组字符串
var arr = [1,5,2,8,10,{a:1}];
console.log(arr);//[ 1, 5, 2, 8, 10, { a: 1 } ]
console.log(arr.toString());//”1,5,2,8,10,[object Object]”
console.log(arr.join(""));//”152810[object Object]”
console.log(arr.join("-"));//”1-5-2-8-10-[object Object]”


 二、栈和队列方法

  1. push() 方法可向数组的末尾添加一个或多个元素,并返回新的长度。
  2. pop() 方法用于删除数组的最后一个元素并返回删除的元素。
  3. shift() 方法用于把数组的第一个元素从其中删除,并返回第一个元素的值
  4. unshift() 方法可向数组的开头添加一个或更多元素,并返回新的长度。

三、排列方法

  1. reverse() 方法用于颠倒数组中元素的顺序。
  2. sort() 方法用于对数组的元素进行排序。


 

 // 1. 翻转数组
        var arr = ['pink', 'red', 'blue'];
        arr.reverse();
        console.log(arr);

        // 2. 数组排序(冒泡排序)
        var arr1 = [13, 4, 77, 1, 7];
        arr1.sort(function(a, b) {
            //  return a - b; 升序的顺序排列
            return b - a; // 降序的顺序排列
        });
        console.log(arr1);



 四、操作方法

  1.  concat() 方法用于连接两个或多个数组
  2.  substr()方法用于截取指定的一段字符
  3. slice() 方法可从已有的数组中返回选定的元素。
  4. splice() 方法用于添加或删除数组中的元素。

 var str = 'andy';
        console.log(str.concat('red'));//andyred

        // 2. substr('截取的起始位置', '截取几个字符');
        var str1 = '改革春风吹满地';
        console.log(str1.substr(2, 2)); // 春风


 五、位置方法

  1. indexOf() 方法可返回数组中某个指定的元素位置,找不到则返回-1。
  2. lastIndexOf() 方法可返回一个指定的元素在数组中最后出现的位置,从该字符串的后面向前查找。
var arr = ['red', 'green', 'pink'];
        console.log(arr.indexOf('blue'));//-1
        // 返回数组元素索引号方法  lastIndexOf(数组元素)  作用就是返回该数组元素的索引号 从后面开始查找
        var arr = ['red', 'green', 'blue', 'pink', 'blue'];
        console.log(arr.lastIndexOf('blue')); // 4


用indexOf()实现数组去重

 function unique(arr) {
            var newArr = [];
            for (var i = 0; i < arr.length; i++) {
                if (newArr.indexOf(arr[i]) === -1) {
                    newArr.push(arr[i]);
                }
            }
            return newArr;
        }
  
        var demo = unique(['blue', 'green', 'blue'])
        console.log(demo);


 六、迭代方法

  1. every() 方法用于检测数组所有元素是否都符合指定条件(通过函数提供)。
  2. some() 方法用于检测数组中的元素是否满足指定条件(函数提供)。
  3. filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。
  4. map() 方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。
  5. forEach() 方法用于调用数组的每个元素,并将元素传递给回调函数。

 2.1 利用函数求任意个数的最大值

function getMax() { 
            var max = arguments[0];
            for (var i = 1; i < arguments.length; i++) {
                if (arguments[i] > max) {
                    max = arguments[i];
                }
            }
            return max;
        }
        console.log(getMax(1, 2, 3));


2.2 利用函数翻转任意数组 reverse 翻转

 function reverse(arr) {
            var newArr = [];
            for (var i = arr.length - 1; i >= 0; i--) {
                newArr[newArr.length] = arr[i];
            }
            return newArr;
        }
        var arr1 = reverse([1, 3, 4, 6, 9]);
        console.log(arr1);
        var arr2 = reverse(['red', 'pink', 'blue']);
        console.log(arr2);


 2.3 利用函数冒泡排序 sort 排序

 function sort(arr) {
            for (var i = 0; i < arr.length - 1; i++) {
                for (var j = 0; j < arr.length - i - 1; j++) {
                    if (arr[j] > arr[j + 1]) {
                        var temp = arr[j];
                        arr[j] = arr[j + 1];
                        arr[j + 1] = temp;
                    }
                }
            }
            return arr;
        }
        var arr1 = sort([1, 4, 2, 9]);
        console.log(arr1);


2.4 利用函数判断闰年

function isRunYear(year) {
            // 如果是闰年我们返回 true  否则 返回 false 
            var flag = false;
            if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
                flag = true;
            }
            return flag;
        }
        console.log(isRunYear(2000));


 2.5 利用函数判断闰年

 function backDay() {
            var year = prompt('请您输入年份:');
            if (isRunYear(year)) { // 调用函数需要加小括号
                alert('当前年份是闰年2月份有29天');
            } else {
                alert('当前年份是平年2月份有28天');
            }
        }
        backDay();


        // 判断是否为闰年的函数
        function isRunYear(year) {
            // 如果是闰年我们返回 true  否则 返回 false 
            var flag = false;
            if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
                flag = true;
            }
            return flag;
        }


 2.6 利用set方法数组去重

function unique(arr){
    var arr2 = arr.sort();
    var res = [arr2[0]];
    for(var i=1;i<arr2.length;i++){
        if(arr2[i] !== res[res.length-1]){
        res.push(arr2[i]);
    }
}
return res;
}
//利用下标查询
 function unique(arr){
    var newArr = [arr[0]];
    for(var i=1;i<arr.length;i++){
        if(newArr.indexOf(arr[i]) == -1){
        newArr.push(arr[i]);
    }
}
return newArr;
}


 3. 作用域和作用域链


作用域 :就是代码名字(变量)在某个范围内起作用和效果 目的是为了提高程序的可靠性更重要的是减少命名冲突

  •  js的作用域(es6)之前 : 全局作用域   局部作用域 
  • 全局作用域: 整个script标签 或者是一个单独的js文件
  •  局部作用域(函数作用域) 在函数内部就是局部作用域 这个代码的名字只在函数内部起效果和作用

作用域链 : 内部函数访问外部函数的变量,采取的是链式查找的方式来决定取那个值 这种结构我们称为作用域链  **就近原则**
案例:

  // 案例1 : 结果是几?
        function f1() {
            var num = 123;

            function f2() {
                var num = 0;
                console.log(num); //num=0 站在目标出发,一层一层的往外查找
            }
            f2();
        }
        var num = 456;
        f1();
        // 案例2 :结果是几?
        var a = 1;

        function fn1() {
            var a = 2;
            var b = '22';
            fn2();

            function fn2() {
                var a = 3;
                fn3();

                function fn3() {
                    var a = 4;
                    console.log(a); //a=4
                    console.log(b); //b=22
                }
            }
        }
        fn1();


3.1 预解析


1. 我们js引擎运行js 分为**预解析、代码执行**
- 预解析 js引擎会把js 里面所有的 var  还有 function 提升到当前作用域的最前面
- 代码执行  按照代码书写的顺序从上往下执行
2. 预解析分为 变量预解析(变量提升) 和 函数预解析(函数提升)
- **变量提升**就是把所有的变量声明提升到当前的作用域最前面  不提升赋值操作
- **函数提升**就是把所有的函数声明提升到当前作用域的最前面  不调用函数
案例:

  var num = 10;
       fun();

        function fun() {
             console.log(num);
             var num = 20;
         }
        //  相当于执行了以下操作
        var num;

        function fun() {
             var num;
            console.log(num);
             num = 20;
         }
         num = 10;
         fun();
        // // 案例2
         var num = 10;

         function fn() {
            console.log(num);
             var num = 20;
             console.log(num);
         }
         fn();
        // // 相当于以下代码
         var num;

         function fn() {
             var num;
             console.log(num);
             num = 20;
             console.log(num);
         }
         num = 10;
         fn();
        // // 案例3
         var a = 18;
         f1();

         function f1() {
             var b = 9;
             console.log(a);
             console.log(b);
             var a = '123';
         }
        // 相当于以下代码
         var a;

         function f1() {
             var b;
             var a;
             b = 9;
             console.log(a);
             console.log(b);
             a = '123';
         }
         a = 18;
         f1();
        // 案例4
        f1();
        console.log(c);
        console.log(b);
        console.log(a);

        function f1() {
            var a = b = c = 9;
            console.log(a);
            console.log(b);
            console.log(c);
        }
        // 以下代码
         function f1() {
             var a;
             a = b = c = 9;
             // 相当于 var  a  = 9; b = 9; c = 9; b 和 c 直接赋值 没有var 声明 当 全局变量看
             // 集体声明  var a = 9, b = 9, c = 9;
             console.log(a);
             console.log(b);
             console.log(c);
         }
         f1();
         console.log(c);
         console.log(b);
         console.log(a);


 三、ES6新特性


 1. let和const关键字

区别:let表示声明变量,而const表示声明常量,两者都为块级作用域;const 声明的变量都会被认为是常量,意思就是它的值被设置完成后就不能再修改了。

需要注意:

-   let 关键词声明的变量不具备变量提升(hoisting)特性

-   let 和 const 声明只在最靠近的一个块中(花括号内)有效

-   当使用常量 const 声明时,请使用大写变量,如:CAPITAL_CASING

-   const 在声明时必须被赋值


2. 原型和原型链


一般情况下,我们的公共属性定义到构造函数里面, 公共的方法我们放到原型对象身上
 如果我们修改了原来的原型对象,给原型对象赋值的是一个对象,则必须手动的利用constructor指回原来的构造函数


3. 模板字符串


基本的字符串格式化。将表达式嵌入字符串中进行拼接。用${}来界定;ES6反引号 **` `` `** 直接搞定;

$("body").html(`This demonstrates the output of HTML content to the page, 
including student's ${name}, ${seatNumber}, ${sex} and so on.`);0


 4. 扩展运算符

  •  扩展运算符可以将数组拆分成以逗号分隔的参数序列
let ary = ["a", "b", "c"];
console.log(...ary)//a,b,c

  • 扩展运算符应用于数组合并

 let ary1 = [1, 2, 3];
    let ary2 = [4, 5, 6];
    let ary3 = [...ary1, ...ary2];
    console.log(ary3)// [1, 2, 3, 4, 5, 6]

//合并数组的第二种方法        
let ary1 = [1, 2, 3];
let ary2 = [4, 5, 6];
ary1.push(...ary2);
console.log(ary1)// [1, 2, 3, 4, 5, 6]

  • 利用扩展运算符将伪数组转换为真正的数组               
var oDivs = document.getElementsByTagName('div');
console.log(oDivs)
var ary = [...oDivs];
ary.push('a');
console.log(ary);


 5. 箭头函数

  1. 不需要 function 关键字来创建函数
  2.  省略 return 关键字
  3. 继承当前上下文的 this 关键字

6. 解构赋值


按照一定模式从数组或对象中提取值,然后对变量进行赋值(先提取,再赋值)

// 对象
const student = {
    name: 'Sam',
    age: 22,
    sex: '男'
}
// 数组
// const student = ['Sam', 22, '男'];

// ES5;
const name = student.name;
const age = student.age;
const sex = student.sex;
console.log(name + ' --- ' + age + ' --- ' + sex);

// ES6
const { name, age, sex } = student;
console.log(name + ' --- ' + age + ' --- ' + sex);


7. Symbol


唯一标识,symbol作为对象的属性名时不会被`for...in`,`for...of`,`Object.keys()`识别;可以改用`Reflect.ownkeys`方法.


8. Promise


是一部编程的解决方案,状态不受外界影响

const p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve()
}, 1000)
}).then(res => {})
.catch(err => {})
```
#### 9.Class类
```
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
}


其中:

1.  constructor方法是类的默认方法,通过new 命令生成对象时会调用该方法,如果声明类时没有定义constructor,会默认定义一个空的。
1.  生成实例时必须用new ,不用会报错
1.  不存在变里提升(选定义类,再new实例)
类的静态方法:

所有在类中定义的方法都会被实例继承,如果不想被继承,可以在定义时加上static。表示为静态方法。
 

class Foo {
static match() {}
}
Foo.match()
const f = new Foo()
f.match() // 报错

9.  类的实例属性

类的方法默认被实例继承,那么属性呢?也是继承的,写法如下:

class Foo {
myProp = 111;
...
}

 classr的继承 extends

class Point {}
class PointSon extends Point {
constructor(x, y, z) {
super(x, y)
this.z = z
}
}

其中:

1.  super等同于父类的constructor。
1.  子类必须在constructor中调用super, 也就是说用extends去继承一个类,就必须调用这个类(父类)的constructor。是因为子类没有自己的this对象,而是继承父类的this,然后对其进行加工
1.  如果了类没有写constructor,会默认生成一个,并包含了super(...args)

 10.  new关键字


 5.1 new关键字执行过程
        1. new 构造函数可以在内存中创建了一个空的对象 
        2. this 就会指向刚才创建的空对象
        3. 执行构造函数里面的代码 给这个空对象添加属性和方法
        4. 返回这个对象


后续更新中....

 类似资料: