js的继承

6.2 为什么要有继承?

重复代码太多了

// Student
function Student(name, age, sno) {
  this.name = name
  this.age = age
  this.sno = sno
}

Student.prototype.running = function () {
  console.log(this.name + " running~")
}

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

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

// Teacher
function Teacher(name, age, title) {
  this.name = name
  this.age = age
  this.title = title
}

Teacher.prototype.running = function () {
  console.log(this.name + " running~")
}

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

Teacher.prototype.teaching = function () {
  console.log(this.name + " teaching")
}
6.3 继承-原型链的方案
// 父类:公共的属性和方法
function Person(name) {
  this.name = "呆呆狗"
  this.friedns = ["萌萌"]
}
Person.prototype.eating = function () {
  console.log(this.name + '  eating~~~');
}
// 子类:自己特有的
function Student(sno) {
  this.sno = 100
}
// 核心代码  13行
Student.prototype = new Person

Student.prototype.studying = function () {
  console.log(this.name + '  studying~~~');
}

var stu = new Student()
var stu2 = new Student()
console.log(stu);
console.log(stu.name);
console.log(stu.eating);
console.log(stu.studying);

// 弊端
// 1.如果打印 stu对象,某些属性是看不到的 (有些数据是在原型上的)
// 2.对于 Person 里面的引用类型的数据,会互相影响的 ,
// 这种不会影响,其实 stu.name 是在 stu 这个对象里面添加一个 name 属性
stu.name = "copy"
console.log(stu2.name); // 呆呆狗

// 这种会影响
stu.friedns.push('2号朋友')
console.log(stu.friedns); // ['萌萌', '2号朋友']
console.log(stu2.friedns); // ['萌萌', '2号朋友']

// 3. 在前面实现类得过程中,都没有传递参数
// 因为不好传递参数
6.4 继承-借用构造函数的方案
// 父类:公共的属性和方法
function Person(name, age, friedns) {
  this.name = name
  this.age = age
  this.friedns = friedns
}
Person.prototype.eating = function () {
  console.log(this.name + '  eating~~~');
}
// 子类:自己特有的
function Student(name, age, friedns, sno) {
  //  此时得this 指向得时 Student
  Person.call(this, name, age, friedns)
  this.sno = sno
}

var p = new Person()
Student.prototype = p
Student.prototype.studying = function () {
  console.log(this.name + '  studying~~~');
}

var stu = new Student("呆呆狗", 18, ["萌萌"], 1.80)
var stu2 = new Student("狗2", 30, ["xxxxxx"], 1.80)
console.log(stu, stu2);

// 借用构造函数 存在的弊端
// 1.person 构造函数被调用了两次
// 2.stu的原型对象上回多出一些属性,但是这些属性是没有存在的必要的
6.5 继承-父类原型赋值给子类 (不建议此方法)
// 父类: 公共属性和方法
function Person(name, age, friends) {
  // this = stu
  this.name = name
  this.age = age
  this.friends = friends
}

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

// 子类: 特有属性和方法
function Student(name, age, friends, sno) {
  Person.call(this, name, age, friends)
  this.sno = 111
}

// 直接将父类的原型赋值给子类, 作为子类的原型
Student.prototype = Person.prototype

// 弊端: 这个studying 方法 会添加到 Person的原型上,如果 创建多个 实例,就会给Person的原型上 添加很多东西
Student.prototype.studying = function () {
  console.log(this.name + " studying~")
}
// name/sno
var stu = new Student("why", 18, ["kobe"], 111)
console.log(stu)
stu.eating()
6.6 继承-原型式继承-对象
var obj = {
  name: "呆呆狗",
  age: 19
}

// 新创建出来一个对象 ,并且用原来某一个对象做为 新对象的原型
function createObject(obj) {
  var newObj = {}
  Object.setPrototypeOf(newObj, obj)
  return newObj
}
function createObject2(obj) {
  function Fn() { }
  // 把 obj 设置为 Fn 的原型对象
  Fn.prototype = obj
  var newObj = new Fn()
  return newObj
}
// var info = createObject(obj)
var info = Object.create(obj) // Object.create方法将 后面的参数,作为 返回值的原型

console.log(info);
6.7 继承-寄生式继承-对象
var obj = {
  running: function () {
    console.log("running");
  }
}
function createObj(obj, name) {
  var newObj = Object.create(obj)
  newObj.name = name
  return newObj
}
var stuObj1 = createObj(obj, "呆呆狗")
console.log(stuObj1);
6.8 继承-寄生组合式继承
function createObject(o) {
  function Fn() { }
  Fn.prototype = o
  return new Fn()
}

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

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

Person.prototype.running = function () {
  console.log("running~")
}

Person.prototype.eating = function () {
  console.log("eating~")
}

function Student(name, age, friends, sno, score) {
  Person.call(this, name, age, friends)
  this.sno = sno
  this.score = score
}

inheritPrototype(Student, Person)

Student.prototype.studying = function () {
  console.log("studying~")
}

var stu = new Student("why", 18, ["kobe"], 111, 100)
console.log(stu)
stu.studying()
stu.running()
stu.eating()

console.log('constructor的name', stu.constructor.name)

你可能感兴趣的:(js,javascript)