前端知识之查漏补缺-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
 
 
  
  
 

 

 

原文地址:https://www.cnblogs.com/tllw/p/15309659.html