Js面向对象--继承篇(二)

66 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第6天,点击查看活动详情

-父类原型赋值给子类方式继承

首先创建一个父类:公共属性与方法

function Boy(name,age,friends) {
  this.name = name
  this.age = age
  this.friends = friends
}

Boy.prototype.eating = function() {
  console.log(this.name + " eating~")
}

创建一个子类:特殊属性和方法

function Life(name, age, friends, job) {
  Boy.call(this, name, age, friends)
  this.job = job
}

将父类原型赋值给子类

Life.prototype = Boy.prototype

Life.prototype.studying = function() {
  console.log(this.name + " studying~")
}

验证结果

var boy1 = new Life ("我妻善逸", 16,["嘴平伊之助"],"鬼杀队剑士")

console.log(boy1.name)//我妻善逸
boy1.eating()//我妻善逸 eating~

但从结果上来看是没有什么问题

但是子类Life原型上添加的studying方法也会同时被添加到父类Boy上面

所以我们通过父类原型赋值给子类的方式实现继承

-原型式继承函数方式继承

原型式继承的渊源

这种模式要从道格拉斯·克罗克福德(Douglas Crockford,著名的前端大师,JSON的创立者)

在2006年写的一篇文章说起: Prototypal Inheritance in JavaScript(在JS中使用原型式继承)

var boy = {
  name: "我妻善逸",
  age: 16
}

function createObject(a) {
  function Fn() {}
  Fn.prototype = a
  var newBoy = new Fn()
  return newBoy
}

var boy1 = createObject(boy)

最终的目的:boy1对象的原型指向了boy对象;

原型式继承的变种写法

var boy = {
  name: "我妻善逸",
  age: 16
}
var boy1 = Object.create(boy)

create 方法用于创建一个新对象,使用现有的对象来作为新创建对象的原型(prototype)

-寄生式继承函数

寄生式继承的思路是结合原型类继承和工厂模式的一种方式;

即创建一个封装继承过程的函数, 该函数在内部以某种方式来增强对象,最后再将这个对象返回;

var boy = {
   running: function() {
    console.log("running")
  }
}
function createBoy(name){
  var Newboy = Object.create(boy)
  Newboy.name = name
  Newboy.studying = function() {
    console.log("studying~")
  }
  return Newboy
}
var boy1 = Object.create(boy)

-寄生组合继承

var boy = {
   running: function() {
    console.log("running")
  }
}
var boy1 = {
    eating: function() {
    console.log("eating")
  }
}
function inheritPrototype(SubType, SuperType) {
  SubType.prototype = Object.create(SuperType.prototype)
  Object.defineProperty(SubType.prototype, "constructor", {
    enumerable: false,
    configurable: true,
    writable: true,
    value: SubType
  })
}


inheritPrototype(boy1, boy)

对象的方法补充

hasOwnProperty 对象是否有某一个属于自己的属性(不是在原型上的属性)

var obj = {
  name: "sabo",
  age: 18
}

var info = Object.create(obj, {
  address: {
    value: "北京市",
    enumerable: true
  }
})

// hasOwnProperty方法判断
// console.log(info.hasOwnProperty("address"))
// console.log(info.hasOwnProperty("name"))

in/for in 操作符 判断某个属性是否在某个对象或者对象的原型上

console.log("address" in info)
console.log("name" in info)

in 操作符: 不管在当前对象还是原型中返回的都是true

for (var key in info) {
 console.log(key)
}

instanceof 用于检测构造函数的pototype,是否出现在某个实例对象的原型链上

function createObject(o) {
  function Fn() {}
  Fn.prototype = o
  return new Fn()
}

function inheritPrototype(SubType, SuperType) {
  SubType.prototype = createObject(SuperType.prototype)
  Object.defineProperty(SubType.prototype, "constructor", {
    enumerable: false,
    configurable: true,
    writable: true,
    value: SubType
  })
}


function Person() {

}

function Student() {

}

inheritPrototype(Student, Person)

console.log(Person.prototype.__proto__)

var stu = new Student()
console.log(stu instanceof Student) // true
console.log(stu instanceof Person) // true
console.log(stu instanceof Object) // true

isPrototypeOf 用于检测某个对象,是否出现在某个实例对象的原型链上(不常用)

function Person() {

}

var p = new Person()

console.log(p instanceof Person)
console.log(Person.prototype.isPrototypeOf(p))

// 
var obj = {
  name: "sabo",
  age: 18
}

var info = Object.create(obj)

console.log(info instanceof obj)
console.log(obj.isPrototypeOf(info))