javascript构造函数的作用(构造函数的八种方法)

javascript构造函数的作用(构造函数的八种方法)JavaScript的学习,其实更多的就是面向对象编程,这就要求了我们要更好的处理对象对象是键/值对。创建对象的最常用方法是使用花括号{},并使用点表示法向对象添加属性和方法。let animal = {}animal.name = ‘Leo’animal.energy = 10animal.eat = function (amount) { console.log(`${this.name} is eating.`) this.energy = amount}animal.sleep = function (length) { console.log(`${this.name} is sleeping.`) this.energy = length}animal.play = function (length) { console.log(`${this.name} is playing.`) this.energy -= length}当我们要创建多个animal时,就需要做逻辑封装,也就是函数实例化,而函数本身是一个构造函数,所以函数负责构造一个新对象,也就是大家经常说的自己new一个对象。函数的实例化function Animal (name, energy) { let animal = {} animal.name = name animal.energy = energy animal.eat = function (amount) { console.log(`${this.name} is eating.`) this.energy = amount } animal.sleep = function (length) { console.log(`${this.name} is sleeping.`) this.energy = length } animal.play = function (length) { console.log(`${this.name} is playing.`) this.energy -= length} return animal}const leo = Animal(‘Leo’, 4)const snoop = Animal(‘Snoop’, 8)

就上面来看,我们就创建一个新的animal(也就是创建一个新的“实例”),需要调用的时候就是调用现在的 Animal 函数,传入参数:name和energy。

但是,这种模式真的好吗?

最大的一个缺点和我们试图解决的问题与函数里面的三个方法有关 -eat,sleep和play。这些方法中的每一种都不仅是动态的,而且它们也是完全通用的。这意味着,我们没有理由像现在一样,在创造新animal的时候重新创建这些方法。我们只是在浪费内存,让每一个新建的对象都比实际需要的还大。

接下来我们就来解决这个问题,函数实例化与共享方法。

函数实例化与共享方法const animalMethods = { eat(amount) { console.log(`${this.name} is eating.`) this.energy = amount }, sleep(length) { console.log(`${this.name} is sleeping.`) this.energy = length }, play(length) { console.log(`${this.name} is playing.`) this.energy -= length }}function Animal (name, energy) { let animal = {} animal.name = name animal.energy = energy animal.eat = animalMethods.eat animal.sleep = animalMethods.sleepanimal.play=animalMethods.play return animal}const leo = Animal(‘Leo’, 4)const snoop = Animal(‘Snoop’, 5)

通过将共享方法移动到它们自己的对象并在Animal函数中引用该对象,我们现在已经解决了内存浪费和新对象体积过大的问题。

Object.create

让我们再次使用Object.create改进我们的例子。简单地说,Object.create 允许你创建一个对象,该对象将在失败的查找中委托给另一个对象。换句话说,Object.create允许你创建一个对象,只要该对象上的属性查找失败,它就可以查询另一个对象以查看该另一个对象是否具有该属性。我们来看一些代码:

const parent = { name: ‘Stacey’, age: 32, heritage: ‘Irish’}const child = Object.create(parent)child.name = ‘Ryan’child.age = 5console.log(child.name) // Ryanconsole.log(child.age) // 5console.log(child.heritage) // Irish因此,在上面的示例中,由于 child 是用 object.create(parent)创建的,所以每当child 对象上的属性查找失败时,JavaScript 就会将该查找委托给 parent 对象。这意味着即使 child 没有属性 heritage ,当你打印 child.heritage 时,它会从 parent 对象中找到对应 heritage 并打印出来。现在如何使用 Object.create 来简化之前的 Animal代码?好吧,我们可以使用Object.create 来委托给animalMethods对象,而不是像我们现在一样逐一向 animal 添加所有共享方法。为了B 格一点,就叫做使用共享方法 和 Object.create 的函数实例化。使用共享方法 和 Object.create 的函数实例化const animalMethods = { eat(amount) { console.log(`${this.name} is eating.`) this.energy = amount }, sleep(length) { console.log(`${this.name} is sleeping.`) this.energy = length }, play(length) { console.log(`${this.name} is playing.`) this.energy -= length }}function Animal (name, energy) { let animal = Object.create(animalMethods) animal.name = name animal.energy = energy return animal}const leo = Animal(‘Leo’, 3)const snoop = Animal(‘Snoop’, 4)leo.eat(6)snoop.play(9)

以现在当我们调用leo.eat时,JavaScript 将在leo对象上查找eat方法,因为leo 中没有 eat 方法,所以查找将失败,由于 Object.create,它将委托给animalMethods对象,所以会从 animalMethods 对象上找到 eat 方法。

到现在为止还挺好。尽管如此,我们仍然可以做出一些改进。为了跨实例共享方法,必须管理一个单独的对象(animalMethods)似乎有点“傻哈”。我们希望这在语言本身中实现的一个常见特,所以就需要引出下一个属性 – prototype。

那么究竟 JavaScript 中的 prototype 是什么?好吧,简单地说,JavaScript 中的每个函数都有一个引用对象的prototype属性。

function doThing () {}console.log(doThing.prototype) // {}

如果不是创建一个单独的对象来管理我们的方法(如上例中 animalMethods),我们只是将每个方法放在 Animal 函数的 prototype 上,该怎么办?然后我们所要做的就是不使用Object.create 委托给animalMethods,我们可以用它来委托Animal.prototype。我们将这种模式称为原型实例化。

原型(prototype)实例化function Animal (name, energy) { let animal = Object.create(Animal.prototype) animal.name = nameanimal.energy=energy return animal}Animal.prototype.eat = function (amount) { console.log(`${this.name} is eating.`) this.energy = amount}Animal.prototype.sleep = function (length) { console.log(`${this.name} is sleeping.`) this.energy = length}Animal.prototype.play = function (length) { console.log(`${this.name} is playing.`) this.energy -= length}const leo = Animal(‘Leo’, 7)const snoop = Animal(‘Snoop’, 10)leo.eat(10)snoop.play(5)同样,prototype 只是 JavaScript 中的每个函数都具有的一个属性,正如我们前面看到的,它允许我们跨函数的所有实例共享方法。我们所有的功能仍然是相同的,但是现在我们不必为所有的方法管理一个单独的对象,我们只需要使用 Animal 函数本身内置的另一个对象Animal.prototype。总结一下

如何创建构造函数。

如何向构造函数的原型添加方法。

如何使用 Object.create 将失败的查找委托给函数的原型。

长按二维码识别添加小站

发表评论

登录后才能评论