我的冤种笔记


前言

记录一下,巩固巩固,朝不秃头的目标前进。


一、HTML部分

二、CSS部分

1.css选择器的权重

  • !important的权重是最高的,当属性后面加上了 !important,他的属性不会被其他属性修改
  • 行内样式,即HTML标签内定义的样式,权重值为1000
  • id选择器权重值为100
  • 类选择器、属性选择器(如:[data-value = 1])、伪类选择器(如::hover)权重值为10
  • 标签选择器、伪元素选择器(如:::after)权重值为1
  • 通配符*选择器为0

2.BFC

BFC全称(block formatting context)也叫块级格式化上下文,BFC简单老说就是一个独立的空间,这个空间内的元素按照一定的规则进行布局,而且空间内的元素与外界的元素互不影响。html标签就是一个最大的BFC。
BFC有一些规则

  • BFC里的盒子会在垂直方向上一个接一个的排列,盒子之间的距离由margin决定,且属于同一个BFC的两个相邻的盒子会发生margin合并。
  • BFC里的每个元素的margin-left/margin-right会与外部元素的border-left/border-right相接触(依布局方向决定),浮动元素也是如此。
  • BFC的元素不会与float的盒子重叠。
  • BFC里的元素与BFC外的元素是相互独立互不影响的。
  • 计算BFC元素高度使,其内部的浮动元素的高度也会加入计算。

如何创建BFC

  • 使用float使其浮动的元素
  • 设置了绝对定位的元素,包含(position: absolute/fixed/sticky)
  • 表格单元格,设置了display: table-cell,包括使用 display: table-* 属性的所有表格单元格
  • 表格标题,设置了display: table-caption的元素
  • 块级元素的overflow元素不为visible
  • 元素属性为 display: flow-root 或 display: flow-root list-item
  • 元素属性为 contain: layout, content或者strict
  • flex items 设置display: flex / inline-flex
  • 网格布局元素:设置display: grid
  • multicol多列布局:设置column-count或者column-width的元素
  • 元素属性设置为column-span: all

BFC的应用场景

  • 解决使用float导致父元素高度塌陷的问题
  • 解决相邻元素margin合并的问题
  • 解决由于设置浮动元素导致其他元素被覆盖的问题等等

三、JavaScript部分

1.原型、原型链

当我们创建一个非箭头函数,即构造函数时,js会自动为这个函数添加一个prototype属性指向一个对象,这个对象就是这个构造函数的原型对象,而这个原型对象默认会获得一个constructor属性,这个属性指向了我们创建的构造函数,当我们通过构造函数创建一个实例时,这个实例有一个隐藏的特性prototype指向我们的原型对象,我们可以通过访问实例的__proto__属性指向这个prototype特性,进而获得实例的原型对象。

而如果构造函数的原型对象是另一个类的实例,那么就说明了这个原型对象里面也有一个指针指向了另一个构造函数的原型对象,以此类推,当多个不同的实例对象被当作原型对象串联起来的话,就形成了原型链。

当访问实例对象的属性时,会先从当前实例对象中进行搜索,如果找到了属性就返回其属性值,如果找不到就会沿着原型链对原型对象里的属性进行查找,以此类推,直到找到该属性,或者到达原型链的顶部后如果还未找到就返回undefined。

2.this指向

this是JavaScript里的一个很重要的关键字,this可以让我们以更加便捷的方式来引用对象。this在全局作用域下指向的是window,一般我们很少在全局作用域中使用this,而是在函数中进行使用。在调用函数时,JavaScript默认会给this绑定一个对象,这个对象的值跟函数定义的位置没有关系,而跟调用的位置及方式有关。

