CoffeeScript—面向对象

概述

自从面向对象的编程头脑涌现以来,这个观点已被炒烂了,只需编程开辟人人都邑拿面向对象来讲事,彷佛只需跟面向对象沾边就会显得逼格很高一样,不过确切逼格进步了。要知道,面向对象只是一种手腕,终究目标是为了进步我们项目标重用性、灵活性和扩大性。

为了投合面向对象的程序设计头脑,JavaScript也经由过程本身的语法完成了本身的一套面向对象机制。不过我想问下,前端开辟当中有多少人运用过面向对象当中的继续?

JavaScript面向对象的完成确切有点不三不四的觉得。下面先简朴申明下JavaScript当中面向对象的完成,触及的东西比较深,要对constructor、prototype有肯定的明白,不然看起来会很费劲,或许你也能够跳开这部分内容,直接看CoffeeScript面向对象的完成。

JavaScript面向对象编程

JavaScript的完成一个类,能够采纳下面的体式格局:

function Animal(name) {
    this.name = name;
}

Animal.prototype.printName = function () {
    console.log(this.name);
};

var animal = new Animal('animal');

animal.printName();

C++、Java…某些程序员能够就吐槽了,我TM都连个关键字class都没看到,这就是类了?

《CoffeeScript—面向对象》

作为一个前端开辟,我竟无言以对。。。

继续

拔取JavaScript当中几种继续体式格局,作一个简朴的申明,想要进修更深的内容,请经由过程搜索引擎吧。

对象假装

function Animal(name) {
    this.name = name;

    this.printName = function () {
        console.log(this.name);
    };
}


function Cat(name) {
    this.inherit = Animal;
    this.inherit(name);

    //Animal.call(this, name);
    //Animal.apply(this, [name]);
}

var cat = new Cat('cat');

cat.printName();//cat

解释是经由过程call和apply完成的体式格局,实在实质是一样的。继续完成了,闲着无聊,我们来打印下:


console.log(cat instanceof Animal);//false

此次别说后端开辟看不下去,我都忍不了了。这类体式格局只能说是经由过程JavaScript的语法机制,模仿完成继续,看起来彷佛是那末回事,不然怎样叫对象假装呢。

原型链完成

function Animal(name) {
    this.name = name;
}

Animal.prototype.printName = function () {
    console.log(this.name);
};

function Cat() {
}

Cat.prototype = new Animal('cat');

var cat = new Cat();

cat.printName();//cat

打印:

console.log(cat instanceof Animal);//true

此次对了,cat也是Animal类的实例了,有点面向对象的的意义了。我又闲着无聊了(约么?),再来打印


console.log(cat.constructor); //[Function: Animal]

咦,又不对了,为啥cat的constructor指向Animal,不应该指向Cat么?

题目出在Cat.prototype = new Animal(‘cat’)上,直接给prototype赋值,改变了constructor的指向,这个时刻,我们还要做个处置惩罚

function Animal(name) {
    this.name = name;
}

Animal.prototype.printName = function () {
    console.log(this.name);
};

function Cat() {
}

Cat.prototype = new Animal('cat');
Cat.prototype.constructor = Cat;

var cat = new Cat();


console.log(cat.constructor); //[Function: Cat]

然则又有人吐槽了,new Cat()为啥把称号放到new Animal()内里,看起来太奇怪了,综合一下就有了第三中——夹杂型。

实际上instanceof的推断道理是跟原型链是相干的。人人自行脑洞!

夹杂完成

function Animal(name) {
    this.name = name;
}

Animal.prototype.printName = function () {
    console.log(this.name);
};

function Cat(name) {
    Animal.call(this, name);
}

Cat.prototype = new Animal();
Cat.prototype.constructor = Cat;

var cat = new Cat('cat');

cat.printName();//cat

看起来惬意点了,也就是惬意那末一点点。

多态

直接拿夹杂型的继续来申清楚明了,这个比较简朴

function Animal(name) {
    this.name = name;
}

Animal.prototype.printName = function () {
    console.log(this.name);
};

function Cat(name) {
    Animal.call(this, name);
}

Cat.prototype = new Animal();
Cat.prototype.constructor = Cat;

Cat.prototype.printName = function () {
    console.log('The name is:' + this.name);
};

