前端基础知识

html

1. html 5 新特性

用于绘画的 canvas 元素

用于媒介回放的 video 和 audio 元素

对本地离线存储的更好的支持
localStorage、sessionStorage 不同浏览器容量不同,容量 4.98M。但注意 javascript 使用 utf-16 编码,所以最多有2.5M
http://dev-test.nemikor.com/web-storage/support-test/

Cookie不同浏览器容量不同, 最多容量4M ,50条数据。

新的特殊内容元素,比如 article、footer、header、nav、section

新的表单控件,比如 calendar、date、time、email、url、search

2. 同源策略

http://www.ruanyifeng.com/blog/2016/04/same-origin-policy.html
同协议,同端口,同域名(一级二级域名是不同域名)

如果非同源,共有三种行为受到限制。

(1) Cookie、LocalStorage 和 IndexDB 无法读取。

(2) DOM 无法获得。

(3) AJAX 请求不能发送

3. 跨域

JSONP 它的基本思想是,网页通过添加一个<script>元素,向服务器请求JSON数据,这种做法不受同源政策限制;服务器收到请求后,将数据放在一个指定名字的回调函数里传回来。

WebSocket是一种通信协议,使用ws://(非加密)和wss://(加密)作为协议前缀。该协议不实行同源政策,只要服务器支持,就可以通过它进行跨源通信。

CORS是一个W3C标准,全称是”跨域资源共享”(Cross-origin resource sharing)。

它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。

4. 标签语义化

通过标签判断内容语义,例如根据h1标签判断出内容是标题,根据<p>判断内容是段落、<input>标签是输入框等。

判断标签是否语义化:去掉样式,看网页结构是否组织良好有序,是否仍然有很好的可读性。

为什么标签要语义化

  1. 搜索引擎友好。
  2. 更容易让屏幕阅读器读出网页内容。
  3. 去掉或样式丢失的时候能让页面呈现清晰的结构。
  4. 便于团队开发和维护。

标题使用<h2>而不是<div class="h2">,段落使用<p>标签,锚点使用<a>

http 状态码

1 信息
2
成功 200
3 重定向 304 (未修改)
4
客户端错误
5** 服务器错误

css3

选择器 [attribute^=value] :nth-of-type(n) :nth-child(n)
盒模型 -> box-sizing:content-box border-box
背景和边框-> 圆角边框/背景图
文本效果
2D/3D 转换 -> 移动translate、缩放scale、转动rotate、拉长或拉伸skew 六个值的矩阵matrix
过渡 -> transition
动画 CSS3 动画属性
多列布局
弹性盒子(Flex Box)

javascript特性

1 类型

基本类型 number、boolean、string、null、undefined
复杂类型 array、function、object
新增类型 Set、Map、Symbol

类型判断 typeof

1
Object.prototype.toString.call(myArr) === '[object Array]'

2 类型的困惑

尽量避免用 new

1
2
3
4
5
6
new String('a') instanceof String //true
'a' instanceof String //false

typeof null //'object'
typeof [] //'object'
[] instanceof Array //true

条件表达式里 null、undefined、’’ 会被判定为 false

3 函数

1
2
3
var a = function a () {
'function' == typeof a //true,这里的 a 是前面那个 var a
}

4 函数的参数变量

1
2
var a = fuction (b,c) {}
a.length //3

5 闭包

在某个作用域中定义的变量只能在该作用域或其内部作用域中才能访问到

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var a = 5;

function woot() {
a==5;//false
console.log(a==5);
var a=6;

function test () {
a==6;//true
console.log(a==6);
}

test();
};

woot();

自执行函数,通过声明调用匿名函数,定义新的作用域

1
2
3
4
5
6
var a = 3;
(function(){
var a = 5;
})()

a == 3; //true

6 类

类通过函数定义

1
2
3
4
5
6
function Animal (name) {
this.name=name;
}
Animal.prototype.getName() {
return this.name;
}

7 深浅拷贝

属性的可枚举性和所有权 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Enumerability_and_ownership_of_properties

for...in 可以循环出 可枚举属性,自身对象及其原型链。再使用 hasOwnProperty 判断,得到自身属性

8 this 指向

按下面优先级

  1. new 绑定?绑定新创建的对象

    1
    var bar = new foo()
  2. call、apply 显式绑定?绑定指定对象

    1
    var bar = foo.call(obj)
  3. 在上下文调用,隐式绑定?绑定上下文对象

    1
    var bar = obj.foo()
  4. 默认绑定,严格模式绑定到 undefined,非严格模式绑定到全局对象

    1
    var bar = foo()

另外 箭头函数的 this 绑定无法被修改,不适用上述规则

箭头函数继承外层函数的 this

9 继承

函数继承

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
function Parent(value) {
this.val = value
}
Parent.prototype.getValue = function() {
console.log(this.val)
}

function Child(value) {
Parent.call(this, value)
}