this的绑定一般有默认绑定、隐式绑定和、显示绑定和new绑定。当函数被直接调用时可以理解为没有跟任何对象关联时,使用的就是默认绑定,而此时的this指向的是全局对象window。而当函数作为对象的某一个方法,之后对象通过调用这个方法执行了这个函数,此时函数里的this会使用隐式绑定,指向调用它的那个对象。而隐式绑定必须保证调用函数的对象里面包含了对该函数的引用,否则就会报错。而如果我们想在某个对象上强制调用又不想这个对象内部包含这个函数的引用,此时我们就可以使用函数的call,apply和bind方法来实现。这三个方法的作用都是为了把函数的this绑定到特定的对象上,但这三者还是有一定的区别。首先,这三个方法的第一个参数都是想要绑定的对象,但是call和apply方法会立即调用这个函数,并把函数中的this绑定到传入的第一个参数对象上,而bind方法会返回一个新的函数,此时新函数中的this指向的就是传入的那个对象。对于原始函数的传参问题,call方法第一个参数之后的参数会被当做实参传递给原始函数,apply方法的第二个参数要求是一个数组,数组内的元素会被当做实参传递给原始函数,而bind方法的话,可以通过给返回的新函数传入参数实现原始函数的传参,另外,bind方法也可以传多个参数,第一个参数之后的参数会被绑定到原始函数的参数上,之后调用返回的新函数时,只要传入未被绑定的参数就可以了。通过call,apply和bind方法改变函数的this值,我们可以称为显示绑定。而我们通过new关键字调用函数时,会执行一些列的操作,首先会先创建一个新的对象,然后将这个对象与构造函数的原型对象进行关联,之后将对象绑定到函数的this上,最后如果函数没有返回其他对象的话,就会返回这个新创建的对象。

另外ES6新增的箭头函数是不会绑定this值的,箭头函数中的this是根据上层作用域中的this来决定的,箭头函数中的this在定义该函数的时候就已经确定了。

3.Promise

promise是异步编程的一种解决方案,过去传统的异步编程方案主要有回调函数和事件监听处理,当需求复杂时很容易写出回调函数嵌套的代码,出现回调地狱的问题。回调地狱使得代码臃肿,可读性差,耦合度变高,而且代码的可维护性以及复用性会更差,且容易滋生 bug,而且只能在回调里处理异常。而promise的出现主要是为了解决回调函数嵌套带来的回调地域问题。使得编写的代码更易读。

我们可以通过new来实例化一个promise对象,promise对象有三个状态,pending(待定)、fulfill(兑现)、reject(拒绝),promise对象只能从pending状态转变为fulfill状态,或者从pending状态转变为reject状态,并且状态一旦改变,就永远不会改变。当我们new一个Promise对象时,可以给Promise构造函数传递一个函数类型的参数,该函数需要写成接受两个参数,一般我们给它们命名为resolve和reject。当我们调用Promise构造函数时,会同步调用我们传入的函数,并自动为resolve和reject参数传入对应的函数值,最后返回新创建的promise对象。这个promise对象由传入Promise构造函数的函数控制,我们可以在传入的函数中执行一些异步操作,如网络请求,或者也可以执行一些同步代码,之后通过不同的条件来选择调用resolve函数以解决或者兑现返回的promise对象或者调用reject函数以拒绝返回的promise对象。

每个promise对象都有一个实例方法then(),通过这个方法我们可以得到promise兑现后的结果或者拒绝的原因。then方法可以接收两个函数类型的参数,当promise得到兑现时,会把兑现的结果传给then的第一个参数的函数,而被拒绝时,也会把异常的结果传给第二个参数的函数。不过在开发中我们很少会给then传第二个参数,通常都是在期约链的末尾添加一个catch方法以此来捕获异常。所谓的期约链就是使用一连串的.then()方法来表达一连串的异步操作。之所以可以使用期约链,是因为每次使用then方法时,都会返回一个新的promise对象,这个对象只有在传给then方法函数执行完毕才会兑现。

Promise还有一些其他得方法,比如Promise.all()、Promise.race()、Promise.allSettled()、Promise.resolve()、Promise.reject()。

另外,ES2017新增的async/await关键字极大地简化了promise的使用,使我们的异步请求代码能像同步阻塞代码一样。await关键字只能在通过async声明的函数中才可以使用,通过async声明的函数会返回一个promise对象,如果函数正常返回,promise对象将解决为这个函数的返回值,如果函数内出现异常,promise对象将被该异常拒绝。

4.不借助第三个变量替换两个变量的值

// 1.利用公式进行
let a = 1;
let b = 2;
a = a + b;
b = a - b;
a = a - b;

