【JS】对象分类

381 阅读3分钟

类型是JS数据的分类:四基两空一对象

类是针对于对象的分类

一、对象的分类

1.数组对象

定义一个数组

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

数组对象的自身属性

  • '0'/'1'/'2'/'lenght'
  • 属性名没有数字,只有字符串 举例
Object.keys(a)

(3) ["0", "1", "2"]
0: "0"
1: "1"
2: "2"
length: 3
__proto__: Array(0)

数组对象的共有属性

  • 数组对象比正常对象多一层共有属性

  • push是推,即从最后添加元素并返回数组长度

  • pop是弹出,即从最后删除元素并返回弹出的属性值

  • shift是提档,从第一个删除并返回数组长度

  • unshift是降档,从第一个添加元素并返回数组新长度

  • join是联合,数组连起来成字符串了,并返回字符串

  • Array.prototype.concat(),合并数组,不会更改当前数组

  • MDN

2.函数对象

定义一个函数

  • function fn (x,y){retun x+y}
  • let fn2 = function fn(x,y){retun x+y}
  • let fn = (x,y)=> x+y
  • let fn = new Function('x','y','retun x+y') 函数对象的自身属性
  • 'name'/'length' 函数对象的共有属性
  • 'call'/'apply'/'bind

二、window(JS终极一问)

window是谁构造的

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

window.Object是谁构造的

  • window.Function
  • 所有函数有window.Function

window.Function由谁创造

  • window.Function
  • 浏览器构造了Function,指定构造者是自己

三、函数和原型结合(new操作符)

计算正方形周长面积代码优化

函数与原型结合

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

每个js函数有prototype属性,每个prototype属性里面存在constructor

当我们使用new X()时,自动做了四件事

  • 自动创建空对象
  • 自动将空对象关联原型,原型地址指定为X.prototype
  • 自动将空对象作为this关键字运行构造函数
  • 自动return this 构造函数X做了哪2件事
  • X函数给自己添加自身属性
  • X.prototype对用于保存对象的共有属性
function Dog(name){this.name=name,this.color='yellow',this.gender='女'};

Dog.prototype.run=function(){console.log('跑起来')};

Dog.prototype.say=function(){console.log('汪汪')};

let dog3=new Dog('小花')

代码规范:

大小写:

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

  • 所有被构造出来的对象,首字母小写

词性:

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

公式

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

对象.__proto__===其构造函数的.prototype

举例

let x={}

let x = {}原型是什么:Object.Prototype 内存图

参考资料:

JS 中 __proto__prototype存在的意义是什么?

四、代码分类

为什么需要分类

理由一

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

理由二

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

五、class(类)

原型方法实现

构造函数,再用this加自身即新对象属性,对原型加共有属性,常为函数

function Person(name,age){
    this.name=name
    this.age=age
}
Person.prototype.sayHi=function(){
    console.log('你好,我叫'+this.name)
}
let person = new Person('frank', 18)
person.name === 'frank' // true
person.age === 18 // true
person.sayHi() // 打印出「你好,我叫 frank」

let person2 = new Person('jack', 19)
person2.name === 'jack' // true
person2.age === 19 // true
person2.sayHi() // 打印出「你好,我叫 jack

Class方法实现

相对于原型方法,直接在constructor里加自身属性,在函数外创建函数对象

class Person{
    constructor(name, age){
        this.name = name
        this.age = age
    }
    sayHi(){
        console.log('你好,我叫'+this.name)
    }
}
let person = new Person('frank', 18)
person.name === 'frank' // true
person.age === 18 // true
person.sayHi() // 打印出「你好,我叫 frank」

let person2 = new Person('jack', 19)
person2.name === 'jack' // true
person2.age === 19 // true
person2.sayHi() // 打印出「你好,我叫 jack」

ES6新语法资料:

ES 6 新特性列表