JS面向对象三大特征:封装、继承、多态

封装

把事物(属性和方法)封装在类(程序对象)中,隐藏事物的属性和方法的实现细节,仅对外公开接口。
1.构造函数模式

function Person(name, sex) {
        this.name = name;
        this.sex = sex;
        this.sayName = function () {
                alert(this.name);
        };
}

var adam = new Person("亚当", 1);
var eve = new Person("夏娃", 0);

2.原型prototype封装

function Cat(name,color){
            this.name = name;
            this.color = color;
        }
        Cat.prototype.type = "英短";
        Cat.prototype.eat = ( () => {
            alert("fish!")
        } )
          
        //生成实例
        var cat1 = new Cat('Tom', 'gray');
        var cat2 = new Cat('Kobe', 'purple');
        console.log(cat1.type); //英短
        cat2.eat(); //fish!

3.声明函数模式

  • 优点
    避免了全局变量--因为存在函数作用域(函数作用域画重点,以后要考)
    按需执行--解析器读取到此处,函数并未执行,只有当你需要的时候,调用此函数即可
    提高代码重用性
  • 缺点:
    易被同名变量覆盖--因为在全局作用域下声明的变量,容易被同名变量覆盖
    立即执行--解析器读取到此处立即执行

4.工厂模式

function createPerson(name, sex) {
        var o = new Object();
        o.name = name;
        o.sex = sex;
        return o;
}

var adam = createPerson("亚当", 1);
var eve = createPerson("夏娃", 0);
  • 优点:这种封装解决了代码重复的问题;

  • 缺点:adam和eve之间没有内在的联系,不能反映出它们是同一个原型对象的实例;

5.闭包

var PI = (function () {
            var _pi = 3.1415926;
            return {
                get: function () {
                    return _pi;
                }
            }
        }())

   console.log(PI.get()); //3.1415926
继承

一个对象可以使用另一个对象的属性和方法 (子类可以使用父类的属性和方法)
1.原型链继承

//创建自定义构造函数
function Hqg() {
    this.name = '洪七公';
}
//在当前构造函数的原型链上添加属性skill
Hqg.prototype.skill = '打狗棒'

//通过自定义构造函数Hqg实例化一个对象gj
const gj = new Hqg()
console.log(gj.skill);//=>打狗棒
//通过自定义构造函数Hqg实例化一个对象hr
const hr = new Hqg()
console.log(hr.skill);//=>打狗棒
  • 缺点:当父类(对象)属性或方法改变时,不同实例对象对应属性方法也会改变。

2.借用构造函数

//创建一个构造函数,并添加一些属性
function Hqg() {
    this.name = '洪七公';
    this.job = '帮主';
    this.skill = ['降龙十八掌', '打狗棒']
}
//创建一个构造函数,并借用了Hqg的构造函数
function Hr() {
        Hqg.call(this)
        this.name = '黄蓉';
        this.job = ['相夫', '教子']
}
//创建一个构造函数,并借用了Hqg的构造函数
function Gj() {
    Hqg.call(this)
    this.name = '郭靖';
    this.job = ['吃饭', '睡觉']

}
const hr = new Hr();
console.log(hr);

const gj = new Gj();
console.log(gj);
2-1.png

这样就避免了原型链继承中,构造函数中的属性或者方法被其他实例所改变的问题
⚠️:这里要注意call方法的执行顺序:

//部分代码省略
function Hr() {
    this.name = '黄蓉';
    this.job = ['相夫', '教子']
    Hqg.call(this)
}
function Gj() {
    this.name = '郭靖';
    this.job = ['吃饭', '睡觉']
    Hqg.call(this)
}

//部分代码省略
4-1.png

值会被覆盖,这个要注意!

function Hqg(name,job,skill) {
  this.name = name;
  this.job = job;
  this.skill = skill
}
function Hr() {
  Hqg.call(this,'黄蓉',['相夫', '教子'],['打狗棒'])
}

function Gj() {
  Hqg.call(this,'郭靖',['吃饭', '睡觉'],['降龙十八掌'])
}
const hr = new Hr();
console.log(hr);

