前端基础-每日一更

GitHub、Gitee 同步更新
GitHub:web_basic-knowledge-study
Gitee: Web_basicKnowledgeStudy

工具-Git

1.git 和 svn的区别
  1. git 和 svn 最大的区别在于 git 是分布式的,而 svn 是集中式的。因此我们不能再离线的情况下使用 svn。如果服务器出现问题,我们就没有办法使用 svn 来提交我们的代码
  2. svn 中的分支是整个版本库的复制的一份完整目录,而 git 的分支是指针指向某次提交,因此git 的分支创建更加开销更小并且分支上的变化不会影响到其他人。svn 的分支变化会影响到
  3. svn相对于 git 来说要简单一些,比 git 更容易上手
  4. git 和 svn 对比 - 掘金
  5. git 学习小计 - 分支原理
2.常见git 命令
git init // 新建 git 代码库
git add // 添加指定文件到暂存区
git rm // 删除工作区文件,并且将这次删除放入暂存区
git commit -m [message] // 提交暂存区到仓库区
git branch // 列出所有分支
git checkout -b [branch] // 新建一个分支,并切换到该分支
git status // 显示有变更的文件

常见 git 命令清单

3.git pull 和 git fetch 的区别 (从远程仓库更新到本地仓库)
  1. git fetch 只是将远程仓库的变化下载下来,并没有和本地分支合并。
  2. git pull 会将远程仓库的变化下载下来,并和当前分支合并
  3. git pull = git fetch + git merge
  4. 详解git pull 和 git fetch 的区别
4.git rebase 和 git merge 的区别
  1. git merge 和 git rebase 都是用于分支合并,关键在 commit 记录的处理上不同。
  2. git merge 会新建一个新的 commit 对象,然后两个分支以前的 commit 记录都指向这个新 commit记录。这种方法会保留之前每个分支的 commit 历史。
  3. git rebase 会先找到两个分支的第一个共同的 commit 祖先记录,然后将提取当前分支这之后的所有commit 记录,然后将这个 commit 记录添加到目标分支的最新提交后面。经过这个合并后,两个分支合并后的 commit 记录就变为了线性的记录了(线性树--对两个分支的历史有破坏)
  4. 《git merge 与 git rebase 的区别》

(最后更新于 day-12021/2/6 )

HTML

1. DOCTYPE的作用是什么?

声明位于 HTML 文档中的第一行,处于 标签之前。

**作用:**告知浏览器以什么文档标准解析这个文档。

DOCTYPE不存在或格式不正确会导致文档以兼容模式呈现。

一般指定了之后会以标准模式来进行文档解析,否则就以兼容模式进行解析。在标准模式下,浏览器的解析规则都是按照最新的标准进行解析的。而在兼容模式下,浏览器会以向后兼容的方式来模拟老式浏览器的行为,以保证一些老的网站的正确访问。

HTML5 之后不再需要指定DTD文档:
因为HTML5之前的文档都是基于SGML的,因此需要指定DTD来定义文档中允许的属性和一些规则。
由于HTML5不再基于SGML,因此不再需要使用DTD

2.标准模式 和 兼容模式的区别

**标准模式:**渲染模式和 JS引擎的解析方式都是以该浏览器所能支持的最高标准运行。

**兼容模式:**页面以宽松的向后兼容的方式显示,模拟老式浏览器的行为,防止站点无法工作。

3. HTML5 为什么只需要写,而不需要引入 DTD?

HTML5不再基于SGML,因此不需要指定DTD

HTML5之前的文档都是基于SGML,需要指定DTD来定义相应的规则和属性

4. SGML 、 HTML 、XML 和 XHTML 的区别?

SGML:标准通用标记语言,是一种定义电子文档和描述其内容的国际标准语言,是所有电子文档标记语言的起源。
HTML:超文本标记语言,规定怎么显示网页。
XML:可扩展标记语言,XML标签可自建,无限多;HTML标签固定且数量有限。
XHTML:基本所有网页都在使用的标记语言,和HTML没有本质区别,标签,数量都一样,主要是比HTML更严格了
											eg:标签规定必须小写,标签都必须由闭合标签等等。

5. DTD 介绍

DTD( Document Type Definition )文档类型定义

是一组机械可读的规则,定义了XML 或 HTML的特定版本中的所有允许元素、规则和属性

在进行网页解析时,浏览器使用这些规则,检查页面的有效性并采取相应的措施

DTD是对HTML文档的声明,还会影响浏览器的渲染模式。

