面向过程

面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现, 使用的时候再一个一个的依次调用就可以了。

面向对象

面向对象是把事务分解成为一个个对象,然后由对象之间分工与合作。

1
2
3
4
5
6
7
8
9
10
11
面向过程
理解:亲力亲为
优点:性能高
缺点:不好维护

面向对象
理解:把一个个东西当做对象来使用(对象,往往都是被人封装好的代码)
优点:好维护,复用,扩展
缺点:性能稍低

都是一种思维

在 ES6 中新增加了类的概念,可以使用 class 关键字声明一个类,之后以这个类来实 例化对象。类抽象了对象的公共部分,它泛指某一大类(class)对象特指某一个, 通过类实例化一个具体的对象

创建类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 1. 创建类 class 创建一个 明星类
class Star{
constructor(uname){
this.uname=uname;
}
// 不用function 不需要逗号分隔
sing(song){
console.log(this.uname+song);
}
}

// 2. 利用类创建对象 new
var ldh = new Star('刘德华');
ldh.sing('冰雨');

1. 通过class 关键字创建类, 类名我们还是习惯性定义首字母大写
2. 类里面有个constructor 函数,可以接受传递过来的参数,同时返回实例对象
3. constructor 函数 只要 new 生成实例时,就会自动调用这个函数, 如果我们不写这个
函数,类也会自动生成这个函数
4. 多个函数方法之间不需要添加逗号分隔
5. 生成实例 new 不能省略
6. 语法规范, 创建类 类名后面不要加小括号,生成实例 类名后面加小括号, 构造函数不需
要加function
类的继承
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 父类
class Father{
constructor(){
}
money(){
console.log(100);
}
}

// 子类继承父类
class Son extends Father{
}
var son = new Son();
son.money();
super
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
// 子类使用super关键字访问父类的方法
class Father{
constructor(x,y){
this.x=x;
this.y=y;
}
sum(){
console.log(this.x+this.y);
}
}

class Son extends Father{
constructor(x,y){
super(x,y); // 调用父类的构造函数
}
}
var son = new Son(1,2);
son.sum();

// 使用父类的方法
class Father{
say(){
return '我是爸爸';
}
}
class Son extends Father{
say(){
console.log(super.say()+'的儿子');
}
}


注意:
1. 继承中,如果实例化子类输出一个方法,先看子类有没有这个方法,如果有就先执行子类的
2. 继承中,如果子类里面没有,就去查找父类有没有这个方法,如果有,就执行父类的这个方法(就近原则)
3. 如果子类想要继承父类的方法,同时在自己内部扩展自己的方法,利用super 调用父类的构造函数,super 必须在子类this之前调用
4. 时刻注意this的指向问题,类里面的共有的属性和方法一定要加this使用
1. constructor中的this指向的是new出来的实例对象
2. 自定义的方法,一般也指向的new出来的实例对象
3. 绑定事件之后this指向的就是触发事件的事件源
5.ES6中类没有变量提升,所以必须先定义类,才能通过类实例化对象

类里面的共有的属性和方法一定要加this使用。
字符串转节点添加
1
2
3
4
5
element.insertAdjacentHTML(position, text); // 把字符串解析成节点 插入DOM树指定位置
'beforebegin':元素自身的前面。
'afterbegin':插入元素内部的第一个子节点之前。
'beforeend':插入元素内部的最后一个子节点之后。
'afterend':元素自身的后面。
选中
1
select();
双击禁止选中文字
1
window.getSelection?window.getSelection().removeAllRanges():document.selection.empty();
静态成员和实例成员
1
2
3
4
5
// 实例成员就是构造函数内部通过this添加的成员 uname age sing 就是实例成员
// 实例成员只能通过实例化的对象来访问

// 静态成员 在构造函数本身上添加的成员
// 静态成员只能通过构造函数来访问
构造函数和原型

构造函数通过原型分配的函数是所有对象所共享的。

​ JavaScript 规定,每一个构造函数都有一个prototype 属性,指向另一个对象。注意这个 prototype就是一个对象,这个对象的所有属性和方法,都会被构造函数所拥有。 我们可以把那些不变的方法,直接定义在 prototype 对象上,这样所有对象的实例就可 以共享这些方法。

