JavaScript 面向对象

面向对象概念

面向对象是一种思想,是基于面向过程而言的。

利用构造函数创建对象

  1. 假如我们把王者荣耀里面的英雄看成一个对象,那王者荣耀英雄有很多不同的属性,比如有名字、攻击类型等等。
    利用构造函数的方法封装
function Hero (name,type) {   // 构造函数
      this.name = name;
      this.type = type;
}

利用构造函数可以生成实例对象,就是在调用函数

var houyi = new Hero ('后羿','射手型')
var lianpo = new Hero ('廉颇','坦克型')

new在执行时会做四件事

  1. 在内存中创建了一个新的空对象
  2. 让this指向这个对象
  3. 执行构造函数里面的代码,给这个对象添加新的属性和方法
  4. 返回这个this对象(所以构造函数内部不需要return)

这时 houyi 和 lianpo 会有一个共同的 constructor 属性 ,这个属性返回的就是这个构造函数。

    console.log(houyi.constructor);
      // ƒ Hero(name, type) {   // 构造函数
         this.name = name;
         this.type = type;
    } 

    console.log(lianpo.constructor);
      // ƒ Hero(name, type) {   // 构造函数
         this.name = name;
         this.type = type;
    } 

这样的确很方便,但是有一个问题,那就是浪费内存。
如果我们向构造函数里添加一个不变的属性和方法。
添加一个方法构造函数如下

function Hero (name,type,dazhao) {   // 构造函数
      this.name = name;
      this.type = type;
      this.dazhao = dazhao;
}
// 生成两个实例
var houyi = new Hero ('后羿','射手型',function () {
      console.log('后羿射日')
})
var lianpo = new Hero ('廉颇','坦克型',function () {
      console.log('后羿射日')
})

但是这两个一模一样的函数会在内存中占用两个空间。

console.log(houyi.dazhao === lianpo.dazhao) // false

要解决这个办法其实可以在全局中定义函数

// 在全局中定义函数
var a = function () {
      consloe.log('后羿射日')
}
function Hero (name,type,dazhao) {   // 构造函数
      this.name = name;
      this.type = type;
      this.dazhao = dazhao;
}

// 生成两个实例
var houyi = new Hero ('后羿','射手型',a)
var lianpo = new Hero ('廉颇','坦克型',a)
console.log(houyi.dazhao === lianpo.dazhao) // true

全局定义虽然可以解决这个问题,但是在全局中定义的变量或者函数很容易被覆盖。这显然也不是最优解。

但是,任何一个对象天生自带一个__ proto__属性,这个东西是一个对象,叫做原型对象。
对象是可以访问到原型上的属性和方法。
任何一个函数都有一个prototype属性,这个也是一个对象,叫做原型对象。这个对象里面的属性和方法是可以被构造函数的实例继承。

这就说明我们可以把这些不变的属性和方法直接定义到prototype这个对象上。

function Hero (name,type) {   // 构造函数
      this.name = name;
      this.type = type;
}
Hero.prototype.dazhao = function () {
      console.log('后羿射日')
}
//  然后生成实例
var houyi = new Hero ('后羿','射手型')
var lianpo = new Hero ('廉颇','坦克型')
houyi.dazhao() // 后羿射日
console.log(houyi.dazhao === lianpo.dazhao)  // true

这样所有实例的 dazhao 属性,其实都是同一个内存地址了,指向了prototype对象,也解决了全局定义容易被覆盖的问题。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。