- 面向对象: 是一种编程思想;OOP; java c++ php python JS 类的'继承 封装 多态'
- 面向过程:也是一种编程思想
比如 类(类型) 实例(具体的某个东西)
人类 马云
动物类 人类
猴类 孙悟空
JS中的内置类:'Array数组类 []
String字符串类 ''
Number数字类 NaN
Boolean布尔类 true false
Object基类 {}
Function函数类 function(){}
... ...
创建实例的两种方式
var ary =['1','2'] //字面量的方式创建的数组类的实例
var ary2=new Array('1','2') //构造函数的方式创建的数组类的实例 new出来的都是引用数据类型
var ary3=new Array(10) //参数只有一个数字的时候 数字代表数组的长度
JS中常见的设计模式
- 单例模式
- 工厂模式
- 构造函数模式
- 原型模式
单例模式
单例模式就是一个对象;可以避免命名冲突的问题;对象名 我们也称为命名空间 可以用来封装一些函数库
var name = '小明'
var age = 10
var sex = '男'
var eat = function(){}
var play = function(){}
var per1 = function(){
name:'小明'
age : 10
sex : '男'
eat : function(){}
play : function(){}
}
var per2 = function(){
name:'小红'
age : 15
sex : '女'
eat : function(){}
play : function(){}
}
高级单例模式:也是一个对象; 只是由一个函数返回了一个单例; 可以用来模块化开发
function fn(){
var name = '小明'
var age = 10
function init(){
console.log(name,age)
}
return {
init
}
}
//再来看这道题
var obj2 = (function(){
var name = 222;
var age = 333;
function f(){
console.log(name,age)
}
function changeAge(n){
age = n;
}
return {
name,
age,
f,
changeAge
}
})()
obj2.name = 666;
obj2.changeAge(100)
obj2.f() // 222 100
console.log(obj2.name,obj2.age)// 666 333
工厂模式
工厂模式: 多用于创建多个含有相同属性,和方法的对象,避免代码的重复编写; 批量产生单例
function factory(name,age,sex){
var obj={
name,age,sex,
eat(){
}
play(){
}
}
}
var par=factory('小明',10,1)
构造函数模式
构造函数模式:一般用来写一些插件
function Person(name,age,sex){
this.name=name
this.age=age
this.sex=sex
this.eat=function(){}
this.play=function(){}
}
var per1 = new Person('小明',100,0) //per1是Person的一个实例
//new 执行函数的时候,开辟作用域 形参赋值 变量提升;然后把函数中的this 指向了一个新开辟的堆内存,在这之后,再去操作this的时候,其实就是在造作这个堆内存最后把 this 返出去;
//若写了返回值 但是返回的是一个值类型 那么默认返回值仍然是this 若返回的是引用数据类型 则返回值会默认的返回值换掉
//es6的箭头函数是不能通过new的方式执行
//es6 创造类的方式 是通过class创造的
class fn3{
constructor(name,age){
this.name=name
this.age=age
}
}
var f3 = new fn3('小明',100)
原型模式
原型模式 : 在构造函数的基础上加一个原型(prototype)的概念
function Person(name='小明',age=10,sex=1){
this.name=name
this.age=age
this.sex=sex
}
Person.prototype.eat=function(){
console.log('吃')
}
Person.prototype.play=function(){
console.log('玩')
}
var p1 = new Person()
var p2 = new Person()
console.log(p1,p2) //p1.eat===p2.eat p1.play===p2.play
//es6的写法
class Fn{
constructor(name,age){
this.name=name
this.age=age
}
//只能写函数 只能写简写 中间不能有标点符号
eat(){}
play(){}
}
//Fn 只能通过 new 的方式执行
var f =new Fn()
原型链
原型链:是属性的查找机制,现在自己身上查找,没有的话 通过__proyo__再去所属类的原型上查找,若所属类的原型上也没有该属性,则通过该原型的__proto__再去原型所属类的原型上接着查找,直到找到基类的原型上,在没有的话 就是undefined
原型重构
原型重构:只针对自定义类
缺点是原型重构身上没有constructor;解决方法:自己手动补一个constructor的指向
例题:
function Person(name,age) {
this.name = name;
this.age = age;
}
Person.prototype.eat = function(){
console.log('吃火锅')
}
var p = new Person('小红',100);
Person.prototype = {
constructor:Person,
eat(){
console.log('吃水果')
},
play(){
console.log('玩游戏')
}
}
var p1 =new Person('小明',20);
p1.eat() //吃水果
p.eat(); //吃火锅
对于原型图的三句话
-
每一个函数(类)都有一个默认的prototype指向自己的原型对象
-
每一个实例(对象)都有一个__proto__的属性 指向所属类的原型对象
-
每一个默认的原型对象上 都有一个constructor属性指向对应的构造函数本身
如图所示👇