js创建对象的方式

1. 工厂模式

function createPerson() {
  this.name = "xiaohong";
  this.getName = function () {
    console.log(this.name);
  };
}

var person1 = createPerson();
// 优点:简单
// 缺点:对象无法识别,因为所有的实例都指向同一个原型

2. 构造函数

function Person() {
  this.name = "xiaohong";
  this.getName = function () {
    console.log(this.name);
  };
}

var person = new Person();
// 优点: 实例可以识别为一个特定的类型
// 缺点: 每次创建实例时,构造函数内的方法都要被创建一次
// 优化
function getName() {
  console.log(this.name);
}
function Person(name) {
  this.name = name;
  this.getName = getName;
}
var person = new Person("xiaoming");

3. 原型模式

function Person() {}
Person.prototype.name = "xiaoming";
Person.prototype.getName = function () {
  console.log(this.name);
};
var person = new Person();

// 优点:方法不会重建
// 缺点:所有的属性和方法都共享;不能初始化参数
// 优化1:
function Person() {}

Person.prototype = {
  name: "xiaoming",
  getName: function () {
    console.log(this.name);
  },
};

var person = new Person();
// 优点:封装清晰点
// 缺点:重写了原型,丢失了constructor属性
// 优化2:
function Person() {}
Person.prototype = {
  constructor: Person,
  name: "xiaoming",
  getName: function () {
    console.log(this.name);
  },
};

var person = new Person();
// 优点:实例可以通过实例.prototype.constructor找到构造函数
// 缺点:所有的属性和方法共享;不能初始化参数

4. 组合模式

function Person() {
  this.name = "xiaohong";
}

Person.prototype = {
  constructor: Person,
  getName: function () {
    console.log(this.name);
  },
};

var person1 = new Person();
// 优点:该共享的共享,该私有的私有,使用最广泛的方式;
// 缺点:希望写在一个地方,即更好的封装性;

5. 动态原型模式

function Person() {
  this.name = "xiaohong";
  if (typeof this.getName !== "function") {
    Person.prototype.getName = function () {
      console.log(this.name);
    };
  }
}
var person = new Person();

注意:使用动态原型模式时,不能用对象字面量重写原型

function Person(name) {
  this.name = name;
  if (typeof this.getName !== "function") {
    // 字面量
    Person.prototype = {
      constructor: Person,
      getName: function () {
        console.log(this.name);
      },
    };
  }
}
var person1 = new Person("xiaohong");
// console.log(person1.__proto__ === Person.prototype);
var person2 = new Person("xiaoming");
// console.log(person2.__proto__ === Person.prototype);

person1.getName(); // 报错
person2.getName(); // 注释掉上面一个,下面一个个执行
  • 注意这个时候,回顾下 apply 的实现步骤,会执行 obj.Person 方法,这个时候就会执行 if 语句里的内容,注意此时实例的原型指向构造函数的 prototype 属性(是字面量覆盖前的prototype),使用字面量方式直接覆盖 Person.prototype,并不会更改实例的原型的值,person1 依然是指向了以前的原型,而不是 覆盖后的Person.prototype。而之前的原型是没有 getName 方法的,所以就报错了。
  • 生成person2实例的时候,Person.prototype已经覆盖了原Person.prototype,所以可以获取到
  • 使用字面量的解决方案
function Person(name) {
  this.name = name;
  if (typeof this.getName !== "function") {
    // 字面量
    Person.prototype = {
      constructor: Person,
      getName: function () {
        console.log(this.name);
      },
    };
    return new Person(name); // __proto__原型继承
  }
}
var person1 = new Person("xiaohong");
// console.log(person1.__proto__ === Person.prototype);
var person2 = new Person("xiaoming");
// console.log(person2.__proto__ === Person.prototype);

person1.getName(); // 报错
person2.getName(); // 注释掉上面一个,下面一个个执行
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值