JavaScript创建对象简单方式到优化

上一篇内容我们学习了JavaScript面向对象的开发思想如何掌握JavaScript面向对象开发相关模式?:下面开始我们今天的学习内容。
 

一、JavaScript创建对象简单方式

我们可以直接通过 `new Object()` 创建:

var person = new Object()
person.name = 'Jack'
person.age = 18

person.sayName = function () {
  console.log(this.name)
}

每次创建通过 `new Object()` 比较麻烦,所以可以通过它的简写形式对象字面量来创建:

var person = {
  name: 'Jack',
  age: 18,
  sayName: function () {
    console.log(this.name)
  }
}

对于上面的写法固然没有问题,但是假如我们要生成两个 `person` 实例对象呢?

var person1 = {
  name: 'Jack',
  age: 18,
  sayName: function () {
    console.log(this.name)
  }
}

var person2 = {
  name: 'Mike',
  age: 16,
  sayName: function () {
    console.log(this.name)
  }
}

通过上面的代码我们不难看出,这样写的代码太过冗余,重复性太高。

二、简单方式的改进:工厂函数

我们可以写一个函数,解决代码重复问题:

function createPerson (name, age) {
  return {
    name: name,
    age: age,
    sayName: function () {
      console.log(this.name)
    }
  }
}

然后生成实例对象:

var p1 = createPerson('Jack', 18)
var p2 = createPerson('Mike', 18)

这样封装确实爽多了,通过工厂模式我们解决了创建多个相似对象代码冗余的问题,

但却没有解决对象识别的问题(即怎样知道一个对象的类型)。

三、构造函数

内容引导:

  • - 构造函数语法
  • - 分析构造函数
  • - 构造函数和实例对象的关系
  • + 实例的 constructor 属性
  • + instanceof 操作符
  • - 普通函数调用和构造函数调用的区别
  • - 构造函数的返回值
  • - 构造函数的问题

四、更优雅的工厂函数:构造函数

一种更优雅的工厂函数就是下面这样,构造函数:

function Person (name, age) {
  this.name = name
  this.age = age
  this.sayName = function () {
    console.log(this.name)
  }
}

var p1 = new Person('Jack', 18)
p1.sayName() // => Jack

var p2 = new Person('Mike', 23)
p2.sayName() // => Mike

五、解析构造函数代码的执行

在上面的示例中,`Person()` 函数取代了 `createPerson()` 函数,但是实现效果是一样的。

这是为什么呢?

我们注意到,`Person()` 中的代码与 `createPerson()` 有以下几点不同之处:

- 没有显示的创建对象

- 直接将属性和方法赋给了 `this` 对象

- 没有 `return` 语句

- 函数名使用的是大写的 `Person`

而要创建 `Person` 实例,则必须使用 `new` 操作符。

以这种方式调用构造函数会经历以下 4 个步骤:

1. 创建一个新对象

2. 将构造函数的作用域赋给新对象(因此 this 就指向了这个新对象)

3. 执行构造函数中的代码

4. 返回新对象

下面是具体的伪代码:

function Person (name, age) {
  // 当使用 new 操作符调用 Person() 的时候,实际上这里会先创建一个对象
  // var instance = {}
  // 然后让内部的 this 指向 instance 对象
  // this = instance
  // 接下来所有针对 this 的操作实际上操作的就是 instance

  this.name = name
  this.age = age
  this.sayName = function () {
    console.log(this.name)
  }

  // 在函数的结尾处会将 this 返回,也就是 instance
  // return this
}

六、构造函数和实例对象的关系

使用构造函数的好处不仅仅在于代码的简洁性,更重要的是我们可以识别对象的具体类型了。

在每一个实例对象中同时有一个 `constructor` 属性,该属性指向创建该实例的构造函数:

console.log(p1.constructor === Person) // => true
console.log(p2.constructor === Person) // => true
console.log(p1.constructor === p2.constructor) // => true

对象的 `constructor` 属性最初是用来标识对象类型的,

但是,如果要检测对象的类型,还是使用 `instanceof` 操作符更可靠一些:

console.log(p1 instanceof Person) // => true
console.log(p2 instanceof Person) // => true

总结:

- 构造函数是根据具体的事物抽象出来的抽象模板

- 实例对象是根据抽象的构造函数模板得到的具体实例对象

- 每一个实例对象都具有一个 `constructor` 属性,指向创建该实例的构造函数

+ 注意: `constructor` 是实例的属性的说法不严谨,具体后面的原型会讲到

- 可以通过实例的 `constructor` 属性判断实例和构造函数之间的关系

+ 注意:这种方式不严谨,推荐使用 `instanceof` 操作符,后面学原型会解释为什么

更多前端内容尽在前端专栏哦,关注再学,好方便~


2022年前端学习路线图:课程、源码、笔记,技术栈
欢迎小伙伴们留言哦,期待看到大家的进步。另外此线路图实时更新!需要课后资料的友友们,可以直接告诉我。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值