对象分类
我们知道,js有7种数据类型,分别是四基两空一对象。
那么对象能不能分类?
js中,我们可以把拥有相同属性和方法的对象归为一类。
例如:数组对象,日期对象。都同属于一类
从数组对象讲起
数组的定义:
* let arr=[1,2,3]//字面量创建一个数组
* let arr =new Array(1,2,3)//利用构造函数创建数组
* let arr =new Array(3)//创建的是一个length为3的数组
我们可以打印一下数组

可以看到数组的自有属性有:下标(keys)、value值、length
这里的下标keys是字符串噢
数组内包含__proto__,里面实际上保存的是这个数组的构造函数的原型地址,也就是Array的prototype

我们可以得出一个公式:
对象的__proto__ ===其构造函数的prototype
举例就是:
let obj={};//字面量创建一个对象
//相当于 let obj = new Object();
obj.__proto__ === Object.prototype //true
对象的__proto__和Object.prototype都保存着原型的地址。这个内存图曾经画过。
那么,如果要把对象分类,这个类里面需要跟数组对象一样,拥有属于自己的属性和属于自己的公共属性才行吧。
构造函数
在ES6之前,我们都用构造函数来创建类,例如我们需要创建一个正方形类,我们知道所有正方形都有自己的宽,也可以计算自己的周长。
//利用构造函数创建一个正方形类
function Fang(width){
this.width = width
this.getLength=()=>{
return this.width * 4
}
}
let rect = new Fang(5)//new 一个正方形,宽5
我们可以使用构造函数来分一个正方形类,然后利用new来创建一个对象。
rect.__proto__ === Fang.prototype
使用公式还是可以得出构造函数new出来的对象rect跟构造函数Fang有一个原型地址,打印出来看看

constructor,还有这个原型的__proto__
constructor里面记录的是构造这个原型的是谁,也就是通过constructor可以查到谁是这个原型的妈妈。
__proto__里面的地址指向的是Object.prototype
只要是创建了函数,都会默认产生prototype和constructor。
其他对象都没有。
prototype里面可以存什么
构造函数每次构造一个函数,都会把自身的属性和方法都赋给这个对象,这样会很浪费内存。
我们知道,prototype里面可以保存共有的属性和方法,那么我们可以往这里面保存共有的属性和方法,达到节省内存的作用。
所以写法就变成了
function Fang(width){
this.width = width
}
Fang.prototype.getLength=()=>{
return this.width * 4
}
当然,你也可以为了简化代码,直接覆盖原来的原型,但是,请不要忘记constructor。
Fang.prototype={
constructor:Fang //覆盖原来的原型,这里要指回构造函数
getLength:()=>{
return this.width * 4
}
}
ES6带来的新语法
class Fang{
constructor(width){//构造函数中填写属性相关
this.width=width
}
getLength(){
return this.width * 4
}
}
new做了什么?
利用new创建对象后,主要做了以下工作:
- 创建一个空对象
- 自动return this
- 自动将空对象作为this来运行函数
- 为空对象关联一个原型地址,是其构造函数的
prototype
再来说说代码规范
1、所有类名请使用名词
2、所有共有的方法请使用动词
3、类名首字母大写
4、构造出来的对象首字母小写
总结一下
-
我们可以使用构造函数或者class来创建一个类。
-
如果使用构造函数,可以把共有的属性和方法都放入
prototype里 -
所有函数创建出来都有自己的prototype,里面有一个constructor指向函数本身。
-
利用new出来的对象的
__proto__===其构造函数的prototype -
代码规范
拓展一下
window是从哪里来的?
来自于Window()
Object是从哪里来的?
来自于Function()
js中,所有函数都是通过Function构造函数new出来的。可以使用constructor来查看构造者。