JS 对象分类

芝麻凛 2021年08月16日 109次浏览

JS 对象分类

对象需要分类吗?

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
    }
  }
}

上面的代码浪费了内存,以下是内存图
image20210818195649291.png

函数与原型的结合

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) // 先使用后定义?NO
  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 可以知道谁构造了这个对象:你妈是谁?
}

构造函数,就是可以构造出对象的函数。

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].constructor)
}
// 每个函数都有 prototype 属性,这是 JS 之父故意的
// 每个 prototype 都有 constructor 属性,也是故意的

总结

new X() 自动做了四件事情

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

构造函数

  • X 函数本身赋值给对象添加属性
  • X.prototype 对象负责保存对象的共用属性

代码规范

大小写

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

词性

  • new 后面的函数,使用名词形式
  • 如 new Person() 、new Object()
  • 其他函数,一般使用动词开头
  • 如 createSquare(5)、createElement('div')

如何确定一个对象的原型

为什么

  • let obj = new Object() 的原型是 Object.prototype
  • let arr = new Array() 的原型是Array.prototype
  • let square = new Square() 的原型是 Square.prototype
  • let fn = new Function() 的原型是 Function.prototype

因为 new 操作故意这么做的

  • 把原型地址 指定为 x.prototype,new的是什么就指定了谁

你是谁构造的,你的原型就是谁的prototype属性对应的对象。

原型公式:对象.proto == 其构造函数.prototype

需要分类

理由一

  • 有很多对象拥有一样的属性和行为
  • 需要把他们分为同一类
  • 如square1 和 square2
  • 这样创建类似对象的时候就很方便

理由二

  • 但是还有很多对象拥有其他的属性和行为
  • 所以就需要不同的分类
  • 比如 Square / Circle / Rect 就是不同的分类
  • Array / Function 也是不同的分类
  • 而Object 创建出来的对象,是最没特点的对象

类型 VS 类

类型

  • 类型是JavaScript数据的分类,有7种
  • 四基两空一对象

  • 类是针对于对象的分类,有无数种
  • 常见的有Array、Function、Date、RegExp等

数组对象

定义一个数组

  • let arr = [1,2,3]
  • let arr = new Array(1,2,3) //元素1,2,3
  • let arr = new Array(3) /长度为3

数组对象的自身属性

  • '0' / '1' / '2' / 'length'
  • 注意,属性名没有数字,只有字符串

数组对象的共用属性

  • 'push' / 'pop' / 'shift' / 'unshift' / 'join'

函数对象

定义一个函数

  • 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','return x+y')

函数对象自身属性

  • 'name' / 'length'

函数对象共用属性

  • 'call' / 'apply' / 'bind‘

JS终极一问

window是谁构造的

  • Window
  • 可以通过 constructor 属性看出构造者

window.Object 是谁构造的

  • window.Function
  • 因为所有的函数都是window.Function 构造的

window.Function 是谁构造的

  • window.Function
  • 因为所有的函数都是window.Function 构造的
  • 浏览器构造了Function,然后指定它的构造者是自己

ES6语法

class Square{
	constructor(width){
		this.width = width
	}
	getArea(){
		return this.width * this.width
	}
}

class语法引入了更多概念

class Square{
	static x = 1
	width = 0
	constructor(width){
		this.width = width
	}
	getArea(){
		return this.width * this.width
	}
	get area2(){ //只读属性
		return this.width * this.width	
	}
}