JavaScript继承解析

栏目: JavaScript · 发布时间: 5年前

内容简介:基本上,ES6 的class可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。本篇完。

基本上,ES6 的class可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。

借助构造函数实现继承

  • 缺点:无法继承原型链上的属性和方法
function Person () {
  this.name = 'person1'
}
Person.prototype.sex = '10'
Person.prototype.sayName = function () {
  alert(this.name)
}
function Man () {
  Person.call(this)
  this.age = '24'
}
var m1 = new Man()
console.log(m1) // Man {name: "person1", age: "24"}  (注意:实例自身不存在sex属性和 
sayName方法)
// m1.sayName() // 报错 (因为原型链上也不存在)
复制代码

借助原型链实现继承

  • 缺点:子类共享父类的引用属性
function Father () {
 this.Farr = [1, 2, 3]
}
function Child () { }
Child.prototype = new Father()
var c1 = new Child()
var c2 = new Child()
console.log(c1.Farr) // [1, 2, 3]
console.log(c2.Farr) // [1, 2, 3]
c1.Farr.push(4)
console.log(c1.Farr) // [1, 2, 3, 4]
console.log(c2.Farr) // [1, 2, 3, 4]
复制代码

组合继承

  • 优点:子类不会共享父类中的属性,缺点:Mother构造函数被执行两次,无法确定实例直接父类了
function Mother () {
  console.log('init Mother...')
  this.Marr = ['a', 'b', 'c']
}
function Daughter () {
  Mother.call(this) // 执行一次Mother构造函数
}
Daughter.prototype = new Mother() // 再执行一次Mother构造函数
var d1 = new Daughter()
var d2 = new Daughter()
console.log(d1.Marr) //  ["a", "b", "c"]
console.log(d2.Marr) //  ["a", "b", "c"]
d1.Marr.push('d')
console.log(d1.Marr) // ["a", "b", "c", "d"]
console.log(d2.Marr) //  ["a", "b", "c"]
console.log(d2.__proto__.constructor === Mother) // true(期望值是false,因为Daughter才是d2的直接父类)
复制代码

组合继承优化(一)

  • 优点:防止调用两次构造函数,缺点:依旧无法确定实例直接父类
function Animal () {
  console.log('init Animal...')
}
function Cat () {
  Animal.call(this) // 执行一次Animal构造函数
}
Cat.prototype = Animal.prototype
var cat = new Cat()
console.log(cat.__proto__.constructor === Animal) // true(期望值是false,因为Cat才是cat的直接父类)
复制代码

组合继承优化(二)

  • 解决无法确定实例直接父类问题
function God () {
  console.log('init Final...')
  this.name = 'god'
}
God.prototype.todo = function () {
  alert('todo')
}
function Son () {
  God.call(this)
}
// Son.prototype = God.prototype
Son.prototype = Object.create(God.prototype) // Object.create()方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__
console.log(God.prototype)
console.log(Object.create(God.prototype))
Son.prototype.constructor = Son

var s = new Son // 无参数时,小括号可以省略
console.log(s)
console.log(s.__proto__.constructor === Son) // true (与期望值一直,完美!)
console.log(s.__proto__.constructor) // true (与期望值一直,完美!)
复制代码

为什么要用Object.create()方法

  • Object.create()方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__
  • 使用这个方法,传入null可以创建一个无任何属性的对象(原型上也没有)
  • 使用这个方法,会将现有对象放到__proto__属性中,会隐藏现有对象原型上的默认属性和方法,仅仅保留用户自己定义的。
// 普通方法创建对象的对象
console.log({})
// 使用Object.create创建的对象
console.log(Object.create(null))

// 使用Object.create,会将现有对象放到__proto__属性中
function God () {
  console.log('init Final...')
  this.name = 'god'
}
God.prototype.todo = function () {
  alert('todo')
}
function Son () {
  God.call(this)
}
// Son.prototype = God.prototype
Son.prototype = Object.create(God.prototype)
Son.prototype.constructor = Son

console.log(Son.prototype)
复制代码
  • 普通方法创建对象的对象

    JavaScript继承解析
  • 使用Object.create创建的对象

    JavaScript继承解析
  • 使用Object.create()方法实现继承

    JavaScript继承解析
  • 不使用Object.create()方法实现继承

    JavaScript继承解析

本篇完。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

密码朋克

密码朋克

[澳] 朱利安·阿桑奇 / Gavroche / 中信出版社 / 2017-10 / 42.00元

互联网已经在世界各地掀起了革命,然而全面的打击也正在展开。随着整个社会向互联网迁移,大规模监控计划也正在向全球部署。我们的文明已经来到一个十字路口。道路的一边通往一个承诺“弱者要隐私,强 者要透明”的未来,而另一边则通往一个极权的互联网,在那里,全人类的权力被转移给不受问责的间谍机构综合体及其跨国公司盟友。 密码朋克是一群倡导大规模使用强密码术以保护我们的基本自由免遭攻击的活动家。维基解密的......一起来看看 《密码朋克》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具