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
}
}
}
上面的代码浪费了内存,以下是内存图
函数与原型的结合
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
}
}