var cat = new Cat('cat');
cat.printName();//The name is:cat

CoffeeScript面向对象编程

CoffeeScript的面向编程的语法同JavaScript比较起来,真是天上地下。一个阳春白雪,一个下里巴人。然则有一点我们要记着:CoffeeScript只是编译到JavaScript,它只是在JavaScript的基础上进行了语法的笼统,实质上照样JavaScript

CoffeeScript采纳class关键字声明类,全部语法看起来越发简明流通。

#编译前
class Animal
  constructor: (name)->
    @name = name
  printName: ->
    console.log(@name)

animal = new Animal 'animal'

animal.printName() #animal


#编译后
var Animal, animal;

Animal = (function () {
    function Animal(name) {
        this.name = name;
    }

    Animal.prototype.printName = function () {
        return console.log(this.name);
    };

    return Animal;

})();

animal = new Animal('animal');

animal.printName();

constructor是组织函数,就上面的例子来讲,还能够简写,实际上结果是一样的

class Animal
  constructor: (@name)->
  printName: ->
    console.log(@name)

animal = new Animal 'animal'

animal.printName() #animal

CoffeeScript将我们习惯性的誊写体式格局变成雄厚的语法糖。说到这里我就想说一句了,能不能把组织函数换个字符,constructor丫太长了。

继续

继续运用的是extends关键字


#编译前
class Animal
  constructor: (@name)->
  printName: ->
    console.log(@name)

class Cat extends Animal

cat = new Cat 'cat'

cat.printName() #cat


#编译后
var Animal, Cat, cat,
    extend = function (child, parent) {
        for (var key in parent) {
            if (hasProp.call(parent, key)) child[key] = parent[key];
        }
        function ctor() {
            this.constructor = child;
        }

        ctor.prototype = parent.prototype;
        child.prototype = new ctor();
        child.__super__ = parent.prototype;
        return child;
    },
    hasProp = {}.hasOwnProperty;

Animal = (function () {
    function Animal(name) {
        this.name = name;
    }

    Animal.prototype.printName = function () {
        return console.log(this.name);
    };

    return Animal;

})();

Cat = (function (superClass) {
    extend(Cat, superClass);

    function Cat() {
        return Cat.__super__.constructor.apply(this, arguments);
    }

    return Cat;

})(Animal);

cat = new Cat('cat');

cat.printName();

extend函数剖析

我们简朴剖析下编译后的extend函数,对JavaScript原型链不是很熟的能够跳过这段。两个参数分别是子类child和父类parent,第一段代码:

for (var key in parent) {
    if (hasProp.call(parent, key)) child[key] = parent[key];
}

这段代码就是将父类上面的属性拷贝到子类上,由于JavaScript当中函数也是对象,能够扩大属性的。什么意义?看代码

class Animal
  constructor: (@name)->
  printName: ->
    console.log(@name)

Animal.prop = 'Animal prop'

class Cat extends Animal

console.log Cat.prop #Animal prop

第二段代码:

function ctor() {
    this.constructor = child;
}

ctor.prototype = parent.prototype;
child.prototype = new ctor();

能够人人看不大明白,我轻微修改下,换种写法

child.prototype = new parent();
child.prototype.constructor=child;

这里就是我们上面提到的原型链继续。再看最后段代码:

child.__super__ = parent.prototype;

这里是为了在子类中挪用父类的要领,完成多态,看下面的例子就知道了。

多态

编译后的代码太长,就不粘贴了,看CoffeeScript代码更易于进修。

直接重写父类要领

class Animal
  constructor: (@name)->
  printName: ->
    console.log(@name)


class Cat extends Animal
  printName: ->
    console.log 'Cat name:' + @name

cat = new Cat 'cat'

cat.printName() #Cat name:cat

重写父类要领,在重写的要领中挪用父类要领

class Animal
  constructor: (@name)->
  move: (meter)->
    console.log(meter)


class Cat extends Animal
  move: ->
    console.log 'Cat move'
    super 4

cat = new Cat 'cat'

cat.move() #Cat move 4

有任何题目,迎接人人指摘指出,我们共同进步。

    原文作者:小俞
    原文地址: https://segmentfault.com/a/1190000002617889
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