DIY熙

  • 首页
  • 归档
  • 服务

  • 搜索
TypeSCript 设计模式 前端 算法 electron React Node.js 规范 直播服务器 服务器 小熙js脚本库 油猴脚本 面试

略解《JavaScript语言精粹》- 继承

发表于 2022-02-16 | 0 | 阅读次数 323

前言

  1. 本篇博客因篇幅有限,仅提取出个人认为十分重要且有用的精华,由于本人能力有限,文章可能未能一一提及,仅供各位同学参考学习。

  2. 本文章所有代码已在WebMaker上有代码测试用例。请点击略解《JavaScript语言精粹》代码片段访问配合学习。

伪类(原型链继承)

JavaScript通过构造器函数产生对象。

const Persion = function (name) {
    this.name = name
}

Persion.prototype.getName = function() {
    return this.name
}

Persion.prototype.says = function() {
    return this.saying || ''
}

const persion1 = new Persion('xiaoxi')
console.log(persion1.getName())

const Father = function (name) {
    this.name = name
    this.saying = "i am father"
}
Father.prototype = new Persion()
Father.prototype.getName = function() {
    return "Father" + this.name
}

Father.prototype.says = function() {
    return this.saying || ''
}

const father1 = new Father('xiaoxi')

console.log(father1.says())

伪类模式本意是向面向对象靠拢,但它看起来格格不入,但可以隐藏prototype的操作系统,使它看起来没那么怪异。

可以使用父类的实例方法和原型方法,但 new 实例化传参不可用,需要手动修改实例属性。静态方法也不能被继承。

使用构造器函数存在严重危害,如果调用构造器函数的时候忘记在前面加 new 关键字,那么this将会绑定到全局对象上,这是一个严重的语言设计错误。伪类的形式隐藏了语言的真实本质,JavaScript有更好的选择。

对象冒充继承

function Person(name, age) {
    this.name = name; //实例属性
    this.age = age; //实例属性
    this.run = function () { //实例方法
        console.log(this.name + ' is running');
    }
}

Person.prototype.swim = function () { //类上添加原型方法
    console.log(`${this.name} is swiming`);
}

Person.work = function () { //类上添加静态方法
    console.log(`${this.name} is working`);
}

function Student(name, age, grade) {
    Person.call(this, name, age); //对象冒充继承
    this.grade = grade; //实例属性
}

通过call改变函数this的指向实现继承,但不能继承原型属性和方法。静态方法也不能被继承。

对象冒充+原型链继承


function Programmer(name, age, language) {
    Person.call(this, name, age); //对象冒充继承
    this.language = language; //实例属性
    this.introduce = function () { //实例方法
        console.log(`${this.name} is a ${this.language} developer`);
    }
}

Programmer.prototype = new Person(); //原型链继承

可以使用父类的实例方法和原型方法,子类也能向父类传参,但同时静态方法仍然不能被继承。

ES6类的语法糖

class Animal {
    constructor(name, age) { //实例属性创建
        this.name = name;
        this.age = age;
    }
    speak() { //实例方法
        console.log(this.name + ' makes a noise.');
    }
    static words = 'All animals eat food.'; //静态属性
}

Animal.prototype.run = function () { //类上添加原型方法
    console.log(this.name + ' is running.');
}

Animal.eat = function () { //类上添加静态方法
    console.log(this.words);
}

class Dog extends Animal {
    constructor(name, age, color) {
        super(name, age);
        this.color = color;
    }
    colorIs() {
        console.log(this.name + ' is ' + this.color);
    }
}
let dog1 = new Dog('Teddy', 2, 'white'); //实例化

//继承父类的实例方法
dog1.speak(); //Teddy makes a noise.
//子类方法使用父类的实例属性
dog1.colorIs(); //Teddy is white
//继承父类的原型方法
dog1.run(); //Teddy is running.

//继承父类的静态方法
Dog.eat(); //All animals eat food.

可以使用父类的实例方法和原型方法,子类也能向父类传参。重点是,静态方法在 ES6 上是能被继承的。

函数化模式

从构造一个生成对象的函数开始,我们以小写字母开头来命名它,因为它不需要用new关键词,分为四个步骤。

  1. 创建一个新对象
  2. 定义私有变量和方法
  3. 给这个新对象扩充方法
  4. 返回那个新对象
const mammal = function (spec) {
    const that = {}
    that.get_name = function () {
        return spec.name
    }
    that.says = function () {
        return spec.saying || ''
    }
    return that
}

const myMammal = mammal({ name: 'Herb' })

console.log(myMammal.get_name())

const cat = function(spec) {
    spec.saying = spec.saying || 'meow';
    const that = mammal(spec)
    that.purr = function() {
        return 'sssssssss'
    }
    that.get_name = function() {
        return that.says() + spec.name
    }
    return that
}

const myCat = cat({name: 'Henrietta'})
console.log(myCat.get_name())

const coolcat = function(spec) {
    const that = cat(spec)
    const super_get_name = that.get_name
    that.get_name = function() {
        return 'like' + super_get_name() + 'baby'
    }
    return that
}

const myCoolCat = coolcat({name: 'Bix'})
const name = myCoolCat.get_name()

console.log(name)

总结

  1. 函数继承有5种方式
  2. 分别是伪类(原型继承)、对象冒充继承、冒充+原型继承、ES6语法糖、函数化模式
类型实例方法原型方法实例属性静态方法建议
伪类(原型链继承)√√可以访问但无法调用父类构造器初始化×
对象冒充继承√×√×
冒充+原型继承√√√×
ES6语法糖√√√√简单易用

函数化模式比较特殊,是利用函数内部对象对外不可见的形式形成对象,所以不是自身继承这样的理念,无法应用到上面的表格当中,函数化模式更多是管理对象,所谓的继承也是对对象的属性和方法进行的一些操作。

  • 本文作者: 大熙哥
  • 本文链接: https://blog.diyxi.top/archives/略解javascript语言精粹-继承
  • 版权声明: 本博客所有文章除特别声明外,均采用CC BY-NC-SA 3.0 许可协议。转载请注明出处!
略解《JavaScript语言精粹》- 函数
探索web3.0
  • 文章目录
  • 站点概览
大熙哥

大熙哥

38 日志
11 分类
13 标签
RSS
Github
Creative Commons
Links
  • Ziki
  • 咸鱼的窝
  • Farmer的自习室
  • 一个肥肥的自习室
  • lafish
  • 小呆呆的生活
  • hekvn
© 2023 大熙哥
由 Halo 强力驱动
|
主题 - NexT.Mist v5.1.4
粤ICP备20011435号-1
0%