JS 的对象分类

223 阅读5分钟

引入

对象要分类吗?

1.正方形的故事

  1. 一个兄弟

let square = {
width: 5,
getArea(){
return this.width * this.width //面积
},
getLength(){
return this.width * 4 // 周长
}
}

预览

  1. 一打兄弟
let square = {
width: 5,
getArea(){
return this.width * this.width
},
getLength(){
return this.width * 4
}
}
let square2 = {
width: 6,
getArea(){
return this.width * this.width
},
getLength(){
return this.width * 4
}
}


预览

3.兄弟来的多,去接的车也多,资源很浪费。

如何解决呢? 那只租一辆车,来回接送吧。

let squareList = []
for(let i = 0; i<12; i++){ //循环语句
squareList[i] = {
width: 5,
getArea(){
return this.width * this.width
},
getLength(){
return this.width * 4
}
}
}

  1. 兄弟们有胖有瘦,怎么解决呢?
let squareList = []
let widthList =  [5,6,5,6,5,6,5,6,5,6,5,6] //规定了不同属性值
for (let i = 0; i <12; i++ ) {
    squareList[i] = {
        width: widthList[i],
        getArea(){
          return this.width * this.width  
        },
        getLength(){
            return this.width*4
        }
    }
}

预览

问题虽然解决了,但是资源还是很浪费

请看内存图

5.根本的解决办法——使用原型(将12个对象的共有属性放在原型里)

let squareList = []
let widthList = [5,6,5,6,5,6,5,6,5,6,5,6]
let squarePrototype = {              //原型
getArea(){
return this.width * this.width
},
getLength(){
return this.width * 4
}
}
for(let i = 0; i<12; i++){
squareList[i] = Object.create(squarePrototype)
squareList[i].width = widthList[i]
}

但是还是有些问题,square的代码太分散了。

6.解决分散的方法——用函数封装,然后调用函数

let squareList = []
let widthList = [5,6,5,6,5,6,5,6,5,6,5,6]
function createSquare(width){ // 此函数叫构造函数
let obj = Object.create(squarePrototype)
// squarePrototype为原型创建空对象
obj.width = width
return obj
}
let squarePrototype = {
getArea(){
return this.width * this.width
},
getLength(){
return this.width * 4
}
}
for(let i = 0; i<12; i++){
squareList[i] = createSquare(widthList[i])
// square
}

还是有些分散,最后一招:将原型和函数相结合!!

let squareList = []
let widthList = [5,6,5,6,5,6,5,6,5,6,5,6]
function createSquare(width){
let obj = Object.create(createSquare.squarePrototype) // 先定义后使用的原则不变
obj.width = width
return obj
}
createSquare.squarePrototype = { //
getArea(){
return this.width * this.width
},
getLength(){
return this.width * 4
},
constructor: createSquare //方便通过原型找到构造函数
}
for(let i = 0; i<12; i++){
squareList[i] = createSquare(widthList[i])
console.log(squareList[i].constructor)}
// constructor  可以知道是谁构造了这个对象:麻麻是谁?

预览

7.new 操作符

以上代码可以简化为下面的代码:

let squareList = []
let widthList = [5,6,5,6,5,6,5,6,5,6,5,6]
function Square(width){
    this.width = width
}
Square.prototype.getArea = function(){return this.width * this.width}
Square.prototype.getLength = function(){return this.width * 4}
for(let i=0;i<12;i++)
{squareList[i] = new Square(widthList[i])
    console.log(squareList[i].construtor)
}

预览:

new操作符做了哪些事?

  • 自动创建空对象
  • 自动为空对象关联原型,原型的地址指定为 X.prototype
  • 自动将空对象作为this关键字运行的构造函数
  • 自动 return this

补充

  1. 构造函数X:
  • X函数本身负责给对象本身添加属性
  • X.prototype对象负责保存对象的共有属性
  1. 代码规范
  • 大小写

所有的构造函数(专门用于创建对象的函数)首字母大写, 所有被构造出来的对象,首字母小写

  • 词性

new后面的函数,要用名词形式(new Person(5)) 其他函数一般使用动词开头(createSquare(5))

8. JS原型公式(宇宙最强)

对象.proto === 其构造函数.prototype

大白话:你是谁创造的,你的原型就是谁的prototype属性对应的对象

let obj = new Object() //原型就是Object.prototype

更多有关原型的知识

2.圆形和长方形的故事

圆形:

function Circle(radius){
this.radius = radius //元素的属性由正方形变换为圆形
}
Circle.prototype.getArea = function(){
return Math.pow(this.radius,2) * Math.PI
}
Circle.prototype.getLength = function(){
return this.radius * 2 * Math.PI
}
let circle = new Circle(5)
circle.radius
circle.getArea()
circle.getLength()

长方形:

function Rect(width, height){
this.width = width
this.height = height
}
Rect.prototype.getArea = function(){
return this.width * this.height
}
Rect.prototype.getLength = function(){
return (this.width + this.height) * 2
}
let react = new Rect(4,5)
rect.width
rect.height
rect.getArea()
rect.getLength()

我们回到了第一问题:对象要分类吗? 答案是确定的。

理由如下:

  1. 很多对象拥有的属性行为相同
  2. 将它们分为同一类
  3. square1 or square2
  4. 创建类似对象就很方便

另一种情况

  1. 有很多对象拥有其他属性和行为
  2. 需要不同的分类
  3. Square / Circle /Rect就是不同的分类
  4. Array 和 Function 也是不同分类
  5. Object 创建出来的对象,是最没特点的对象

9.类和类型

  1. 类型(prototype)
  • 类型是JS的数据分类,一共有7种
  • 四级两空一对象
  1. 类(class)
  • 是针对对象的分类,有无数种
  • 常见的有Array(数组)/Fuction(函数)/Date(日期)/RegEXP(正则表达式)

10.数组对象和函数对象初览

定义一个数组:

let arr = [1,2,3]
let arr = new Array(1,2,3)//元素为1,2,3
let arr = new Array(3) // 长度为3
注意属性名只有字符串

定义一个函数:

function fn(x,y){return x+y}
let fn2 = function fn(x,y){return x+y}
let fn = (x,y) => x+y
let fn = new Function ('x','y','returnx+y')

10. JS的终极一问

  • window是谁构造的?Window

  • window.Object是window.Function构造的
  • window.function是window.Function够早的(它是造物主

11.ES6新语法(class 一统天下)

预览地址

//正方形代码(class)
class Square{
static x = 1
width = 0
constructor(width){
this.width = width
}
getArea(){
return this.width * this.width
}
getLength(){
return this.width * 4
}
get area2(){ 
return this.width * this.width
}
}

//圆形代码(class)
class Circle{
constructor(radius){
this.radius = radius
}
getArea(){
return Math.pow(this.radius,2) * Math.PI
}
getLength(){
return this.radius * 2 * Math.PI
}
}
let circle = new Circle(5)
circle.radius
circle.getArea()
circle.getLength()

//长方形代码(class)
class Rect{
constructor(width, height){
this.width = width
this.height = height
}
getArea(){
return this.width * this.height
}
getLength(){
return (this.width + this.height) * 2
}
}
let react = new Rect(4,5)
rect.width
rect.height
rect.getArea()
rect.getLength()

总结

本文介绍了JS的对象分类,两种形式(类型、类)根据不同的场景进行选择使用,JS的唯一公式,能让你直接找到对象的原型,未完待续。。。