coffeeScript学习02

闭包

closure = do ->
  _private = "foo"
  -> _private

console.log(closure()) #=> "foo"

//`do`关键词可以产生一个`Immediate Function`

(function() {
  var closure;

  closure = (function() {
    var _private;
    _private = "foo";
    return function() {
      return _private;
    };
  })();

  console.log(closure());

}).call(this);
  • 闭包中经常需要绑定this的值给闭包的私有变量,CoffeeScript使用特殊的=>语法省去了这个麻烦
element = document.getElementById('id')
@clickHandler = -> alert "clicked"
element.addEventListener "click", (e) => @clickHandler(e)

//
(function() {
  var element;

  element = document.getElementById('id');

  this.clickHandler = function() {
    return alert("clicked");
  };

  element.addEventListener("click", (function(_this) {
    return function(e) {
      return _this.clickHandler(e);
    };
  })(this));

}).call(this);

扩展

  • 在js中,所有的对象都是开放的,有时候会扩展原有对象的行为
String::expends = -> @replace /_/g, "-"

//
(function() {
  String.prototype.expends = function() {
    return this.replace(/_/g, "-");
  };

}).call(this);

class Person 
  _private = 'value'  //private
  @sex: true          //Person.sex
  @log: ->            //Person.log
  	console.log 0

  @create: (name, age)->   
  	new Person(name,age)

  constructor: (@name, @age) ->
  log: ->                     //instance.log
  	console.log @name
  tell: =>                    //instance.tell
  	console.log @age

jinks = new Person('jinks', 23)
jack = Person.create('jack', 22)

  • constructor是构造函数,必须用这个名称

  • 构造函数中如果给实例变量赋值,直接将@name写在参数中即可,等价于在函数体中的@name = name

  • 对于实例方法,要用=>来绑定this,这样可以作为闭包传递

类的继承

class Gadget
  constructor: (@name) ->
  sell: =>
  	"buy #{@name}"

class Iphone extends Gadget
  constructor: -> super("iphone")
  nosell: =>
  	"Don't #{@sell()}"

iphone = new Iphone
iphone.nosell()
  • 使用extends关键字可以继承父类中的所有实例属性,比如sell
  • super方法可以调用父类的同名方法
  • 如果不覆盖constructor,则她被子类默认调用

混入(Mixin)

在ruby语言中的Mixin,能够让你的类获得多个模块的方法,可以说是对多重继承一种很好的实现

class Module
  @extend: (obj) ->
  	for key, value of obj
  	  @[key] = value

  @include: (obj) ->
  	for key, value of obj
  	  @::[key] = value

classProperties = 
  find: (id) ->
  	console.log ("find #{id}")

instanceProperties = 
  save: ->
  	console.log ("save")

class User extends Module
  @extend classProperties
  @include instanceProperties

user = User.find
user = new User
user.save()

  • 继承了Module的类才可以Mixin,当然,这里也可以用组合或者直接为js的构造函数做Monkey patching
  • classProperties是类成员模块,使用@extend来Mixin,实现是简单的拷贝对象的属性
  • instanceProperties是实例成员模块,使用@include来Mixin,实现是拷贝对象原型的属性
  • 需要指出的是,这里的拷贝是引用拷贝,有可能外部会更改被Mixin的模块内部值,更好的方法是深层值拷贝(clone)
posted @ 2015-03-25 16:54  JinksPeng  阅读(148)  评论(0编辑  收藏  举报