CSS
BFC
BFC(Block Formatting Context)
是 Web 页面中的一个渲染上下文,它是一个独立的布局环境,决定了内部块级元素如何布局,并且与外部元素相互隔离。BFC
主要影响布局、浮动、清除浮动和边距折叠等方面的表现,具体地:
1.块级盒子: BFC 中的元素都是块级盒子,即元素在垂直方向上一个接一个地放置,块级元素之间不会发生外部流的交叉。
2.外边距折叠: 在同一个 BFC 中,相邻块级盒子的垂直外边距会发生折叠,而不同 BFC 中的块级盒子不会折叠。
3.浮动: BFC 中的浮动元素不会影响到外部元素的布局,且不会被浮动元素覆盖。
4.清除浮动: BFC 可以包含浮动元素并阻止浮动元素溢出。
5.内部元素与外部元素相互隔离: BFC 内部的元素不受外部元素的影响,反之亦然。
BFC
的创建条件包括:
- 根元素(
html
)。 - 浮动元素(
float
不为none
)。 - 绝对定位元素(
position
取值为absolute
或fixed
)。 overflow
属性值不为visible
的块级元素。- 弹性盒子(
display: flex
或display: inline-flex
)。
选择器权重
有以下分类:
1.内联样式: <div style="color: red;">
,权重为 1000
2.ID 选择器: #myElement { color: blue; }
,权重为 100
3.类选择器: .myClass { color: green; }
,权重为 10
4.元素选择器: p { color: orange; }
,权重为 1
5.组合选择器: .myClass p { color: purple; }
,权重为 20(10 + 1)
6.!important
: 的权重是最高的,它会覆盖任何其他规则,包括内联样式
伪类和伪元素
伪类(Pseudo-class):
伪类用于选择处于特定状态 或者某种上下文中 的元素,一般使用冒号 :
来表示。
:hover
:选择鼠标悬停在其上的元素。:active
:选择被激活(例如,被点击)的元素。:focus
:选择获取焦点的元素:first-child
:选择父元素下的第一个子元素。:nth-child(n)
:选择父元素下的第 n 个子元素。
js
button:hover {
background-color: lightblue;
}
li:first-child {
font-weight: bold;
}
伪元素(Pseudo-element):
伪元素用于选择元素的特定部分 ,或者在元素的特定位置插入内容 ,一般使用 ::
来表示。
::before
:在元素内容之前插入内容。::after
:在元素内容之后插入内容。::first-line
:选择元素的第一行文本。::first-letter
:选择元素的第一个字母。
js
p::before {
content: "Note: ";
color: red;
}
h1::first-line {
font-size: 150%;
color: blue;
}
JS
箭头函数
箭头函数是 ECMAScript 6(ES6)
引入的一种新的函数声明语法,相比传统的函数声明有一些语法上的简洁和功能上的特性
- 简洁的语法: 箭头函数的语法更为简洁,尤其是在只有一行返回语句的情况下,可以省略花括号和
return
关键字
js
// 传统函数声明
function double(x) {
return x * 2;
}
// 箭头函数
const doubleArrow = x => x * 2;
- 没有自己的
this
: 箭头函数没有自己的this
,它会继承父级作用域的this
- 不适用于构造函数: 箭头函数不能用作构造函数,不能使用
new
关键字调用,也没有prototype
原型链
原型链是 JavaScript 中用于实现继承的一种机制,每个对象都有一个内部属性 __proto__
,它指向其构造函数的原型对象prototype
。
prototype
是 JavaScript 中函数的一个特殊属性,这个属性是一个对象,通常被用来定义一个构造函数的原型对象,其包含了共享给该构造函数实例的属性和方法。
js
function Person(name) {
this.name = name;
}
console.log(Person.prototype); // 输出 Person {}
__proto__
是每个对象都有的属性,用于连接对象与其构造函数的原型对象
js
const person = new Person('John');
console.log(person.__proto__ === Person.prototype); // 输出 true
当我们访问一个对象的属性时,如果对象本身没有这个属性,JavaScript 引擎就会沿着原型链(__proto__
)往上查找
js
Person.prototype.say = function(){
console.log('say!')
}
person.say(); // say!
总的来说,原型链是 JavaScript 实现继承的基础,prototype
是构造函数的原型对象,而 __proto__
是连接对象与其构造函数原型对象的指针。
闭包
当一个函数嵌套在另一个函数内部时,内部函数形成了一个闭包。内部函数可以访问外部函数的变量,甚至在外部函数执行完毕后,闭包仍然保持对这些变量的引用。
js
function counter() {
// 外部函数的变量
let count = 0;
return function() {
count++;
console.log(count);
};
}
let increment = counter();
increment(); // 输出 1
increment(); // 输出 2
注意: 闭包不会主动释放使用的变量,会占用内存,需要手动释放将闭包函数置为null(会使得原有的引用被断开,从而使得该对象成为垃圾回收的候选对象。)
js
increment = null; // 提醒垃圾回收器回收
防抖(Debounce)和节流(Throttle)使用闭包主要是为了维护一些状态信息,以便在函数执行期间持久化信息。
this指向
谁最终调用函数,this就指向谁
- 直接调用函数,
this
是window
obj.foo()
调用,this
是obj
- 对于
new
来说,this
会被永远绑定在new
的对象上 - 箭头函数中的
this
只取决 包裹箭头函数的第一个普通函数的this
。 - 对于
call
、apply
、bind
这些改变上下文的函数来说,this
指向取决于第一个参数。如果第一个参数为''
、null
、undefined
等,则this
指向window
;有参数则this
指向第一个参数
call
和 apply
的区别
call
和apply
的区别在于参数传递方式不一样- 第一个参数都是要指向的
this
对象,apply
的第二个参数是参数集合,call
的参数个数不确定 call
比apply
的性能要好一点,call
传入的参数正是我们需要的格式,apply
还需要做一次解耦
js
function greet(name) {
console.log(`Hello, ${name}!`);
}
const obj = { name: 'John' };
greet.call(obj, 'Alice'); // Hello, John!
greet.apply(obj, ['Alice']); // Hello, John!
bind 方法: bind
方法用于创建一个新函数,它的 this
值会被指定,并且其它参数作为新函数的参数供调用时使用。
js
function greet() {
console.log(`Hello, ${this.name}!`);
}
const obj = { name: 'John' };
const boundGreet = greet.bind(obj);
boundGreet(); // 输出 'Hello, John!'
工程化
Git的使用
git基础指令
javascript
rm -rf .git //删除项目记录
git init //初始化仓库
git add . //添加所有改动文件到暂存区
git commit -m "message" //将暂存区内容提交到当前分支
git status //仓库当前状态
git diff //查看修改内容
git log //修改记录,--pretty=oneline参数表示每条记录单行显示
git reset --soft HEAD^ //回退上一个提交,保留本地修改
git reflog //记录每次命令
git diff HEAD -- file //命令可以查看工作区和版本库里面最新版本的区别
git checkout -- file //丢弃工作区的修改
git reset HEAD <file> //撤销暂存区的修改
git rm <file> //用于删除文件
//远程仓库
git remote add origin <url> //绑定远程仓库,关联一个远程库时必须给远程库指定一个名字,origin是默认习惯命名
git push -u origin master //将当前分支master推送到远程,第一次推送添加-u参数,将本地master与远程master进行关联
git remote -v //查看远程仓库信息
git remote rm origin //删除本地仓库和远程仓库的关联
//分支管理
git branch dev //创建dev分区
git checkout dev //切换到dev分区
git checkout -b dev //创建(-b)并切换到dev分支
git switch -c dev //创建(-c)并切换到dev分支
git branch //查看当前分支
git merge dev //用于合并指定分支到当前分支
git branch -d dev //删除dev分支
git merge --no-ff -m "merge with no-ff" dev //合并分支时,加上--no-ff参数就可以用普通模式合并,合并后的历史有分支,能看出来曾经做过合并,还需要加上-m参数,把commit描述写进去
git stash //保存工作现场
git stash pop //恢复工作现场
git cherry-pick <commit> //复制提交操作到当前分支
git branch -D <name> //强行删除一个没有合并的分区
git checkout -b branch-name origin/branch-name //在本地创建和远程分支对应的分支
//标签管理
git tag <tagname> //新建一个标签
git tag -a <tagname> -m "message" //指定标签信息
git tag //查看所有标签
git push origin <tagname> //可以推送一个本地标签;
git push origin --tags //可以推送全部未推送过的本地标签;
git tag -d <tagname> //可以删除一个本地标签;
git push origin :refs/tags/<tagname> //可以删除一个远程标签。
git代码提交流程
javascript
// 正常操作 [第一步]
git add . // 代码添加暂存区
git commit -am "xxx" // commit
git pull --rebase // 拉取最新代码
git push origin HEAD:refs/for/${目标分支} // gerrit提交方式
// 拉取远程代码可能出现冲突 [第二步]
git add .
git stash // 暂存本地更改
git pull
git stash pop // 拉出本地,解决冲突
git commit -am "xxx"
git push origin HEAD:refs/for/xx
// 提交上去后,你觉得[代码有问题]或者[检视意见修改]需要修改 [第三步]
git add .
git commit --amend // 按esc,输入":q"
git push origin HEAD:refs/for/xx
// 提交上去后,代码有冲突,
先在gerrit上面把代码提交abandon掉
git reset --soft HEAD^
执行第二步
// 切换分支
git checkout -b feature-B16-cart origin/feature-B16-cart
如何将某一个分支的部分代码合并到另外一个分支上面
git log 在A分支上通过git log 查看日志;将自己提交的该功能对应的hash值整理出来;
git checkout --track origin/B 如果本地没有B分支,需要先将B分支从远程仓库拉到本地仓库(如果本地有B分支,并且已与远程对应的B分支已关联;无需这一步,直接到下一步)
git checkout B 切换到B分支
git cherry-pick b5dc0dd 在B分支上操作:通过git cherry-pick <commit对应的hash值>将当前hash对应提交的代码合并到B分支上去
注意 每一次合并都可能会产生冲突,如果产生冲突,先解决冲突,然后将代码commit到本地仓库即可;测试无误之后,再将合并后的代码push到远程仓库。切记!
javascript
// 单个commit合并
git cherry-pick commitid
// 多个分开的commit一起合并
git cherry-pick commit-id1 commit-id3 commit-id6
// 多个连续的commit合并
git cherry-pick commitid1..commitid8 // 将commitid1到commitid8之间的所有提交合并到B分支上(不包含第一个commitid)