• 前端知识之查漏补缺-1


    一、html语义化

      优点:

        1、易修改、易维护

        2、无障碍阅读

        3、搜索引擎友好,易于SEO

        4、面向未来的HTML、以后可能有更多的支持

      标签

        header: 标注内容的标题、标注网页的页眉

        nav:导航栏、一组文章的链接

        main:主要内容

        footer: 可以包含版权、来源信息、法律限制等等之类的文本或链接信息

        aside:侧边栏、与内容无关联的附注解释某个观点或者其他的内容链接

        section:  与页面主体并列显示的小内容块;独立性内容,清单、表单等;分组内容,如 CMS 系统中的文章分类区块;比较长文档的一部分,可能仅仅是为了正确规定页面大纲

        article: 表示一个完整的、自成一体的内容块

        figure: 插图

        figcaption: 包含了关于插图的详细解释 

    二、CSS选择器

       类型:id选择器、类选择器(class)、标签选择器(div)、相邻选择器(a+b)、父子选择器(a>b)、后代选择器(a b)、通配符选择器(*)、属性选择器(a[rel="external"])、伪类选择器(a:hover, li:nth-child)伪元素选择器(::before)

       权重:!important > 行内样式>ID选择器 > 类选择器 = 属性选择器 = 伪类选择器 > 标签 = 伪元素选择器 > 通配符 > 继承 > 浏览器默认属性同一级别

    三、BFC

      格式化上下文

        浮动元素和绝对定位元素,非块级盒子的块级容器(例如inline-blocks,table-cells,和table-captions),以及overflow值不为”visiable”的块级盒子,都会为他们的内容创建新的BFC(Block Fromatting Context,即块级格式上下文)

      渲染规则

        (1)BFC垂直方向边距重叠

        (2)BFC的区域不会与浮动元素的box重叠

        (3)BFC是一个独立的容器,外面的元素不会影响里面的元素

        (4)计算BFC高度的时候浮动元素也会参与计算

      解决问题

        父元素塌陷、下边距重合等用创建BFC解决例如父元素加overflow hidden

      宽度高度未知的水平垂直居中

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
        <style>
          /* 第一种 */
          /* .box {
            display: flex;
            display: -webkit-flex;
            border: 1px solid #0000ff;
            height: 400px;
             400px;
            align-items: center;
            justify-content: center;
          } */
          /* 第二种 */
          /* .box {
            display: flex;
            display: -webkit-flex;
            border: 1px solid #0000ff;
            height: 400px;
             400px;
          }
          .item {
            margin: auto;
          } */
          /* 第三种 */
          /* .box {
            position: relative;
            border: 1px solid #0000ff;
            height: 400px;
             400px;
          }
          .item {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
          } */
          /* 第四种 */
          /* .box {
            border: 1px solid #0000ff;
            height: 400px;
             400px;
            display: table-cell;
            text-align: center;
            vertical-align: middle;
          } */
          /* 第五种 */
          /* .box {
            border: 1px solid #0000ff;
            height: 400px;
             400px;
            display: grid;
          }
          .item {
            align-self: center;
            justify-self: center;
          } */
          /* 第六种 */
          .box {
            border: 1px solid #0000ff;
            height: 400px;
            width: 400px;
            text-align: center;
            font-size: 0;
          }
          .box::before {
            content: '';
            display: inline-block;
            vertical-align: middle;
            height: 100%;
          }
          .item {
            vertical-align: middle;
            display: inline-block;
            font-size: 16px;
          }
        </style>
      </head>
      <body>
        <div class="box">
          <div class="item">horizontal and vertical</div>
        </div>
      </body>
    </html>

    三、数据类型

      8种:Boolean、Undefined、Number、BigInt、String、Symbol、Null、Object

      BigInt :Number是-9007199254740991 -(2^53-1) 至9007199254740991(2^53-1)之间的双精度64位浮点数,如果超出就会出现失去精度的问题,例如9007199254740992 === 9007199254740993返回true,可以使用9007199254740992n

      Symbol:一种新的原始数据类型 Symbol ,表示独一无二的值,最大的用法是用来定义对象的唯一属性名,因为 Symbol 是原始数据类型,不是对象。可以接受一个字符串作为参数,为新创建的 Symbol 提供描述,用来显示在控制台或者作为字符串的时候使用,便于区分。

    let sy = Symbol("KK");
    console.log(sy);   // Symbol(KK)
    typeof(sy);        // "symbol"
     
    // 相同参数 Symbol() 返回的值不相等
    let sy1 = Symbol("KK"); 
    sy === sy1;       // false

    由于每一个 Symbol 的值都是不相等的,所以 Symbol 作为对象的属性名,可以保证属性不重名。

    let sy = Symbol("key1");
    // 写法1
    let syObject = {};
    syObject[sy] = "kk";
    console.log(syObject);    // {Symbol(key1): "kk"}
    // 写法2
    Symbol 作为对象属性名时不能用.运算符,要用方括号。因为.运算符后面是字符串,所以取到的是字符串 sy 属性,而不是 Symbol 值 sy 属性
    let syObject = {
      [sy]: "kk"
    };
    console.log(syObject);    // {Symbol(key1): "kk"}
    // 写法3
    let syObject = {};
    Object.defineProperty(syObject, sy, {value: "kk"});
    console.log(syObject);   // {Symbol(key1): "kk"}

    Symbol 值作为属性名时,该属性是公有属性不是私有属性,可以在类的外部访问。但是不会出现在 for...in 、 for...of 的循环中,也不会被 Object.keys() 、 Object.getOwnPropertyNames() 返回。如果要读取到一个对象的 Symbol 属性,可以通过 Object.getOwnPropertySymbols() 和 Reflect.ownKeys() 取到。

    let syObject = {};
    syObject[sy] = "kk";
    console.log(syObject);
     
    for (let i in syObject) {
      console.log(i);
    }    // 无输出
     
    Object.keys(syObject);                     // []
    Object.getOwnPropertySymbols(syObject);    // [Symbol(key1)]
    Reflect.ownKeys(syObject);                 // [Symbol(key1)]

    使用 Symbol 定义常量,可以保证常量的唯一

    const COLOR_RED = Symbol("red");

    const COLOR_YELLOW = Symbol("yellow");

    Symbol.for() 类似单例模式,首先会在全局搜索被登记的 Symbol 中是否有该字符串参数作为名称的 Symbol 值,如果有即返回该 Symbol 值,若没有则新建并返回一个以该字符串参数为名称的 Symbol 值,并登记在全局环境中供搜索。

    Symbol.keyFor() 返回一个已登记的 Symbol 类型值的 key ,用来检测该字符串参数作为名称的 Symbol 值是否已被登记。

    let yellow = Symbol("Yellow");
    let yellow1 = Symbol.for("Yellow");
    yellow === yellow1;      // false
     
    let yellow2 = Symbol.for("Yellow");
    yellow1 === yellow2;     // true
    Symbol.keyFor(yellow1);    // "Yellow"

    四、事件模型

      捕获阶段、目标阶段、冒泡阶段

      目标阶段执行事件发生在捕捉之后,是冒泡之前还是之后和执行事件函数的绑定位置有关

    <!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="s1" style=" 500px; height: 500px; display: flex; align-items: center; justify-content: center; background-color: aquamarine">
                父集
                <div id="s2" style=" 200px; height: 200px; background-color: gold">子集</div>
            </div>
            <script>
                s1.addEventListener('click', e => printHandle(e, '父集 冒泡事件'), false);
                s1.addEventListener('click', e => printHandle(e, '父集 捕获事件'), true);
                s2.addEventListener('click', e => printHandle(e, '子集 冒泡事件1'), false);
                s2.onclick = () => console.log('执行事件');
                s2.addEventListener('click', e => printHandle(e, '子集 捕获事件'), true);
                s2.addEventListener('click', e => printHandle(e, '子集 冒泡事件2'), false);
                const printHandle = (e, text) => {
                    // 阻止事件冒泡
                    // if (e.stopPropagation) {
                    //     e.stopPropagation();
                    // } else {
                    //     e.cancelBubble();
                    // }
                    console.log(text);
                };
            </script>
        </body>
    </html>

     五、ES6 let 和const

      let 不可重复声明定义,var可以

      const 声明时必须赋值,且值不可更改

      let 和const 不会变量提升

      var 会变量提升

      for 循环中使用let 可保证值的改变,let 有块作用域

    for (var i = 0; i < 10; i++) {
      setTimeout(function(){
        console.log(i);
      })
    }
    // 输出十个 10
    for (let j = 0; j < 10; j++) {
      setTimeout(function(){
        console.log(j);
      })
    }
    // 输出 0123456789

    变量 i 是用 var 声明的,在全局范围内有效,所以全局中只有一个变量 i, 每次循环时,setTimeout 定时器里面的 i 指的是全局变量 i ,而循环里的十个 setTimeout 是在循环结束后才执行,所以此时的 i 都是 10。

    变量 j 是用 let 声明的,当前的 j 只在本轮循环中有效,每次循环的 j 其实都是一个新的变量,所以 setTimeout 定时器里面的 j 其实是不同的变量,即最后输出 12345。(若每次循环的变量 j 都是重新声明的,如何知道前一个循环的值?这是因为 JavaScript 引擎内部会记住前一个循环的值)。

    六、ES6 Map Set

    Map

      Map 对象保存键值对。任何值(对象或者原始值) 都可以作为一个键或一个值。

      与Object的差别

      1. Object只能用字符串或者symbol作为key值,Map无限制

      2.Map中的键值是有序的(FIFO 原则),而添加到对象中的键则不是

      3.Map的键值对个数可以从 size 属性获取,而 Object 的键值对个数只能手动计算

    var myMap = new Map();
    var keyString = "a string"; 
     
    myMap.set(keyString, "和键'a string'关联的值");
     
    myMap.get(keyString);    // "和键'a string'关联的值"
    myMap.get("a string");   // "和键'a string'关联的值"
                             // 因为 keyString === 'a string'
    var myMap = new Map();
    var keyObj = {}, 
     
    myMap.set(keyObj, "和键 keyObj 关联的值");
    
    myMap.get(keyObj); // "和键 keyObj 关联的值"
    myMap.get({}); // undefined, 因为 keyObj !== {}
    var myMap = new Map();
    var keyFunc = function () {}, // 函数
     
    myMap.set(keyFunc, "和键 keyFunc 关联的值");
     
    myMap.get(keyFunc); // "和键 keyFunc 关联的值"
    myMap.get(function() {}) // undefined, 因为 keyFunc !== function () {}
    var myMap = new Map();
    myMap.set(NaN, "not a number");
     
    myMap.get(NaN); // "not a number"
     
    var otherNaN = Number("foo");
    myMap.get(otherNaN); // "not a number"

      虽然 NaN 和任何值甚至和自己都不相等(NaN !== NaN 返回true),NaN作为Map的键来说是没有区别的。 

      for of 

    var myMap = new Map();
    myMap.set(0, "zero");
    myMap.set(1, "one");
     
    // 将会显示两个 log。 一个是 "0 = zero" 另一个是 "1 = one"
    for (var [key, value] of myMap) {
      console.log(key + " = " + value);
    }
    for (var [key, value] of myMap.entries()) {
      console.log(key + " = " + value);
    }
    /* 这个 entries 方法返回一个新的 Iterator 对象,它按插入顺序包含了 Map 对象中每个元素的 [key, value] 数组。 */
     
    // 将会显示两个log。 一个是 "0" 另一个是 "1"
    for (var key of myMap.keys()) {
      console.log(key);
    }
    /* 这个 keys 方法返回一个新的 Iterator 对象, 它按插入顺序包含了 Map 对象中每个元素的键。 */
     
    // 将会显示两个log。 一个是 "zero" 另一个是 "one"
    for (var value of myMap.values()) {
      console.log(value);
    }
    /* 这个 values 方法返回一个新的 Iterator 对象,它按插入顺序包含了 Map 对象中每个元素的值。 */

      forEach

    var myMap = new Map();
    myMap.set(0, "zero");
    myMap.set(1, "one");
    // 将会显示两个 logs。 一个是 "0 = zero" 另一个是 "1 = one"
    myMap.forEach((value, key) => console.log(key + " = " + value))

      Map与二维数组之间的转换

        Aarry.form(map) 解构[...map] 和 new Map(arr)

      Map的克隆

        new Map(map)

      Map的合并

        new Map([...mapA, ...mapB])

    Set

      Set 对象允许你存储任何类型的唯一值,无论是原始值或者是对象引用。

    let mySet = new Set();
     
    mySet.add(1); // Set(1) {1}
    mySet.add(5); // Set(2) {1, 5}
    mySet.add(5); // Set(2) {1, 5} 这里体现了值的唯一性
    mySet.add("some text"); 
    // Set(3) {1, 5, "some text"} 这里体现了类型的多样性
    var o = {a: 1, b: 2}; 
    mySet.add(o);
    mySet.add({a: 1, b: 2}); 
    // Set(5) {1, 5, "some text", {…}, {…}} 
    // 这里体现了对象之间引用不同不恒等,即使值相同,Set 也能存储// Array 转 Set
    var mySet = new Set(["value1", "value2", "value3"]);
    // 用...操作符,将 Set 转 Array
    var myArray = [...mySet];
    String
    // String 转 Set
    var mySet = new Set('hello');  // Set(4) {"h", "e", "l", "o"}
    // 注:Set 中 toString 方法是不能将 Set 转换成 String

      可以用作数组去重等

      var mySet = new Set([1, 2, 3, 4, 4]); [...mySet]; // [1, 2, 3, 4]

    七、其他ES6补充

    // includes、startsWith、endsWith、repeat、padStart、padEnd
    let string = 'apple,banana,orange';
    string.includes('banana'); // true
    string.startsWith('apple'); // true
    string.endsWith('apple'); // false
    string.startsWith('banana', 6); // true
    console.log('Hello,'.repeat(2)); // "Hello,Hello,"
    console.log('h'.padStart(5, 'o')); // "ooooh"
    console.log('h'.padEnd(5, 'o')); // "hoooo"
    console.log('h'.padStart(5)); // "    h"

    indexOf lastIndexOf 查找数组或字符串中某个对象出现的位置和最后位置

    数值的指数运算 2**3 = 8

    八、JS中的this

                // 1.全局对象中的this
                {
                    const obj = {
                        a: {
                            b: {
                                c: this
                            }
                        }
                    };
                    console.log('全局对象中的this, window', obj.a.b.c == window);
                }
                // 2.全局函数中的this
                {
                    function fun() {
                        function fun1() {
                            console.log('全局函数中的this, window', this === window);
                        }
                        fun1();
                    }
                    fun();
                }
                // 3.全局对象中函数的this
                {
                    const obj = {
                        fun() {
                            console.log('全局对象中函数的this, obj', this === obj);
                        }
                    };
                    obj.fun();
                }
                // 4.全局函数中的对象的this
                {
                    function fun() {
                        const obj = {
                            a: 1,
                            c: this
                        };
                        console.log('全局函数中的对象的this, window', obj.c === window);
                    }
                    fun();
                }
                // 5.全局对象中调用函数中调用函数的this
                {
                    const obj = {
                        fun() {
                            function fun1() {
                                function fun2() {
                                    console.log('全局对象中调用函数中调用函数的this, window', this === window);
                                }
                                fun2();
                            }
                            fun1();
                        }
                    };
                    obj.fun();
                }
                // 6.关键是执行时的this指向
                {
                    const obj = {
                        objIn: {
                            obj: 'objIn',
                            fun() {
                                return this;
                            }
                        }
                    };
                    console.log('关键是执行时的this指向, objIn', obj.objIn.fun() === obj.objIn);
                    const fun = obj.objIn.fun;
                    console.log('关键是执行时的this指向, window', fun() === window);
                }
                // window.obj.obj.obj(this) => window 全局声明的对象下的属性this指向全局对象
                // window.fun(fun(this)) => window 函数的this指向调用函数的对象,  fun1() 调用对象是window
                // window.obj fun(this) => obj 函数的this指向调用函数的对象, obj.fun() 调用对象是obj
                // window.fun(obj(this))  => window 函数调用 fun() this指向window, window下声明的obj中属性this指向window
                // window.obj.fun() =>window 全局声明的对象下的函数this指向全局对象
                // window.obj.objIn.fun(this) => 函数的this指向调用函数的对象, objIn.fun() objIn

      1.JavaScript的this是在调用阶段进行绑定

      2.严格模式下this是指向undefined,在非严格版中this指向undefined时默认自动指向全局对象(浏览器中就是window)

      3.函数的this指向执行函数的对象

      4.对象中的this执行声明对象的所在对象

      5.new操作符会改变函数this的指向 

    function Fun() {
      //new做的事情
      const obj = {};
      obj.__proto__ = Fun.prototype;
      //Base为构造函数
      //一系列赋值以及更多的事 obj.name = 'Daming' ...
      return obj;
    }
           a.创建一个临时对象
         b.给临时对象绑定原型
         c.给临时对象对应属性赋值
         d.将临时对象return
      6.call 、applay、bind会改变普通函数(箭头函数不可更改)this的指向
      7.箭头函数会捕获其所在上下文的 this 值,作为自己的 this 值
      
                {
                    const obj = {};
                    const fun = () => console.log('=>', this === window ? 'window' : 'obj');
                    const fun1 = function () {
                        console.log('()', this === window ? 'window' : 'obj');
                    };
                    fun();
                    fun.call(obj);
                    fun1();
                    fun1.call(obj);
                }
                console.log('---------我是分割线--------');
                {
                    const obj = {};
                    function fun() {
                        let f = () => console.log('=>', this === window ? 'window' : 'obj');
                        f();
                    }
                    function fun1() {
                        let f = function () {
                            console.log('()', this === window ? 'window' : 'obj');
                        };
                        f();
                    }
                    fun();
                    fun.call(obj);
                    fun1();
                    fun1.call(obj);
                }
                console.log('---------我是分割线--------');
                {
                    function Fun() {
                        this.name = 'Damonare';
                    }
                    Fun.prototype.say = () => {
                        console.log('=>', this === window ? 'window' : 'obj');
                    };
                    function Fun1() {
                        this.name = 'Damonare';
                    }
                    Fun1.prototype.say = function () {
                        console.log('()', this === window ? 'window' : 'obj');
                    };
                    const f = new Fun();
                    f.say();
                    const f1 = new Fun1();
                    f1.say();
                }
                console.log('---------我是分割线--------');
                {
                    function Fun() {
                        this.name = 'Damonare';
                        this.say = () => {
                            console.log('=>', this === window ? 'window' : 'obj');
                        };
                    }
                    function Fun1() {
                        this.name = 'Damonare';
                        this.say = function () {
                            console.log('()', this === window ? 'window' : 'obj');
                        };
                    }
                    const f = new Fun();
                    f.say();
                    const f1 = new Fun1();
                    f1.say();
                }

     九、变量提升问题

    var a = 1;
                    function fn() {
                        if (!a) {
                            var a = 123;
                        }
                        console.log(a);
                    }
                    fn();
                    // -----------------------
                    var a;
                    function fn() {
                        if (!a) {
                            var a = 123;
                        }
                        console.log(a);
                    }
                    a = 1;
                    fn(); // 123
    function Foo() {
                    getName = function () {
                        console.log('1');
                      };
                      return this;
                    }
                    Foo.getName = function () {
                        console.log('2');
                    };
    
                    Foo.prototype.getName = function () {
                        console.log('3');
                    };
    
                    var getName = function () {
                        console.log('4');
                    };
                    function getName() {
                        console.log('5');
                    }
                    Foo.getName();
                    getName();
                    Foo().getName();
                    getName();
                    new Foo.getName();
                    new Foo().getName();
                    //  -----------
                    // 变量提升转换
                    function Foo() {
                        getName = function () {
                            console.log('1');
                        };
                        return this;
                    }
                    function getName() {
                        console.log('5');
                    }
                    var getName;
                    Foo.getName = function () {
                        console.log('2');
                    };
                    Foo.prototype.getName = function () {
                        console.log('3');
                    };
                    getName = function () {
                        console.log('4');
                    };
                    // 执行
            Foo.getName(); // 2
            getName(); // 4
            Foo().getName(); // 1
            getName(); // 1
            new Foo.getName(); // 2
            new Foo().getName(); // 3
     
     
      
      
     

     

     

  • 相关阅读:
    Android音频(7)——项目实战——耳麦插拔
    Android音频(6)——音频系统分析
    Android音频(5)——框架中的概念和涉及的文件
    Android音频(4)——音频驱动实战
    Android音频(3)——ALSA声卡驱动——DAPM
    Android音频(2)——ALSA声卡驱动——ASoC
    Mvc中Session导致action不异步的问题
    RabbitMQ 声明Queue时的参数们的Power
    RabbitMQ 实现RPC
    RabbitMQ Topic exchange
  • 原文地址:https://www.cnblogs.com/tllw/p/15309659.html
Copyright © 2020-2023  润新知