# 重学前端 🍏
这个文档是根据程劭非大佬最近在即刻时间上开设的《重学前端》作的笔记,想要巩固一下自己的前端知识,大概的建立一下自己的知识架构。
# JS
# JS类型
JavaScript 语言规定了 7 种语言类型:
- Number
- Boolean
- String
- Object
- Symbol
- Null
- Undefined
Undefined
类型表示未定义,它的类型只有一个值,就是 undefined
null
表示的是:“定义了但是为空”。
与Undefined不同的是,null 是 JavaScript 关键字,所以在任何代码中,都可以用null关键字来取null值。
因为 JavaScript 的代码 undefined 是一个变量,而并非是一个关键字,所以,我们为了避免无意中被篡改,建议使用void 0来获取 undefined 值。
String
用于表示文本数据。String 有最大长度是 2^53 - 1
Number
类型有 18437736874454810627(即 2^64-2^53+3) 个值。
为什么在 JavaScript 中,0.1+0.2 不能 =0.3:浮点数运算的精度问题导致等式左右的结果并不是严格相等,而是相差了个微小的值。正确的比较方法是使用 JavaScript 提供的最小精度值:
console.log( Math.abs(0.1 + 0.2 - 0.3) <= Number.EPSILON);
2
Symbol
是 ES6 中引入的新类型,它是一切非字符串的对象 key 的集合
我们创建 Symbol 的方式是使用全局的 Symbol 函数。例如:
var mySymbol = Symbol("my symbol");
一些标准中提到的 Symbol,可以在全局的 Symbol 函数的属性中找到。例如,我们可以使用 Symbol.iterator 来自定义 for…of 在对象上的行为:
var o = new Object
o[Symbol.iterator] = function() {
var v = 0
return {
next: function() {
return { value: v++, done: v > 10 }
}
}
};
for(var v of o)
console.log(v); // 0 1 2 3 ... 9
2
3
4
5
6
7
8
9
10
11
12
13
14
# JS属性
# 数据属性
value:就是属性的值。
writable:决定属性能否被赋值。
enumerable:决定 for in 能否枚举该属性。
configurable:决定该属性能否被删除或者改变特征值。
# 访问器属性
getter:函数或 undefined,在取属性值时被调用。
setter:函数或 undefined,在设置属性值时被调用。
enumerable:决定 for in 能否枚举该属性。
configurable:决定该属性能否被删除或者改变特征值。
var o = { a: 1 };
o.b = 2;
//a 和 b 皆为数据属性
Object.getOwnPropertyDescriptor(o,"a") // {value: 1, writable: true, enumerable: true, configurable: true}
Object.getOwnPropertyDescriptor(o,"b") // {value: 2, writable: true, enumerable: true, configurable: true}
2
3
4
5
如果我们要想改变属性的特征,或者定义访问器属性,我们可以使用 Object.defineProperty
,示例如下:
var o = { a: 1 };
Object.defineProperty(o, "b", {value: 2, writable: false, enumerable: false, configurable: true});
//a 和 b 都是数据属性,但特征值变化了
Object.getOwnPropertyDescriptor(o,"a"); // {value: 1, writable: true, enumerable: true, configurable: true}
Object.getOwnPropertyDescriptor(o,"b"); // {value: 2, writable: false, enumerable: false, configurable: true}
o.b = 3;
console.log(o.b); // 2 因为 writable 特征为 false,所以我们重新对 b 赋值,b 的值不会发生变化。
2
3
4
5
6
7
8
# JS原型
如果所有对象都有私有字段 [[prototype]],就是对象的原型;
读一个属性,如果对象本身没有,则会继续访问对象的原型,直到原型为空或者找到为止。
但从 ES6 以来,JavaScript 提供了一系列内置函数,以便更为直接地访问操纵原型。三个方法分别为:
Object.create 根据指定的原型创建新对象,原型可以是 null;
Object.getPrototypeOf 获得一个对象的原型;
Object.setPrototypeOf 设置一个对象的原型。
var cat = {
say(){
console.log("meow~");
},
jump(){
console.log("jump");
}
}
var tiger = Object.create(cat, {
say:{
writable:true,
configurable:true,
enumerable:true,
value:function(){
console.log("roar!");
}
}
})
var anotherCat = Object.create(cat);
anotherCat.say();
var anotherTiger = Object.create(tiger);
anotherTiger.say();
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
# 类
类提供了继承性 ES6 中引入了 class 关键字,并且在标准中删除了所有 [[class]] 相关的私有属性描述,类的概念正式从属性升级成语言的基础设施,从此,基于类的编程方式成为了 JavaScript 的官方编程范式。
基本写法:
class Rectangle {
constructor(height, width) {
this.height = height;
this.width = width;
}
// Getter
get area() {
return this.calcArea();
}
// Method
calcArea() {
return this.height * this.width;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
类提供了继承性
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(this.name + ' makes a noise.');
}
}
class Dog extends Animal {
constructor(name) {
super(name); // call the super class constructor and pass in the name parameter
}
speak() {
console.log(this.name + ' barks.');
}
}
let d = new Dog('Mitzie');
d.speak(); // Mitzie barks.
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# JS对象分类
宿主对象(host Objects):由 JavaScript 宿主环境提供的对象,它们的行为完全由宿主环境决定。
内置对象(Built-in Objects):由 JavaScript 语言提供的对象。
- 固有对象(Intrinsic Objects ):由标准规定,随着 JavaScript 运行时创建而自动创建的对象实例。
- 原生对象(Native Objects):可以由用户通过 Array、RegExp 等内置构造器或者特殊语法创建的对象。
- 普通对象(Ordinary Objects):由{}语法、Object 构造器或者 class 关键字定义类创建的对象,它能够被原型继承。
# 宿主对象
JavaScript 宿主对象千奇百怪,但是前端最熟悉的无疑是浏览器环境中的宿主了。
在浏览器环境中,我们都知道全局对象是 window,window 上又有很多属性,如 document。
实际上,这个全局对象 window 上的属性,一部分来自 JavaScript 语言,一部分来自浏览器环境
JavaScript 标准中规定了全局对象属性,w3c 的各种标准中规定了 Window 对象的其它属性。
宿主对象也分为固有的和用户可创建的两种,比如 document.createElement 就可以创建一些 dom 对象。 宿主也会提供一些构造器,比如我们可以使用 new Image 来创建 img 元素。
# 固有对象
固有对象是由标准规定,随着 JavaScript 运行时创建而自动创建的对象实例。
# 原生对象
能够通过语言本身的构造器创建的对象称作原生对象。在 JavaScript 标准中,提供了 30 多个构造器。 通过这些构造器,我们可以用 new 运算创建新的对象,所以我们把这些对象称作原生对象 这些构造器创建的对象多数使用了私有字段, 例如:
- Error: [[ErrorData]]
- Boolean: [[BooleanData]]
- Number: [[NumberData]]
- Date: [[DateValue]]
- RegExp: [[RegExpMatcher]]
- Symbol: [[SymbolData]]
- Map: [[MapData]]
# CSS
# @规则
# @charset
@charset 用于提示 CSS 文件使用的字符编码方式,它如果被使用,必须出现在最前面。这个规则只在给出语法解析阶段前使用,并不影响页面上的展示效果。
@charset "utf-8";
# @import
@import 用于引入一个 CSS 文件,除了 @charset 规则不会被引入,@import 可以引入另一个文件的全部内容。
@import "mystyle.css";
@import url("mystyle.css");
@import [ <url> | <string> ]
[ supports( [ <supports-condition> | <declaration> ] ) ]?
<media-query-list>? ;
2
3
4
5
# @media
media 就是大名鼎鼎的 media query 使用的规则了,它能够对设备的类型进行一些判断。在 media 的区块内,是普通规则列表。
@media print {
body { font-size: 10pt }
}
2
3
# @page
page 用于分页媒体访问网页时的表现设置,页面是一种特殊的盒模型结构,除了页面本身,还可以设置它周围的盒。
@page {
size: 8.5in 11in;
margin: 10%;
@top-left {
content: "Hamlet";
}
@top-right {
content: "Page " counter(page);
}
}
2
3
4
5
6
7
8
9
10
11
# @ counter-style
counter-style 产生一种数据,用于定义列表项的表现。
@counter-style triangle {
system: cyclic;
symbols: ‣;
suffix: " ";
}
2
3
4
5
# @ key-frames
keyframes 产生一种数据,用于定义动画关键帧。
@keyframes diagonal-slide {
from {
left: 0;
top: 0;
}
to {
left: 100px;
top: 100px;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
# @ fontface
fontface 用于定义一种字体,icon font 技术就是利用这个特性来实现的。
@font-face {
font-family: Gentium;
src: url(http://example.com/fonts/Gentium.woff);
}
p { font-family: Gentium, serif; }
2
3
4
5
6
# @ support
support 检查环境的特性,它与 media 比较类似。
# @ namespace
用于跟 XML 命名空间配合的一个规则,表示内部的 CSS 选择器全都带上特定命名空间。
# @ viewport
用于设置视口的一些特性,不过兼容性目前不是很好,多数时候被 html 的 meta 代替。
# 声明:属性和值
在CSS Variables 标准中,以双中划线开头的属性被当作变量,与之配合的则是 var 函数:
:root {
--main-color: #06c;
--accent-color: #006;
}
/* The rest of the CSS file */
#foo h1 {
color: var(--main-color);
}
2
3
4
5
6
7
8
9