6. 行内元素(内联元素)定义

常见行内元素:a b span img strong sub sup button input label select textarea

7. 块级元素定义

常见的块级元素有 div ul ol li dl dt dd h1 h2 h3 h4 h5 h6 p

8.行内元素和块级元素的区别

  1. **主要区别:**体现在盒模型上。设置width和height无效,设置magin 和padding的上下不会对其他元素产生影响

  2. 行内元素不会换行,块级元素会另起一行

  3. 行内元素只能包含文本和其他行内元素,但是块级元素可以包含块其他级元素和行内元素

9.HTML5 元素的分类 (***有点难记)

在HTML4中,元素被分为 inline 和 block两大类,但是在实际应用中,我们经常需要用display转换,更是出现了inline-block对外显示inline 对内显示block的属性,inline和block已不再符合实际需求

HTML5的元素分类(7类):Metadata Flow Sectioning Heading Phrasing Embedded Interactive

10. 空元素定义

标签中没有内容的HTML标签被称为空元素空元素在开始标签中关闭。

常见的空元素 :br(换行) hr(分隔线) img link meta input

11.link 标签定义

link 标签定义文档与外部资源的关系

link 元素是空元素,仅包含属性,存在于head ,可以出现无限次

link 标签中的rel定义了当前文档与链接文档之前的关系,例如常见的stylesheet指的就是一个外部加载的样式文件

12. 页面导入样式时,使用 link 和 @import 有什么区别?

4个主要的区别

  1. 从属关系区别:@import是css提供的语法,只可导入样式表,但是link不仅导入css样式表,还可以定义rss,rel 连接属性、引入网站图标等。

  2. 加载顺序区别:link引入的css在页面加载时同时加载,但是@import引入的css在页面加载完后加载

  3. 兼容性区别:@import 是css2.1的语法,在IE5+才可以使用,而link是HTML的元素,不存在兼容性问题

  4. DOM可控性区别:link可以通过JS操作DOM插入link标签修改样式,但是@improt是css的语法,无法通过DOM操作。DOM是基于文档的。

(最后更新于 day-22021/2/7 )

JavaScript

1.介绍 js 的基本数据类型

js 一共有六种基本数据类型,

5种简单类型分别是 Undefined、Null、Boolean、Number、String (巧记 undefined / null,NSB)

1种复杂数据类型 object(对象)

ES6 新增的 symbol 类型:

Symbol 代表创建后独一无二且不可变的数据类型,它的出现我认为主要是为了解决可能出现的全局变量冲突 的问题。

ES10 新增的BigInt 类型:

BigInt 是一种数字类型的数据,它可以表示任意精度格式的整数,使用 BigInt 可以安全地存储和操作大 整数,即使这个数已经超出了Number 能够表示的安全整数范围。

(最后更新于 day-22021/2/7 )

2.原始值和引用值

**原始值 **即一些代表原始数据类型的值,也叫基本数据类型,首先说一下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],指向了新的堆空间。

3. JS中数据类型的4种判断方法

typeof 、 instanceof 、 Object.prototype.toString.call() 、constructor(构造函数)

**1.typeof **
返回值包括number、boolean、string、symbol、object、undefined、function等7种数据类型
但不能判断nullarray

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了;

4.类数组与数组的区别与转换

类数组:

  1. 拥有length属性,其它属性(索引)为非负整数(对象中的索引会被当做字符串来处理)
  2. 不具有数组所具有的方法
  3. 是一些元素的集合(普通对象),相当于是个伪数组,数组是Array型
在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返回的结果

5. 数组常见的API

分为以下三大类:

数组操作方法(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

面经

1 浏览器存储缓存机制

缓存的数据类型都为字符串,通常需将对象序列化成字符串。

一、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后,会把关联的session_id通过setCookie添加到http相应头部
  • 浏览器在加载页面时发现响应头部有set-cookie字段,就把这个cookie种到浏览器指定域名下
  • 当下次刷新页面时,发送的请求会带上这条cookie,服务端在接收到后根据这个session_id来识别用户。

四、localStorage

  • localStorage是H5本地存储web storage特性的API之一,用于将大量数据(最大5M)保存在浏览器中,保存后数据永远存在不会失效过期,除非用js手动清除。
  • 不参与网络传输
  • 一般用于性能优化,可以保存图片、js、css、html模板、大量数据

五、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-12021/2/6 )

你可能感兴趣的:(前端学习,git,session,javascript,html5,css)