JS构造函数及相关原型问题

411 阅读2分钟

JS中有7种数据类型:Number String Symbol Boolean Null Undefined Object

前 6 种都是表达的特定事物

但我们可以通过第七种 Object 构造出 ‘类’ , 用来构造不同的东西

例如:我们可以构造一个 ‘人’ 对象,它可以包含prototype(共有属性),比如 肤色,发色,国籍等。

当我们需要创建一个特定的‘人’的时候,就可以调用那个类的共有属性来创建那个人

使用这种方法的好处就是可以省内存

图1

图2

我们可以看到,当使用 ‘类’ 时,我们名称创建一个对象只需要赋予其 name 就可以了,另一些可以被调用的共有属性只需要放在另一个地方,在需要时调用就可以了

若不使用 ‘类’ ,我们每次创建一个对象就要浪费内存去存放一些共同属性。如图2,但我们创建多个对象时,每次都要浪费内存去填写年龄,肤色等属性。


构造函数

我们可以通过构造函数去创建‘类’

完整写法(以求正方形面积,周长为例)

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

new 写法

let squareList = [];
let widthList = [5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6];

//第一部分,创建 类 ;相较于 完整写法 省略了创建prototype,并return
function Square(width) {
  this.width = width;
}

//第二部分 直接写prototype中的共有属性
Square.prototype.getArea = function () {
  return this.width * this.width;
};

Square.prototype.getLength = function () {
  return this.width * 4;
};

//第三部分 需要在创建对象时,在构造函数前加 new 且构造函数的第一给字母大写
for (let i = 0; i < 12; i++) {
  squareList[i] = new Square(widthList[i]);
}

ES6 class 写法

class Square {
  constructor(width) {
    this.width = width;
  }
  // 自身属性写在constructor中
  
  // 共有属性写在 constructor外
  getArea() {
    return this.width * this.width;
  }
  getLength() {
    return this.width * 4;
  }
}

for (let i = 0; i < 12; i++) {
  squareList[i] = new Square(widthList[i]);
}

class 写法的注意点

使用 getArea = function(){} 时,我们发现原型失效了,getArea 又跑到每个对象下面去了

而使用 getAre(){} 时,getArea 是在原型上的

所以使用class 语法时, 必须使用getArea(){} 这种写法!


一些特殊的原型相关问题

window是Window构造的

window.Object是window.Function构造的

window.Function是其自身构造的

Object.prototype 是一开始就存在的,不存在被谁创建的问题

Object.prototype.__proto__ 的 值为null