//组合继承
Child.prototype = new Parent();
Child.prototype.constructor = Child;

//寄生组合继承
Child.prototype = Object.create(Parent.prototype, {
constructor: {
value: Child,
enumerable: false,
writable: true,
configurable: true
}
})

// 调用
const child = new Child(1)
child.getValue() // 1
child instanceof Parent; // true

class 继承

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Parent {
constructor(value) {
this.val = value
}
getValue() {
console.log(this.val)
}
}
class Child extends Parent {
constructor(value) {
super(value)
this.val = value
}
}
let child = new Child(1)
child.getValue() // 1
child instanceof Parent // true

10. event loop

不同的任务源会被分配到不同的 Task 队列中,任务源可以分为 微任务(microtask) 和 宏任务(macrotask)

宏任务(macrotask)
setTimeout
setInterval
setImmediate (Node独有)
requestAnimationFrame (浏览器独有)
I/O
UI rendering (浏览器独有)

微任务(microtask)
process.nextTick (Node独有)
Promise
Object.observe
MutationObserver

11. 实现 call、apply、bind

call
首先 context 为可选参数,如果不传的话默认上下文为 window
接下来给 context 创建一个 fn 属性,并将值设置为需要调用的函数
因为 call 可以传入多个参数作为调用函数的参数,所以需要将参数剥离出来
然后调用函数并将对象上的函数删除

1
2
3
4
5
6
7
8
9
10
11
Function.prototype.myCall = function(context) {
if (typeof this !== 'function') {
throw new TypeError('Error')
}
context = context || window
context.fn = this
const args = [...arguments].slice(1)
const result = context.fn(...args)
delete context.fn
return result
}

apply

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Function.prototype.myApply = function(context) {
if (typeof this !== 'function') {
throw new TypeError('Error')
}
context = context || window
context.fn = this
let result
// 处理参数和 call 有区别
if (arguments[1]) {
result = context.fn(...arguments[1])
} else {
result = context.fn()
}
delete context.fn
return result
}

bind
bind 返回了一个函数,对于函数来说有两种方式调用,一种是直接调用,一种是通过 new 的方式,我们先来说直接调用的方式

对于直接调用来说,这里选择了 apply 的方式实现,但是对于参数需要注意以下情况:因为 bind 可以实现类似这样的代码 f.bind(obj, 1)(2),所以我们需要将两边的参数拼接起来,于是就有了这样的实现 args.concat(…arguments)

最后来说通过 new 的方式,在之前的章节中我们学习过如何判断 this,对于 new 的情况来说,不会被任何方式改变 this,所以对于这种情况我们需要忽略传入的 this

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Function.prototype.myBind = function (context) {
if (typeof this !== 'function') {
throw new TypeError('Error')
}
const _this = this
const args = [...arguments].slice(1)
// 返回一个函数
return function F() {
// 因为返回了一个函数,我们可以 new F(),所以需要判断
if (this instanceof F) {
return new _this(...args, ...arguments)
}
return _this.apply(context, args.concat(...arguments))
}
}

12. new

在调用 new 的过程中会发生以上四件事情:

新生成了一个对象
链接到原型
绑定 this
返回新对象

根据以上几个过程,我们也可以试着来自己实现一个 new

1
2
3
4
5
6
7
function create() {
let obj = {}
let Con = [].shift.call(arguments)
obj.__proto__ = Con.prototype
let result = Con.apply(obj, arguments)
return result instanceof Object ? result : obj
}

创建一个空对象
获取构造函数
设置空对象的原型
绑定 this 并执行构造函数
确保返回值为对象

es6

1. let, const

var命令会发生”变量提升“现象,即变量可以在声明之前使用,值为undefined。这种现象多多少少是有些奇怪的,按照一般的逻辑,变量应该在声明语句之后才可以使用。

为了纠正这种现象,let命令改变了语法行为,它所声明的变量一定要在声明后使用,否则报错。

不允许重复声明

暂时性死区
只要块级作用域内存在let命令,它所声明的变量就“绑定”(binding)这个区域,不再受外部的影响。
总之,在代码块内,使用let命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”(temporal dead zone,简称 TDZ)。

但对于复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指针,const只能保证这个指针是固定的

2. 块级作用域

ES5 只有全局作用域和函数作用域
ES6 的块级作用域 {}

3. es7

Array.prototype.includes -> 代替 indexOf,返回true或false,还可以参数规定从第几位开始
求冥运算(次方)

事件传播

冒泡捕获
先捕获再冒泡

阻止传播 e.stopPropagation();

事件委托

1
2
3
4
5
6
7
var parent = document.getElementById("parent");
var child = document.getElementById("child");
parent.onclick = function(e){
if(e.target.id == "child"){
console.log("您点击了child元素")
}
}

React 生命周期

http://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/

getderivedstatefromprops

夏味 wechat
欢迎添加我个人微信,互相学习交流