1
2
3
4
5
6
7
8
9
10
11
function Star(uname, age) {
this.uname = uname;
this.age = age;
}
Star.prototype.sing = function() {
console.log('我会唱歌');
}
var ldh = new Star('刘德华', 18);
var zxy = new Star('张学友', 19);
ldh.sing();//我会唱歌
zxy.sing();//我会唱歌
原型
1
2
3
4
5
6
7
8
9
10
11
12
所有对象都有一个__proto__(隐式原型)属性,属性值是一个普通的对象
所有函数都有一个prototype(原型)属性,属性值是一个普通的对象
所有对象的__proto__属性指向它构造函数的prototype

所以我们对象可以使用构造函数 prototype 原型对象的属性和方法,

共享方法
不必开辟新的空间

__proto__ // 浏览器帮我们写好的非标准的方法
// __proto__对象原型指向构造函数的原型对象 prototype
// __proto__对象原型和原型对象prototype是等价的
constructor 构造函数
1
2
// 构造器 指回构造函数本身
// 如果修改了原来的原型对象,赋值的是一个对象,则必须手动的利用constructor指回原来的构造函数
原型链
1
2
3
4
5
// 构造函数.prototype.__proto__ 指向Object的原型对象
// Object的原型对象.__proto__ 指向null


// 构造函数的原型对象===Object的实例对象
原型链查找规则
1
// 就近原则 没有往上找
原型对象的this指向
1
2
1. 构造函数中,this指向是实例对象
2. 原型对象里面的this指向的也是实例对象
扩展内置对象方法
1
2
3
4
5
6
7
8
9
10
Array.prototype.sum = function(){
var sum=0;
for(var i = 0 ;i<this.length;i++){
sum += this[i];
}
return sum;
}

var arr = [1,2,3]
console.log(arr.sum());
call方法
1
2
3
4
call();
1. // 可以调用函数 fn.call(); 借用 a.fn.call(b);
2. // 可以改变函数this指向 fn.call('参数'); 此时this就指向了参数
3. // 可以传参 fn.call('指向','实参','实参')
借用父构造函数继承属性
1
2
3
4
5
6
7
8
9
10
11
function Father(uname,age){
this.uname=uname;
this.age=age;
}
function Son(uname,age){
Father.call(this,uname,age);
}

// 子构造函数继承父构造函数
Son.prototype = new Father();
Son.prototype.constructor = Son;
类的本质
1
2
3
4
5
6
7
8
// 还是一个function  是构造函数的另外一种写法

// 类有原型对象prototype
// 类原型对象prototype里面有constructor指向类本身
// 类可以通过原型对象添加方法
// 类创建的实例对象有__proto__指向类的原型对象

// ES6的类其实就是语法糖 更便捷的写法
ES5新增方法
数组方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
array.forEach(function(value,index,array){

}) // 迭代(遍历) 数组 return true 也不会中止遍历


var newArr = array.filter(function(value,index,array){
// return value >= 20;
return value % 2 === 0;
}) // 筛选数组 return true 也不会中止遍历

var flag = array.some(function(value,index,array){
return value >= 20;
}) // 查找数组中是否有满足条件的元素 返回布尔值 return true 会中止遍历

var flag = array.every(function(value,index,array){
return value >= 20;
}) // 查找数组中元素是否都满足条件 返回布尔值

var flag = array.map(function(value,index,array){
return value + 1
}) // 迭代(遍历) 数组 处理 返回新数组

字符串方法
1
str.trim(); // 去除字符串两端的空格 返回新的字符串
对象方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Object.keys(obj); // 获取对象自身所有的属性 返回由属性名组成的数组
Object.values(obj); // 获取对象自身所有的属性值 返回由属性值组成的数组
Object.entries(obj); // 获取对象自身所有的键值对 返回由键值对组成的二维数组


// 数据劫持
Object.defineProperty // 设置或修改对象中的属性
Object.defineProperty(obj,'修改或新增的属性名',{
get:function(){}, // 在读取属性时调用的函数。默认值为undefined。
set:function(anotherVariable){}, // 在给属性赋值时调用的函数。默认值为undefined。anotherVariable是指给属性赋值时的值



value:修改或新增的属性的值 (默认undefined),
writable:true/false, // 如果值为false 是否允许修改属性值 (默认false)
enumerable: false, // 是否允许遍历 (默认false)
configurable: false // 属性是否可以被删除或是否可以再次修改特性 (默认false)
})
函数的定义和调用方式
1
2
var fn = new Function('a','b','console.log(a+b)');
f(1,2);
改变函数内部this指向
1
2
3
4
5
6
.call(obj,a,b) // 简单理解为调用函数,但是可以改变函数的this指向 应用场景: 经常做继承.

