GitHub、Gitee 同步更新
GitHub:
web_basic-knowledge-study
Gitee:
Web_basicKnowledgeStudy
- git 和 svn 最大的区别在于 git 是分布式的,而 svn 是集中式的。因此我们不能再离线的情况下使用 svn。
如果服务器出现问题,我们就没有办法使用 svn 来提交我们的代码
- svn 中的分支是整个版本库的复制的一份完整目录,而 git 的分支是指针指向某次提交,因此
git 的分支创建更加开销更小
并且分支上的变化不会影响到其他人。svn 的分支变化会影响到svn
相对于 git 来说要简单
一些,比 git 更容易上手- git 和 svn 对比 - 掘金
- git 学习小计 - 分支原理
git init // 新建 git 代码库
git add // 添加指定文件到暂存区
git rm // 删除工作区文件,并且将这次删除放入暂存区
git commit -m [message] // 提交暂存区到仓库区
git branch // 列出所有分支
git checkout -b [branch] // 新建一个分支,并切换到该分支
git status // 显示有变更的文件
常见 git 命令清单
从远程仓库更新到本地仓库
)
- git fetch 只是将远程仓库的变化下载下来,并没有和本地分支合并。
- git pull 会将远程仓库的变化下载下来,并和当前分支合并
git pull = git fetch + git merge
- 详解git pull 和 git fetch 的区别
- git merge 和 git rebase 都是用于分支合并,关键在 commit 记录的处理上不同。
- git merge 会新建一个
新的 commit 对象
,然后两个分支以前的 commit 记录都指向这个新 commit记录。这种方法会保留之前每个分支的 commit 历史。
- git rebase 会先找到两个分支的第一个共同的 commit 祖先记录,然后将提取当前分支这之后的所有commit 记录,然后将这个 commit 记录添加到目标分支的最新提交后面。经过这个合并后,两个分支合并后的
commit 记录就变为了线性的记录了(线性树--对两个分支的历史有破坏)
- 《git merge 与 git rebase 的区别》
(最后更新于 day-1
,2021/2/6
)
DOCTYPE
的作用是什么?声明位于 HTML 文档中的第一行,处于
标签之前。
**作用:**告知浏览器以什么文档标准
解析这个文档。
DOCTYPE
不存在或格式不正确会导致文档以兼容模式
呈现。
一般指定了之后会以标准模式来进行文档解析,否则就以兼容模式进行解析。在标准模式下,浏览器的解析规则都是按照最新的标准进行解析的。而在兼容模式下,浏览器会以向后兼容的方式来模拟老式浏览器的行为,以保证一些老的网站的正确访问。
HTML5 之后不再需要指定DTD文档:
因为HTML5之前的文档都是基于SGML的,因此需要指定DTD来定义文档中允许的属性和一些规则。
由于HTML5不再基于SGML,因此不再需要使用DTD
**标准模式:**渲染模式和 JS引擎的解析方式都是以该浏览器所能支持的最高标准
运行。
**兼容模式:**页面以宽松的向后兼容
的方式显示,模拟老式浏览器的行为,防止站点无法工作。
,而不需要引入 DTD?HTML5不再基于SGML,因此不需要指定DTD
HTML5之前的文档都是基于SGML,需要指定DTD来定义相应的规则和属性
SGML:标准通用标记语言,是一种定义电子文档和描述其内容的国际标准语言,是所有电子文档标记语言的起源。
HTML:超文本标记语言,规定怎么显示网页。
XML:可扩展标记语言,XML标签可自建,无限多;HTML标签固定且数量有限。
XHTML:基本所有网页都在使用的标记语言,和HTML没有本质区别,标签,数量都一样,主要是比HTML更严格了
eg:标签规定必须小写,标签都必须由闭合标签等等。
DTD( Document Type Definition )文档类型定义
是一组机械可读的规则,定义了XML 或 HTML的特定版本中的
所有允许元素、规则和属性
在进行网页解析时,浏览器使用这些规则,
检查页面的有效性并采取相应的措施
DTD是对HTML文档的声明,还会
影响浏览器的渲染模式。
常见行内元素:a b span img strong sub sup button input label select textarea
常见的块级元素有 div ul ol li dl dt dd h1 h2 h3 h4 h5 h6 p
**主要区别:**体现在
盒模型
上。设置width和height无效,设置magin 和padding的上下不会对其他元素产生影响行内元素不会换行,块级元素会另起一行
行内元素只能包含文本和其他行内元素,但是块级元素可以包含块其他级元素和行内元素
在HTML4中,元素被分为 inline 和 block两大类,但是在实际应用中,我们经常需要用display转换,更是出现了inline-block对外显示inline 对内显示block的属性,inline和block已不再符合实际需求
HTML5的元素分类(7类):Metadata Flow Sectioning Heading Phrasing Embedded Interactive
标签中没有内容的HTML标签
被称为空元素
,空元素在开始标签中关闭。
常见的空元素 :br(换行) hr(分隔线) img link meta input
link 标签定义文档与外部资源的关系
link 元素是空元素,仅包含属性,存在于head ,可以出现无限次
link 标签中的rel
定义了当前文档与链接文档之前的关系,例如常见的stylesheet
指的就是一个外部加载的样式文件
4个主要的区别
从属关系区别:@import是css提供的语法,只可导入样式表,但是link不仅导入css样式表,还可以定义rss,rel 连接属性、引入网站图标等。
加载顺序区别:link引入的css在页面加载时同时加载,但是@import引入的css在页面加载完后加载
兼容性区别:@import 是css2.1的语法,在IE5+才可以使用,而link是HTML的元素,不存在兼容性问题
DOM可控性区别:link可以通过JS操作DOM插入link标签修改样式,但是@improt是css的语法,无法通过DOM操作。
DOM是基于文档的。
(最后更新于 day-2
,2021/2/7
)
js 一共有六种基本数据类型,
5种简单类型分别是 Undefined、Null、Boolean、Number、String (巧记 undefined / null,NSB)
1种复杂数据类型 object(对象)
ES6
新增的 symbol 类型:Symbol 代表创建后独一无二且不可变的数据类型,它的出现我认为主要是为了解决可能出现的全局变量冲突 的问题。
ES10
新增的BigInt 类型:BigInt 是一种数字类型的数据,它可以表示任意精度格式的整数,使用 BigInt 可以安全地存储和操作大 整数,即使这个数已经超出了
Number
能够表示的安全整数范围。
(最后更新于 day-2
,2021/2/7
)
**原始值 **即一些代表原始数据类型的值,也叫基本数据类型,首先说一下js中有哪些原始值,Number,String,Boolean,Null,Undefined这些基本数据类型都是原始值。
原始值存储在栈中。
var a = 10 ;
var b = a ;
a = 20;
console.log(b); //输出10 b的值不会因a的值的改变而该改变
引用值 是指一些复合类型数据的值,包括Object,function,Array,RegExp,Data,引用值于原始值不同。
引用值由指针(引用变量)指向对象,指针放在栈中,但是对象在堆内存里。
var a = [1,2,3] ;
var b = a ;
a.push(4) ;
console.log(b) ; //输出1,2,3,4
a = [12] ;
console.log(b) ; //输出1,2,3,4
console.log(a) ; //输出12
上例中a指向[12],指向了新的堆空间。
typeof 、 instanceof 、 Object.prototype.toString.call() 、constructor(构造函数)
**1.typeof **
返回值包括number、boolean、string、symbol、object、undefined、function等7种数据类型
但不能判断null
、array
等
typeof Symbol(); // symbol 有效
typeof ''; // string 有效
typeof 1; // number 有效
typeof true; //boolean 有效
typeof undefined; //undefined 有效
typeof new Function(); // function 有效
typeof null; //object 无效
typeof [] ; //object 无效
typeof new Date(); //object 无效
typeof new RegExp(); //object 无效
2.instanceof
用来判断A是否为B的实例,A instanceof B
, 返回 boolean
值。
但它不能检测 null 和 undefined
[] instanceof Array; //true
{} instanceof Object;//true
new Date() instanceof Date;//true
new RegExp() instanceof RegExp//true
null instanceof Null//报错
undefined instanceof undefined//报错
3.Object.prototype.toString.call()
一般数据类型都能够判断,最准确最常用的一种。
补充:
Object.prototype.toString.call来获取,而不能直接 new Date().toString(), 从原型链的角度讲,所有对象的原型链最终都指向了Object, 按照JS变量查找规则,其他对象应该也可以直接访问到Object的toString方法,而事实上,大部分的对象都实现了自身的toString方法,这样就可能会导致Object的toString被终止查找,
因此要用call来强制执行Object的toString方法。
Object.prototype.toString.call('') ; // [object String]
Object.prototype.toString.call(1) ; // [object Number]
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(new Function()) ; // [object Function]
Object.prototype.toString.call(new Date()) ; // [object Date]
Object.prototype.toString.call([]) ; // [object Array]
Object.prototype.toString.call(new RegExp()) ; // [object RegExp]
Object.prototype.toString.call(new Error()) ; // [object Error]
4.Constructor
//constructor这个属性存在于构造函数的原型上,指向构造函数
//对象可以通过__proto__在其所属类的原型上找到这个属性
var arr = [];
arr.constructor === Array;//true
arr.constructor === Object;//false
//arr通过原型链查找到的constructor指向了Array,所以Object判断是错误的
constructor是比较准确判断对象的所属类型的,但是在类继承时会出错
function Fn() {}
Fn.prototype = new Array();
var fn = new Fn();
fn.constructor === Array; //true
//fn是一个对象,但是它的构造函数指向Array是true
function A(){};
function B(){};
A.prototype = new B(); //A继承自B
var aObj = new A();
aobj.constructor === B //true;
aobj.constructor === A // false;
对象直接继承和间接继承的都会报true
aobj instanceof B //true;
aobj instanceof B //true;
解决construtor的问题通常是让对象的constructor手动指向自己:
aobj.constructor = A; //将自己的类赋值给对象的constructor属性
aobj.constructor === A //true;
aobj.constructor === B //false; //基类不会报true了;
类数组:
在JavaScript中常见的类数组有:内置对象arguments、DOM方法返回的结果
eg:
document.querySelectorAll('li'),document.getElementsByTagName('div')
类数组转换数组:
方法1.Array.prototype.slice.call(arrayLike)
的结果是将arrayLike对象转换成Array对象,Array.prototype.slice
表示数组的原型中的slice方法。slice方法返回的是一个Array类型的对象。
//方法实现
Array.prototype.slice = function(start,end){
var result = new Array();
start = start || 0;
end = end || this.length; //使用call后,改变了this的指向,也就是指向传进来的对象
for(var i = start; i < end; i++){
result.push(this[i]);
}
return result;
}
//调用过程
let oDivs = document.getElementsByTagName('div');
oDivs = Array.prototype.slice.call(oDivs);
方法2:使用栈开运算符 ...src
//例子
let ary1 = [1, 2, 3];
let ary2 = [4, 5, 6];
let ary3 = [...ary1, ...ary2];
//ary1.push(...ary2);
console.log(...ary1);//1, 2, 3
console.log(...ary2);//4, 5, 6
console.log(ary3);//[1,2,3,4,5,6]
//类数组转换
let oDivs = document.getElementsByTagName('div');
oDivs = [...oDivs];
方法3:使用ES6里面的Array.from()方法
//例子
let a = Array.from('一二三四五六七') // ["一", "二", "三", "四", "五", "六", "七"]
let b = Array.from(new Set([1, 2, 1, 2])) // [1,2] 数组去重
let c = Array.from(new Map([[1, 2], [2, 4], [4, 8]])) // 接受一个map
//类数组转换
let d = Array.from(arguments)// 接受一个类数组对象
let e = Array.from(document.querySelectorAll('li')) //接受DOM返回的结果
分为以下三大类:
数组操作方法(push、pop、shift、unshift、reverse(倒置)、sort、toString、join、concat、slice(数组截取)、splice(删除 / 插入
))
数组位置方法(indexOf、lastIndexOf)
数组迭代方法(forEach、map、filter、some、every)
详细用法如下:(简单的已经跳过,从sort开始,选择性的讲)
sort()
//传递一个回调函数 代表从小到大
var arr=[1,22,33,55,66,77,4];
arr.sort(function(a,b){
return a-b; //升序,如果降序则return b-a;
});
console.log(arr);//[1, 4, 22, 33, 55, 66, 77]
arr.sort((a,b) => a-b)//箭头函数写法
toString()
//返回值以',' 分隔
var color = ["red", "green", "blue"];
console.log(color.toString()); //red,green,blue
join
啥都没有默认加’,'分隔
var color = ["red", "green", "blue"];
var color1 = color.join(); //默认,
console.log(color1);//red,green,blue
var color2 = color.join('|');
console.log(color2);//red|green|blue
slice 数组截取 默认左闭右开
var color = ["red", "green", "blue"];
var color1 = color.slice(1,2); //默认左闭右开
console.log(color1);//["green"]
splice() 可以用于数组删除 / 插入操作
//删除
//参数为:起点 和 删除 的个数
var color = ["red", "green", "blue"];
color.splice(2,1);
console.log(color);//["red", "green"]
//插入
//参数为:起点 删除0项 插入的新项
var color = ["red", "green", "blue"];
color.splice(2,0,"red","green","pink");
console.log(color);//["red", "green", "red", "green", "pink", "blue"]
//替换 (本质为删除某些项然后再添加新的项)
//参数为:起点 删除数量 新插入的项
var color = ["red", "green", "blue"];
color.splice(2,1,"red","green");
console.log(color);//["red", "green", "red", "green"]
indexOf 和 lastIndexOf 一般用于数组去重
var arr = [1, 1, 1, 2, 2, 2, 3, 5, 6];
var newArr = [];
for (var i = 0; i < arr.length; i++) {
if (newArr.indexOf(arr[i]) === -1) { //该元素在新数组中不存在(index===-1)则放进去
newArr.push(arr[i]);//相当于 newArr[newArr.length]=arr[i];
}
}
console.log(newArr);//[1, 2, 3, 5, 6]
map(callback)
map(callback)方法对数组中的每一项运行给定函数,返回每次函数调用的结果组成的数组
,返回一个新数组;
var arr = [10, 20, 30, 4];
var newArr = arr.map((value) => value > 4);
console.log(newArr);//[true, true, true, false]是给定函数返回的结果组成一个数组
var newArr1 = arr.map((value) =>value * 2);
console.log(newArr1);//[20, 40, 60, 8]
filter(call back)
对数组中的每个元素运行给定函数,返回该函数会返回true 的项组成的数组
,相当于查找满足条件的元素,而且把满足条件的元素组成一个新数组返回
var arr = [10, 20, 30, 4];
var newArr = arr.filter((value) => value > 4);
console.log(newArr);//[10, 20, 30]
some(callback)
返回布尔值,有一个为true
就结束循环
var arr = [10, 20, 30, 4];
console.log(arr.some((value) => value == 20));//true
every(callback)
返回布尔值,全部为true
返回true
;有一个为false
就返回false
var arr = [10, 20, 30, 4];
var flag = arr.every((value) => value >= 4);
console.log(flag);//true
缓存的数据类型都为字符串,通常需将对象序列化成字符串。
一、JS中的三种数据存储方式
cookie、sessionStorage、localStorage
二、cookie 服务端生成,客户端进行维护和存储。(最大 4k)
1、cookie的定义:
cookie是存储在浏览器上的一小段数据,用来记录某些当页面关闭或者刷新后仍然需要记录的信息。在控制台用document.cookie
可以查看当前正在浏览网站的cookie。
2、cookie存在安全问题:
cookie虽然很方便,但是使用cookie有一个很大的弊端,cookie中的所有数据在客户端就可以被修改,数据非常容易被伪造,那么一些重要的数据就不能放在cookie中了,而且如果cookie中数据字段太多会影响传输效率
3、cookie的作用
保存用户登录状态。
例如将用户id存储于一个cookie内,这样当用户下次访问该页面时就不需要重新登录了,现在很多论坛和社区都提供这样的功能。 cookie还可以设置过期时间,
当超过时间期限后,cookie就会自动消失。因此,系统往往可以提示用户保持登录状态的时间:常见选项有一个月、三个 月、一年等。跟踪用户行为。
例如一个天气预报网站,能够根据用户选择的地区显示当地的天气情况。如果每次都需要选择所在地是烦琐的,当利用了 cookie后就会显得很人性化了,系统能够记住上一次访问的地区,当下次再打开该页面时,它就会自动显示上次用户所在地区的天气情况。
因为一切都是在后 台完成,所以这样的页面就像为某个用户所定制的一样,使用起来非常方便定制页面。
如果网站提供了换肤或更换布局的功能,那么可以使用cookie来记录用户的选项,例如:背景色、分辨率等。
当用户下次访问时,仍然可以保存上一次访问的界面风格。手写cookie
let cookie = {
//一个cookie的格式为键值对‘key=value; key=value; key=value’
// 每个cookie以'; '分隔(分号+空格)
//设置cookie
// time为有效时间
set: function(key, val, time) {
let date = new Date();
let expiresDays = time;
date.setTime(date.getTime() + expiresDays * 24 * 3600 * 1000); //计算过期时间
document.cookie = key + '=' + val + ';expires=' + date.toGMTString();
},
// 获取cookie
get: function(key) {
let getCookie = document.cookie.replace(/[ ]/g, ""); //去除不同cookie之间的分界空格
let arrCookie = getCookie.split(";"); //将cookie保存到arrCookie数组中
let res;
for (let i = 0; i < arrCookie.length; i++) {
// 格式: key=value
let arr = arrCookie[i].split('=');
if (key === arr[0]) {
res = arr[1];
break;
}
}
return res;
}
}
三、sessionStorage
当用户用账号和密码登录某个网站后,刷新页面仍然保持登录的状态,服务器如何分辨这次发起请求的用户是刚才登录过的用户呢?这里就是用session保存状态。
用户在输入用户名密码提交给服务器,服务端验证通过后会创建一个session用于记录用户的相关信息,这个session可保存在服务器内存中也可保存在数据库中。
session_id
通过setCookie
添加到http相应头部
session_id
来识别用户。四、localStorage
(最大5M)
保存在浏览器中,保存后数据永远存在不会失效过期,除非用js手动清除。
五、cookie、sessionStorage、localStorage之间的区别
**相同点:**都是存储在浏览器端。并且是同源的
不同点:
1、存储大小
一般浏览器存储cookie最大容量为4kb
,很多浏览器都限制一个站点最多保存20个cookie
。
sessionStorage和localStorage虽然也有存储大小的限制,但是要比cookie大得多。
2、存储有效期:
cookie保存的数据在过期时间之前一直有效,即使关闭浏览器
sessionStorage
保存的数据用于浏览器的一次会话(session),当会话结束(通常是窗口关闭),数据被清空;
localStorage
保存的数据长期存在,因为localStorage的数据是写入磁盘中,每次读取数据时,实际上是从硬盘驱动器上读取这些字节。
3、安全性
cookie中的所有数据在客户端就可以被修改,数据非常容易被伪造,所以对于用户信息来讲,应该将与登录相关的重要信息存储在session中。
4、性能
如果cookie中数据字段太多的话,会影响传输效率,此时需要将重要的信息存放在session中。
但是,session会在一定的时间内保存在服务器上,当访问增多时,会影响服务器的性能。为了减轻服务器的负担,应当使用cookie。
(更新 day-1
,2021/2/6
)