zoukankan      html  css  js  c++  java
  • 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)
  • 相关阅读:
    最深叶节点的最近公共祖先
    ML-Agents(十)Crawler
    ML-Agents(九)Wall Jump
    ML-Agents(八)PushBlock
    ML-Agents(七)训练指令与训练配置文件
    Unity Editor扩展编辑器中显示脚本属性
    ML-Agents(六)Tennis
    数据结构(二)—栈
    ML-Agents(五)GridWorld
    ML-Agents(四)3DBall补充の引入泛化
  • 原文地址:https://www.cnblogs.com/jinkspeng/p/4366155.html
Copyright © 2011-2022 走看看