.apply(obj,[a,b]) // 参数是数组 应用场景: 经常跟数组有关系

.bind(obj,a,b) // bind() 方法不会调用函数,可以改变函数的this指向,返回是原函数改变this之后产生的新函数 应用场景:不调用函数,但是还想改变this指向

严格模式
1
2
3
4
1.消除了 Javascript 语法的一些不合理、不严谨之处,减少了一些怪异行为。
2.消除代码运行的一些不安全之处,保证代码运行的安全。
3.提高编译器效率,增加运行速度。
4.禁用了在 ECMAScript 的未来版本中可能会定义的一些语法,为未来新版本的Javascript 做好铺垫。比如一些保留字如:class,enum,export, extends, import, super 不能做变量名
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 为整个脚本开启严格模式
<script>
'use strict';
</script>
<script>
(function(){
'use strict';
})() ;
</script>

// 为某个函数开启严格模式
<script>
function(){
'use strict';
}
</script>

严格模式的变化
1
2
3
4
5
6
7
8
//	严格模式后 不能使用未声明的变量
// 严格模式 不允许删除变量
// 严格模式下 全局作用域中函数中的 this 是 undefined
// 严格模式下 如果 构造函数不加new调用, this 指向的是undefined 如果给他赋值则会报错.
// 严格模式下 定时器 this 还是指向 window

// 严格模式下 函数内不能出现重名的变量
// 严格模式下 函数不能在非函数代码块上声明(if等)
高阶函数
1
// 高阶函数是对其他函数进行操作的函数,它接收函数作为参数或将函数作为返回值输出。
闭包
1
2
3
4
5
// 闭包(closure)指有权访问另一个函数作用域中变量的函数。简单理解就是 ,一个作用域可以访问另外一个函数内部的局部变量。

// 作用:延伸变量的作用范围。

// 立即执行函数也称为小闭包
递归函数
1
2
3
// 如果一个函数在内部可以调用其本身,那么这个函数就是递归函数。简单理解:函数内部自己调用自己, 这个函数就是递归函数

// 防止栈溢出要加return条件
深浅拷贝
1
2
3
4
Object.assign(新对象,老对象) // 浅拷贝 复制不了复杂数据类型的真实数据 for in 循环

// 深拷贝 直接复制简单数据类型,发现复杂数据类型,先创建复杂数据类型然后把值放进去
// 对象转字符串转对象也可以做深拷贝 JSON.parse(JSON.stringify(obj))
正则表达式
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
30
31
32
33
34
35
36
37
38
39
40
41
42
var regexp = new RegExp(/123/);  // 使用RegExp对象创建
var rg = /123/; // 使用字面量创建
rg.test(str); // 检测是否符合正则表达式 返回布尔值

1. //
包含

2. 边界符 ^ $
^ 开头
$ 结尾

3. [] 限定 其中的一个
[-] 范围
[a-z] 26个英文字母(小写)
[a-zA-Z0-9_-] 26个英文字母(大小写)和数字和下划线
[^] 取反

4. 量词符 设定某个模式出现的次数
* // 大于等于0次
+ // 大于等于1次
? // 1或者0次
{x} // x次
{x,} // 大于等于x次 中间不要有空格
{,x} // 小于等于x次
{x,y} // 大于等于x,小于等于y次

5. () 表示优先级


6. 预定义类
\d // 相当于[0-9] 数字
\D // 相当于[^0-9] 非数字
\w // 相当于[A-Za-z0-9_] 大小写字母,数字下划线
\W // 相当于[^A-Za-z0-9_] 非大小写字母,数字下划线
\s // 相当于[\t\r\n\v\f] 空白
\S // 相当于[^\t\r\n\v\f] 非空白

7. 或者 |



// exec() 方法用于检索字符串中的正则表达式的匹配。
replace替换
1
2
3
4
5
str.replace('abc','baby')
str.replace(/abc/,'baby') // 替换第一个
str.replace(/abc/g,'baby') // 替换全部
str.replace(/abc/i,'baby') // 替换第一个忽略大小写
str.replace(/abc/gi,'baby') // 替换全部忽略大小写
其他
1
Object.create:用来创建对象,创建出来的对象的原型指向第一个形参