JavaScript
数据类型
数据类型分两种,基础类型和复杂类型,基础类型存储在栈中,复杂类型的对象存储在堆中,基础类型包括6种,分别是Undefined/Null/Boolean/Number/String/Symbol,除了基础类型外都是复杂类型,包括Object/Array/Function等。
原型
原型其实就是每个对象的父级,通过proto获取。在JavaScript中,一切都是对象。我可以将对象分成三类,分别是普通对象、函数对象、原型对象。
比如我们定一个函数Person,Person就是函数对象,new Person就是普通对象,Person.prototype就是原型对象,Person.proto是Person的父级,也就是Functuon的原型对象,相比普通对象,原型对象多了一个constructor属性,指向函数对象。
原型对象可以通过proto属性,访问父级的原型对象,这样就构成了原型通过proto连接原型的链状结构,也就是常说的原型链。
当我们访问对象的属性时,会先在对象上查找,如果没有定义该属性,则会在原型链中逐级查找。
继承
继承是一种概念,子类通过继承可以访问父类的属性和方法,在JavaScript中,对象的属性和方法分成两种,
- 第一种是内部对象this上面的属性和方法
- 第二种是原型上的属性和方法。
所以继承可以分成两步,
- 第一步,是构建原型链,设置子类原型的proto指向父类的原型,这样就继承了父类原型上的属性和方法。
- 第二步,在子函数第一行调用父函数,可以通过父函数.call的方式调用,这样就继承了父类内部对象this的属性和方法。
作用域
变量和函数能被访问的区域称为作用域,可以分成三类
- 全局作用域:任何不在函数或者大括号中申明的变量,就是全局作用域。
- 函数作用域:在函数内部申明,就是函数作用域。
- 块级作用域:在大括号里面申明的,就是块级作用域,是es6新引入作用域。
而变量或函数的作用域所处的层级,是在创建阶段确认的,也就是常说的词法作用域,而非运行阶段。。当访问某个变量时,会先从当前作用域查找,如果没有找到会逐层往上查找,如果一直到全局作用域还没找到,则会在全局作用域创建一个变量。
闭包
闭包是指定义在函数内部的函数,通过闭包可以访问函数作用域的特性,可以实现两个功能。
- 对象的私有变量
- 变量的持久化,比如柯里化函数:把接受多个参数的函数变换成接受一个单一参数的函数,并返回一个新函数,这个新函数可以接受余下的函数,执行后返回结果。
注意事项
对于函数对象,我可以利用闭包的特性,将内部对象绑定的函数,写到prototype中。
this
this是函数运行时的内部对象,指向调用它的对象,调用方式通常有以下几种。
- 在顶层直接调用函数,this就是全局对象window。
- 如果函数是某个对象的属性,通过对象点函数的方式调用,this就是这个对象。
- 函数通过apply/call注入对象的方式调用,this就是注入的这个对象。
- 函数通过bind绑定某个对象,那么函数运行时,this就是绑定的这个对象。 箭头函数比较特殊,在编译期就已经绑定了当前对象。
数组
- 操作方法
- 增
- push(...插入的元素)
- unshift(...插入的元素) 开头添加
- splice(起始位置,删除数量,...插入的元素)
- concat(...插入的元素,[...插入的元素]) 不会影响原数组
- 删
- pop 删除最后一个
- shift 删除第一个
- splice
- slice(开始位置,截止位置) 截取元素生成数组
- 改
- splice
- 查
- indexOf
- includes
- find
- 增
- 排序
- reverse 逆转
- sort
- 转换
- reduce
- join
- 迭代
- map
- forEach
- filter
- every 全部true标识true
- some 有一个true表示true
ES6
var/let/const
- var 用于申明变量,可以重复申明,如果是在顶层相当于全局变量,如果声明在方法里面是局部变量,var存在变量提升的情况,。
- let和const是es6新加入的语法,let用于申明变量,const用于申明常量,他们都是块级作用域,不可重复申明,在申明前存在暂时性死区。
Promise
Promise是异步编程的解决方案,可以通过new Promise来创建异步任务,又叫微任务,执行结果有两种,成功和失败。Promise对象有3个方法,分别是then、catch、finally,调用这三个方法都会返回一个新的Promise对象,其中then和catch可以通过监听函数的返回值来修改新的Promise对象的执行结果。
Promise还提供了几个静态方法
- resolve
- reject
- all 全部成功
- allSettled 全部结束
- race 第一个成功
Proxy
Proxy可以用于实现修改对象或函数的行为,通过new-Proxy将需要代理的对象或函数传入第一个参数,第二个参数为代理的具体实现,常用可代理的方法有
- get
- set
- apply
ES6 模块
ES6模块是ES6新增的模块化方案,早期的JavaScript是没有模块的概念,资源的加载是通过script标签自上而下,容易造成变量污染,大项目难以维护。为了解决这些问题,出现了几种JavaScript模块化方案。包括CommonJs、AMD、CMD、UMD、ES模块。
-
CommonJS 是NodeJs采用的模块化方式,加载是同步的,一个单独的文件就是一个模块,通过exports导出require导入。
-
AMD 是异步模块化规范,代表库是RequireJs,所有的依赖都定义在require函数中,等模块加载完后,require回调函数才会执行。
/** main.js 入口文件/主模块 **/ // 首先用config()指定各模块路径和引用名 require.config({ baseUrl: "js/lib", paths: { "jquery": "jquery.min", //实际路径为js/lib/jquery.min.js "underscore": "underscore.min", } }); // 执行基本操作 require(["jquery","underscore"],function($,_){ // some code here });很明显,所有依赖都写在前面,这是很不符合编码思想的,于是就出现了CMD。
-
CMD 也是异步模块化的一种,代表库是SeaJS,相比AMD的依赖前置,CMD采用的是依赖就近。
define(function (requie, exports, module) { //依赖可以就近书写 var a = require('./a'); a.test(); ... //软依赖 if (status) { var b = requie('./b'); b.test(); } }); -
UMD 通用模块规范,既可用于服务端,也可以用于浏览器端,实际是CommonJs和AMD的糅合,会根据当前环境选择对应的加载方式。
-
ES6,是语言层面的模块化方案,完全可以取代AMD和CommonJS,可用于服务端和浏览器端。
- ES6模块通过export导出,import导入,只有通过export导出的内部变量外部才能访问。
- ES6导出和导入时,可以通过as对变量进行重命名,也可以通过export default导出默认的变量。
ES6 Decorator装饰器
ES6装饰器是一个函数,可以在不改变类结构的情况下,拓展类的属性和方法。装饰器可以分成两种,分别是类装饰器和类属性装饰器。
-
类装饰器,更像是将类作为参数传递给装饰器,React高阶组件经常用到。
@testable class MyTestableClass { // ... } function testable(target) { target.isTestable = true; } -
属性装饰,包含3个参数,分别是target,name,descriptor。可以收集属性信息或修改属性特征。
function readonly(target, name, descriptor){ descriptor.writable = false; // 将可写属性设为false return descriptor; }
CSS
盒模型
盒模型是指文档流在布局时,浏览器渲染引擎会将文档表示成一个矩形的盒子,这个盒子包含4个部分。
- content,指实际内容,文本或者图像
- border,是指边框,有粗细、样式、颜色三部分组成
- padding,是指内边距
- margin,是指外边距
盒模型包含两种
- 标准的盒模型,盒子宽度=内容的宽度+边框+内边距+外边距,盒子高度=内容的高度+边框+内边距+外边距。
- IE怪异的盒模型,盒子宽度=内容的宽度+外边距,盒子高度=内容的宽度+外边距,内容的宽高包含了边框和内边距。
我们可以通过box-sizing来设置盒模型的方式
- content-box,默认行为,宽度和高度不包含border和padding,也就是标准盒模型
- border-box, 元素的宽度和高度包含padding和border,也就是怪异盒模型
- inherit,从父元素继承
选择器
分类
-
id选择器(#box),选择id为box的元素
-
类选择器(.one),选择类名为one的所有元素
-
标签选择器(div),选择标签为div的所有元素
-
后代选择器(#box div),选择id为box元素内部所有的div元素
-
子选择器(.one>one_1),选择父元素为.one的所有.one_1的元素
-
相邻同胞选择器(.one+.two),选择紧接在.one之后的所有.two元素
-
群组选择器(div,p),选择div、p的所有元素
-
伪类选择器
:link :选择未被访问的链接 :visited:选取已被访问的链接 :active:选择活动链接 :hover :鼠标指针浮动在上面的元素 :focus :选择具有焦点的 :first-child:父元素的首个子元素 -
伪元素选择器
:first-letter :用于选取指定选择器的首字母 :first-line :选取指定选择器的首行 :before : 选择器在被选元素的内容前面插入内容 :after : 选择器在被选元素的内容后面插入内容 -
属性选择器
优先级
我们将样式分成四大类,分别是
- 内联样式
- ID选择器
- 类选择器
- 标签选择器
他们的优先级顺序是
内联 > ID选择器 > 类选择器 > 标签选择器
如果某个元素的同一个样式,被设置了多次,而且是通过子选择或者后代选择器的方式设置,那优先级的计算方式,会根据各大选择器类别出现的次数进行计算。
- 首先比较样式设置中,ID选择器出现次数,会采用次数多的那个样式,如果相同。
- 再次比较类选择器出现的次数
- 最后比较标签选择器出现的次数
- 如果还相同,那就采用最后设置的那个样式
// ID(1次),类(1次),标签(3次) #nav-global > ul > li > a .nav-link
可继承继承
- 字体系列属性
- font:组合字体
- font-family:规定元素的字体系列
- font-weight:设置字体的粗细
- font-size:设置字体的尺寸
- font-style:定义字体的风格
- font-variant:偏大或偏小的字体
- 文本系列属性
- text-indent:文本缩进
- text-align:文本水平对刘
- line-height:行高
- word-spacing:增加或减少单词间的空白
- letter-spacing:增加或减少字符间的空白
- text-transform:控制文本大小写
- direction:规定文本的书写方向
- color:文本颜色
- 元素可见性
- visibility
- 表格布局属性
- caption-side:定位表格标题位置
- border-collapse:合并表格边框
- border-spacing:设置相邻单元格的边框间的距离
- empty-cells:单元格的边框的出现与消失
- table-layout:表格的宽度由什么决定
- 列表属性
- list-style-type:文字前面的小点点样式
- list-style-position:小点点位置
- list-style:以上的属性可通过这属性集合
- 引用
- quotes:设置嵌套引用的引号类型
- 光标属性
- cursor:箭头可以变成需要的形状 不可继承的属性
- display
- 文本属性:vertical-align、text-decoration
- 盒子模型的属性:宽度、高度、内外边距、边框等
- 背景属性:背景图片、颜色、位置等
- 定位属性:浮动、清除浮动、定位position等
- 生成内容属性:content、counter-reset、counter-increment
- 轮廓样式属性:outline-style、outline-width、outline-color、outline
- 页面样式属性:size、page-break-before、page-break-after