const gj = new Gj();
console.log(gj);
3-1.png

3.组合继承
使用原型链实现对原型对象属性和方法的继承,借用构造函数实现对实例属性方法的继承
这样既通过在原型上定义方法实现了函数复用,又能保证每个实例都有自己的属性

 function hqg(name) {
        this.name = name
        this.skill = ['打狗棒', '乾坤大挪移']
      }
      hqg.prototype.sayName = function () {
        console.log(this.name)
      }
      function Hero(name, job) {
        hqg.call(this, name)
        this.job = job
      }
      Hero.prototype.sayJob = function () {
        console.log(this.job)
      }
      Hero.prototype = new hqg()
      Hero.prototype.constructor = Hero
      var gj = new Hero('郭靖', '打老虎')
      var hr = new Hero('黄蓉', '打豆豆')
      console.log(gj)
      console.log(hr)

4.寄生式继承
寄生式继承是与原型式继承紧密相关的一种思路,它创造一个仅用于封装继承过程的函数,在函数内部以某种方式增强对象,最后再返回对象。

function object(o) {
    function F() {}
    F.prototype = o;
    return new F();
}

function hero(params) {
    const clone = object(params) //通过调用函数创建一个新对象
    clone.sayHi = () => {
        console.log('hi');
    }
    return clone
}
const hqg = {
    name: "洪七公",
    skill: ['降龙十八掌', '打狗棒']
}
const gj = hero(hqg);
gj.name = '郭靖';
gj.skill.push('九阴真经')
console.log(gj);
3-4.png

5.寄生组合式继承

function object(o) {
    function F() {}
    F.prototype = o;
    return new F();
}

function hero(Children, Parent) {
    const proto = object(Parent.prototype); //返回Parent的一个副本
    proto.constructer = Children; //设置constructor指向, 因为新副本的原型对象被重写
    Children.prototype = proto; //副本作为sub的原型对象
}

function Hqg() {
    this.name = '洪七公';
}
Hqg.prototype.show = function () {
    console.log(this.name);
}

function Gj() {
    Hqg.call(this);
    this.name = '郭靖'
}

function Hr() {
    Hqg.call(this);
    this.name = '黄蓉'
}
hero(Gj, Hqg);
hero(Hr, Hqg);
const gj = new Gj();
const hr = new Hr();
gj.show(); // =>郭靖
hr.show(); //=> 黄蓉
多态

不同对象与同一操作产生不同结果。把“想做什么”跟“谁去做”分开,把过程化的条件语句转换为对象的多态性,从而消除条件分支语句。有重写跟重载:
重写:子类可继承父类中的方法,而不需要重新编写相同的方法。但有时子类并不想原封不动地继承父类的方法,而是想作一定的修改,这就需要采用方法的重写。方法重写又称方法覆盖。
重载:函数或者方法有相同的名称,但是参数列表不相同的情形,这样的同名不同参数的函数或者方法之间,互相称之为重载函数或者方法。

//非多态     
var hobby = function(animal){
    if(animal == 'cat'){
        cat.eat()
    }else if(animal == 'dog'){
        dog.eat()
    }
}

var cat = {
    eat: function() {
        alert("fish!")
    }
}

var dog = {
    eat: function() {
        alert("meat!")
    }
}

console.log(123);
hobby('cat'); //fish!
hobby('dog'); //meat!
//多态  
var hobby=function(animal){
  if(animal.eat instanceof Function){
     animal.eat() 
  }
}
var cat={
 eat:()=>{
  console.log('miao')
 }
}
var dog={
 eat:()=>{
  console.log('wang')
 }
}
hobby(cat)// miao
hobby(dog)// wang
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 223,924评论 6 521
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 95,776评论 3 402
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 170,954评论 0 366
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 60,576评论 1 300
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 69,589评论 6 399
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 53,105评论 1 314
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 41,480评论 3 427
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 40,457评论 0 278
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,998评论 1 324
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 39,026评论 3 343
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 41,174评论 1 354
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,812评论 5 350
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 42,502评论 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,979评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 34,101评论 1 275
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 49,674评论 3 380
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 46,204评论 2 363