// 2.利用^(按位异或)
a ^= b;
b ^= a;
a ^= b;

// 3. 利用对象
a = {
   a: b, b: a};
b = a.b;
a = b.a;

// 4. 利用数组
a = [a, b];
b = a[0];
a = a[1];

// 5.
a = [b, b = a][0];

// 6. 解构赋值
[a, b] = [b, a];

5.js作用域

作用域是在程序运行时代码中的某些特定部分中变量、函数和对象的可访问性。从使用方面来解释,作用域就是变量的使用范围,也就是在代码的哪些部分可以访问这个变量,哪些部分无法访问到这个变量,换句话说就是这个变量在程序的哪些区域可见。从存储上来解释的话,作用域本质上是一个对象, 作用域中的变量可以理解为是该对象的成员。

作用域又分为全局作用域和局部作用域。在web浏览器中全局作用域指的是window对象,而在node中全局作用域指的是global对象。在ES6之前,局部作用域只包含了函数作用域,即函数定义时{}括号里面的部分。而像if、switch语句,for、while循环,这些是不具有局部作用域的。在ES6之后有了 ‘块级作用域’,可以通过新增关键字let和const来实现。通过这两个关键字声明的变量或者常量只能在声明时所处的作用域里面才可以被访问,换句话说,在一对{}括号内通过let,const声明的变量或者常量,在{}括号之外是不可以访问到的。像if、switch、while循环语句,他们都可以通过在{}内使用let,const关键字,而使其具有块级作用域。另外,在for循环中,我们在()括号里面通过let、const声明变量和常量,它最终其实是以循环体作为其局部作用域的。

作用域最为重要的一点是安全。变量只能在特定的区域内才能被访问,外部环境不能访问内部环境的任何变量和函数,即可以向上搜索,但不可以向下搜索, 有了作用域我们就可以避免在程序其它位置意外对某个变量做出修改导致程序发生事故。
作用域能够减轻命名的压力。我们可以在不同的作用域内定义相同的变量名,并且这些变量名不会产生冲突。

6.ES6~ES13新特性

ES6

  • let/const关键字
  • 模板字符串
// 用法一
let name = 'zzw'
let info = `name: ${
     name}` 
console.log(info)  // "name: zzw"

// 用法二
function foo(...arg) {
   
	console.log(arg)
}
foo`Hello ${
     name}, how are you`  // [['Hello ', ', how are you'], 'zzw']
  • 函数默认参数
function sum(a = 20, b = 30) {
   
	console.log(a + b)
}
sum()  // 50
sum(1, 1) // 2

// 默认值和解构一次使用
// 写法一
function foo({
   name, age} = {
   name: 'zzw', age: 23}) {
   
	console.log(name, age)
}

// 写法二
function foo1({
   name = 'zzw', age = 23} = {
   }) {
   
	console.log(name, age)
}

foo()  // zzw 23
foo1()  // zzw 23
  • 函数剩余参数
function foo(a, b, ...arg) {
   
	console.log(a, b, arg)
}

foo('你', '好', '呀', '!!!')  // 你 好 ['呀', '!!!']

// 注:剩余参数必须放在最后面
  • 箭头函数
const foo = () => {
   
	console.log('hello')
}
  • 展开语法
// 函数中使用
function foo(a, b, c) {
   
	console.log(a, b, c)
}
const arr = [1, 2, 3, 4]
foo(...arr)  // 1 2 3

// 数组中使用
const arr2 = [5, 6, 7]
const arr3 = [...arr, ...arr2]  // [1, 2, 3, 4, 5, 6, 7]
  • 规范数值写法
const decimalism = 100  // 十进制
const binary = 0b100  // 二进制
const octonary = 0o100  // 八进制
const hexademical = 0x100  // 十六进制
  • Symbol
// Symbol基本用法
const s1 = Symbol('aaa')
const s2 = Symbol('aaa')
s1 === s2  // false

const obj = {
   }
obj[s1] = 'bbb'
obj[s2] = 'ccc'
console.log(obj)  // {Symbol(aaa): 'bbb', Symbol(aaa): 'ccc'}

const s3 = Symbol.for('ccc')
const s4 = Symbol.for(
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值