CoffeeScript對象

2018-08-25 14:09 更新

CoffeeScript 中對象的綁定


有時(shí)候你需要一個(gè)函數(shù)運(yùn)行在特定的上下文對象中,而不管它在哪里被調(diào)用。比如有類似這樣一個(gè)函數(shù):
callback = (message) –> @v.push message


當(dāng)直接調(diào)用這個(gè)函數(shù)時(shí) @(this)所代表的就是全局對象,如果通過 call 或者 apply 指定了其他的上下文對象,@ 則代表了其他上下文對象。有什么辦法使 @ 綁定為特定的上下文對象呢?


在 CoffeeScript 中有一個(gè)非常方便的方式,只要用 => 代替 –> 定義需要綁定特定上下文對象的函數(shù)即可,比如以上 callback 函數(shù):
callback = (message) => @v.push message


此時(shí)的 @ 指代的就是該函數(shù)定義時(shí)所在的上下文對象。以上函數(shù)解析成 javascript 就是:


var callback, 
  _this = this;
callback = function(message) { 
  _this.v.push(message); 
};


那為什么不直接用 => 代替 –> 呢?
增加了代碼量以及運(yùn)行時(shí)間,并且這是沒有必要的
為了適應(yīng)復(fù)雜的上下文對象,可以提供更加優(yōu)雅的代碼編寫方式
在你定義函數(shù)的時(shí)候一定要非常認(rèn)真考慮使用 this/@ 指定正確的上下文對象。同時(shí)使用綁定和 call/apply 方法編寫更優(yōu)雅的代碼。



CoffeeScript面向?qū)ο缶幊?/strong>


CoffeeScript的面向編程的語法同JavaScript比較起來,真是天上地下。一個(gè)陽春白雪,一個(gè)下里巴人。但是有一點(diǎn)我們要記?。篊offeeScript只是編譯到JavaScript,它只是在JavaScript的基礎(chǔ)上進(jìn)行了語法的抽象,本質(zhì)上還是JavaScript。



CoffeeScript采用class關(guān)鍵字聲明類,整個(gè)語法看起來更加簡明流暢。


#編譯前
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是構(gòu)造函數(shù),就上面的例子來說,還可以簡寫,實(shí)際上效果是一樣的


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


animal = new Animal 'animal'


animal.printName() #animal
CoffeeScript將我們習(xí)慣性的書寫方式變成豐富的語法糖。說到這里我就想說一句了,能不能把構(gòu)造函數(shù)換個(gè)字符,constructor丫太長了。


繼承
繼承使用的是extends關(guān)鍵字




#編譯前
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函數(shù)解析
我們簡單分析下編譯后的extend函數(shù),對JavaScript原型鏈不是很熟的可以跳過這段。兩個(gè)參數(shù)分別是子類child和父類parent,第一段代碼:


for (var key in parent) {
    if (hasProp.call(parent, key)) child[key] = parent[key];
}
這段代碼就是將父類上面的屬性拷貝到子類上,因?yàn)镴avaScript當(dāng)中函數(shù)也是對象,可以擴(kuò)展屬性的。什么意思?看代碼


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();
可能大家看不大明白,我稍微改動(dòng)下,換種寫法


child.prototype = new parent();
child.prototype.constructor=child;
這里就是我們上面提到的原型鏈繼承。再看最后段代碼:


child.__super__ = parent.prototype;
這里是為了在子類中調(diào)用父類的方法,實(shí)現(xiàn)多態(tài),看下面的例子就知道了。


多態(tài)
編譯后的代碼太長,就不粘貼了,看CoffeeScript代碼更易于學(xué)習(xí)。


直接重寫父類方法
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
重寫父類方法,在重寫的方法中調(diào)用父類方法
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

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)