为什么对象要分类?
举例
//正方形:边长、面积、周长
let zhengfangxing = {
witdh:5,
getArea(){
return this.witdh * this.witdh;
},
getZhouChang(){
return this.witdh * 4;
}
}
//新手写法,多个正方形
let zhengfangxing2 = {
witdh:4,
getArea(){
return this.witdh * this.witdh;
},
getZhouChang(){
return this.witdh * 4;
}
}
//...
//代码优化 for循环,宽度固定为4
let zhengfangxing = [];
for(let i = 0; i < 5; i++){
zhengfangxing[i] = {
witdh:4,
getArea(){
return this.witdh * this.witdh;
},
getZhouChang(){
return this.witdh * 4;
}
}
}
//继续代码优化,浪费内存
let zfx = [];
let widthList = [5,6,5,6,5];
for(let i = 0; i < 5; i++){
zfx[i] = {
witdh:widthList[i],
getArea(){
return this.witdh * this.witdh;
},
getZhouChang(){
return this.witdh * 4;
}
}
}
内存图如下:
从内存图中,可以发现10个函数重复
//优化代码,借助原型,有一定优化,但是代码分散
let zxf = [];
let widthList = [5,6,5,6,5];
let zxfPrototype = {
getArea(){
return this.witdh * this.witdh;
},
getZhouChang(){
return this.witdh * 4;
}
}
for(let i = 0; i < 5; i++){
zfx[i] = Object.create(zxfPrototype);
zfx[i].witdh = widthList[i];
}
//继续优化代码 抽离到函数
let zfx = [];
let widthList = [5,6,5,6,5];
let zxfPrototype = {
getArea(){
return this.witdh * this.witdh;
},
getZhouChang(){
return this.witdh * 4;
}
}
function createZfx(width){
let obj = Object.create(zxfPrototype);
obj.width = width;
return obj;
}
for(let i = 0; i < 5; i++){
zfx[i] = createZfx( widthList[i]);
}
//继续代码优化,上面原型和抽离函数还是分散
let zfx = [];
let widthList = [5,6,5,6,5];
function createZfx(width){
let obj = Object.create(zxfPrototype);
obj.width = width;
return obj;
}
createZfx.zxfPrototype = {
getArea(){
return this.witdh * this.witdh;
},
getZhouChang(){
return this.witdh * 4;
},
constructor:createZfx
}
for(let i = 0; i < 5; i++){
zfx[i] = createZfx( widthList[i]);
}
//最后优化,函数和原型结合,用new。(重写)
let zfxList = [];
let widthList = [5,6,5,6,5];
function zfx(witdh){
this.witdh = width;
}
zfx.prototype.getArea = function(){
return this.witdh * this.witdh;
}
zfx.prototype.getZhouChang = function(){
return this.witdh * 4;
}
for(let i = 0; i < 5; i++){
zfxList[i] = new zfx(widthList[i]);
}
总结
- new Obj()自动做了四件事
- 自动创建空对象
- 自动为空对象关联原型,原型地址指定为Obj.prototype
- 自动将空对象作为this关键字运行构造函数
- 自动返回this
- 构造函数 Obj
- Obj函数本身负责给对象本身添加属性
- Obj.prototype对象负责保存对象的共有属性
JS里面唯一的一个公式
- let Obj = new Object()的原型是Object.prototype
- let arr = new Array()的原型是Array.prototype
- let zfx = new zfx()的原型是zfx.prototype
- let fn = new Function()的原型是Function.prototype
- 因此:你是谁构造的,你的原型就是谁的prototype属性对应的对象
- 原型公式:对象.proto===其构造函数.prototype
- JS 中 proto 和 prototype 存在的意义是什么?
通过以上代码和总结可以知道构造函数、prototype、new
对象分类的理由
- 有很多对象拥有一样的属性和行为
- 需要把它们归为同一类
- 但也有很多对象拥有其他的属性和行为
- 所以需要不同的分类
- Object创建出来的对象,是最没有特点的对象
class语法引入
class Square{
static x = 1;
width = 0;
constructor(width){
this.width = this.width;
}
getArea(){
return this.width * this.width;
}
getZhouChang(){
return this.width * 4;
}
get area2(){
return this.width * this.width;
}
}