JS中的面向对象

最近在复习JS基础,对于JS中的面向对象写法在此总结一下。

第一种:TS写法(ES6写法)

这种写法是在做项目里经常遇到的。特别是最近我参与的一个NG4的项目,全程TS,爽的不要不要的。

  • 先声明一个Car类(为了保证在ES6环境也可以运行,我没写TS的类型注解)
//ES6,使用传统的类、继承、多态和构造函数
class Car {
    constructor(name) {
        this.name = name;
        this.gear = 0;
        this.speed = 0;
    }

    drive() {
        clearInterval(this.driving);
        this.gear++;
        this.driving = setInterval(() => {
            this.speed += this.gear * 10;
            console.log(`老司机的${this.name}车速到了${this.speed}`);
            if (this.speed >= 200) {
                this.stop();
            }
        }, 100);
    }

    stop() {
        console.log("翻车了!");
        this.gear = 0;
        clearInterval(this.driving);
    }
}
let car = new Car("五菱宏光");
car.drive();
  • 这种风格和后端语言的风格非常接近,构造函数+自有方法。
  • 里面使用的模板字符串和箭头函数都是ES6的新特性,有兴趣的可以去看文档。
  • 接下来我们声明一个YunNanCar类,并实例化它。
class YunNanCar extends Car {
    constructor(name, personName) {
        super(name);
        this.personName = personName;
    }

    drive() {
        clearInterval(this.driving);
        this.gear++;
        this.driving = setInterval(() => {
            this.speed += this.gear * 10;
            console.log(`${this.personName}的${this.name}车速到了${this.speed}`);
            if (this.speed >= 300) {
                this.stop();
            }
        }, 100);
    }
}
let kunmingCar = new YunNanCar("昆明车", "樛木");
kunmingCar.drive();
  • 运行代码,毫无违和感。

第二种:ES5写法

第二种就是传统的ES5实现OOP,高级程序设计那本书推崇的方法。

//ES5,(高级程序设计书)使用原型链+构造函数
function Car(name) {
    this.name = name;
    this.gear = 0;
    this.speed = 0;
}
Car.prototype.drive = function () {
    clearInterval(this.driving);
    this.gear++;
    this.driving = setInterval(function () {
        //这里可以用self,但是不好
        this.speed += this.gear * 10;
        console.log("老司机的" + this.name + "车速到了" + this.speed);
        if (this.speed >= 200) {
            this.stop();
        }
    }.bind(this), 100);
};
Car.prototype.stop = function () {
    console.log("翻车了!");
    this.gear = 0;
    clearInterval(this.driving);
};
// var car = new Car("五菱宏光");
// car.drive();
function YunNanCar(name, personName) {
    //继承
    Car.call(this, name);
    this.personName = personName;
}
YunNanCar.prototype = Object.create(Car.prototype);
// 高程上的,会有意想不到的bug
// YunNanCar.prototype = new Car();
// YunNanCar.prototype.constructor = Car;
YunNanCar.prototype.drive = function () {
    clearInterval(this.driving);
    this.gear++;
    this.driving = setInterval(function () {
        //这里可以用self,但是不好
        this.speed += this.gear * 10;
        console.log(this.personName + this.name + "车速到了" + this.speed);
        if (this.speed >= 300) {
            this.stop();
        }
    }.bind(this), 100);
}
var kunmingCar = new YunNanCar("昆明车", "樛木");
kunmingCar.drive();
  • 这是前端们在艰难探索后找到的模仿传统类式OOP的方法,构造+原型链方法。
  • 和属性有关的用构造,和方法有关的添在原型上。目的是防止只用构造函数的时候不能复用函数,和只用原型链的时候会共享引用类型属性。
  • 没有箭头函数的时候,this会有问题,优雅的方法是采用bind强绑定,还有一种方法是使用self变量存放this。
  • 在设置原型链关联的时候,我没有使用高程的用法,原来需要指定YunNanCar的prototype为Car的实例,还要指定YunNanCar的prototype的constructor为Car,但其一那样关联原型链如果Car出了事YunNanCar也会跟着倒霉,其二是constructor根本不靠谱。所以使用更加靠谱的Object.create,如果要兼容旧式浏览器,就写段Polyfill代码。

第三种:纯面向对象写法

第三种方法是为JS量身定做的,和传统的OOP思想完全不一样,没有类,也没有继承,这种模式里没有父类,子类继承父类的概念。只有对象之间互相关联的关系。
比如说,传统OOP:我要一辆车,肯定是从车的基类继承,我要滑板鞋 肯定是从鞋的基类继承。
而行为委托根本不需要基类,在只有车和滑板鞋的情况下,滑板鞋也想飙车怎么办?于是滑板鞋和云南车关联起来,借用它的drive方法就可以了。

//JS中的纯面向对象,这里的三个方法可以分开写(ES5语法)比如init:function(name){..}
let Car = {
    init(name) {
        this.name = name;
        this.gear = 0;
        this.speed = 0;
    },
    drive() {
        clearInterval(this.driving);
        this.gear++;
        this.driving = setInterval(() => {
            this.speed += this.gear * 10;
            console.log(`老司机的${this.name}车速到了${this.speed}`);
            if (this.speed >= 200) {
                this.stop();
            }
        }, 100);
    },
    stop() {
        console.log("翻车了!");
        this.gear = 0;
        clearInterval(this.driving);
    }
}
let Shoe = Object.create(Car);
Shoe.product = function (name, personName) {
    this.init(name);
    this.personName = personName;
}
//独特的飙车方法
Shoe.racing = function () {
    clearInterval(this.driving);
    this.gear++;
    this.driving = setInterval(() => {
        this.speed += this.gear * 10;
        console.log(`${this.personName}的${this.name}滑板鞋速度到了${this.speed}`);
        if (this.speed >= 300) {
            this.stop();
        }
    }, 100);
}
let kunmingShoe = Object.create(Shoe);
kunmingShoe.product("滑板鞋", "樛木");
kunmingShoe.racing();
  • 这里我为了节省力气用了es6语法,es5语法使用传统的方法声明就好了,像init:function(name){..}这样。
  • Car对象里面有三个方法。是特有的。
  • 让滑板鞋关联这个车,接着给滑板鞋对象添加两个方法。
  • produce和racing方法和车毛关系都没有,但是它们的实现借用了车的三个方法,所以达到了滑板鞋也能飙车的目的。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,524评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,869评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,813评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,210评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,085评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,117评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,533评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,219评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,487评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,582评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,362评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,218评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,589评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,899评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,176评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,503评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,707评论 2 335

推荐阅读更多精彩内容