饥人谷技术博客

JS创建对象

2021-02-10  本文已影响0人  茜Akane

Get Started

• 用prototype来创建对象
• 用class类来创建对象

输出12个正方形的面积和周长

• 方法:用for循环
• 问题:要创建12个对象,每个还要带2个函数当做属性,占用太多内存了
• 改进:将两个函数添加进对象的原型里,共用同一块内存
• 代码:

    let squareList = []
    let widthList = [1,2,3,4,5,6,7,8,9,10,11,12]
    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]
    }


• 改进:还可以更加精简,将代码抽离到一个函数再调用
• 代码:

    let squareList = []
    let widthList = [1,2,3,4,5,6,7,8,9,10,11,12]
    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])
    }

构造函数:构造函数就是可以构造对象的函数。
封装:将逻辑细节写到一个函数里面,只需要调用传参,叫做封装。

• 改进:squarePrototype原型和createSquare函数还是分散的
• 代码:

    let squareList = []
    let widthList = [1,2,3,4,5,6,7,8,9,10,11,12]
    
    function createSquare(width){  //构造函数
      let obj = Object.create(createSquare.squarePrototype )
      // 以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可以知道谁构造了这个对象
    }

注意:代码上先是定义了createSquare函数,然后给函数增加了新的属性。
当createSquare函数被调用时,将自身的squarePrototype属性指定为obj的原型,
再将obj返回赋值给目标对象。

new操作符

• 代码再优化,用new

    let squareList = []
    let widthList = [1,2,3,4,5,6,7,8,9,10,11,12]
    
    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属性,每个prototype都有constructor属性。

总结

• new X() 操作其实自动帮我们做了很多事情,这些事情包括
自动创建一个空对象
自动将该空对象的原型(_proto_)指向 X.prototype(即将 X.prototype 保存的地址复制到空对象._proto_ 里)
自动将空对象作为 this 来运行构造函数
自动 return this
• 构造函数X
X函数本身负责给对象本身添加属性
X.prototype对象负责保护对象的共用属性

代码规范

• 大小写
所有构造函数(专门用于创建对象的函数)首字母大写
所有被构造出来的对象,首字母小写
• 词性
new后面的函数,使用名词形式
如new Person(),new Object()
其他函数一般使用动词开头
如createsquare(5),createElemnet('div')

JS重要公式,也是唯一一个公式

对象.proto = 其构造函数.prototype
注意:window.object是函数对象

Circle

• 代码

fucntion 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()

类型V.S.类

• 类型
类型是JS数据的分类,有七种
四基两空一对象
• 类
类的针对于对象的分类,有无数种
常见的有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'
用法都在MDN

函数对象

• 定义一个函数

function fn(x, y){return x+y}
let fn2 = hunction 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构造的

函数都有prototype属性

如果一个对象不是函数,那么这个对象一般来说没有 prototype 属性,但这个对象一般一定会有 _proto_ 属性

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重写Circle

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()
上一篇下一篇

猜你喜欢

热点阅读