关于功能:这个JavaScript语法到目前为止我还没有看过,它真正做到了什么?

This JavaScript syntax I haven't seen till now, what does it do really?

今天我看到了一个我不熟悉的JavaScript语法(在调用函数时)。 它就像:

1
2
3
4
def('Person') ({
  init: function(name) {this.name=name;}
  ,speak: function(text) {alert(text || 'Hi, my name is ' + this.name);}
});

,和

1
2
3
def('Ninja') << Person ({
  kick: function() {this.speak('I kick u!');}
});

1:第一个例子中括号内的对象会发生什么? 它以某种方式由def函数处理,但我不明白这里发生了什么(参见下面的def函数)。 物体在哪里?

2:关于同样的事情,但是使用了我从未见过的<<运算符(我想!)。 那是什么意思?

代码来自http://gist.github.com/474994,其中Joe Dalton做了一个小的JavaScript-OO继承的事情(它显然是别人工作的一个分支,但看起来很彻底改写)。 也许你想在那里查看def函数引用的东西,我在这里给你:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
function def(klassName, context) {
  context || (context = global);

  // Create class on given context (defaults to global object)
  var Klass =
    context[klassName] = function Klass() {

      // Called as a constructor
      if (this != context) {

        // Allow the init method to return a different class/object
        return this.init && this.init.apply(this, arguments);
      }

      // Called as a method
      // defer setup of superclass and plugins
      deferred._super = Klass;
      deferred._plugins = arguments[0] || { };
    };

  // Add static helper method
  Klass.addPlugins = addPlugins;

  // Called as function when not
  // inheriting from a superclass
  deferred = function(plugins) {
    return Klass.addPlugins(plugins);
  };

  // valueOf is called to set up
  // inheritance from a superclass
  deferred.valueOf = function() {
    var Superclass = deferred._super;
    if (!Superclass)
        return Klass;
    Subclass.prototype = Superclass.prototype;
    Klass.prototype = new Subclass;
    Klass.superclass = Superclass;
    Klass.prototype.constructor = Klass;
    return Klass.addPlugins(deferred._plugins);
  };
  return deferred;
}


1:调用def('Person')返回一个函数,该函数以对象作为参数调用。它的原理与:

1
2
3
4
5
function x() {
  return function(y) { alert(y); }
}

x()('Hello world!');

2:<<运算符是左移运算符。它将整数值向左移动特定的位数。我没有找到任何其他用途的参考,并且在Javascript中没有运算符重载,所以我无法理解在函数上使用它。到目前为止,它看起来像是一个错字。

编辑:

正如蒂姆解释的那样,移位运算符仅用于引发对valueOf方法的调用。它就像所有操作员的过载一样,接管了最初的目的并做了一些完全不同的事情。


哇,这让我的小脑子理解得足够复杂,但是现在我知道它是如何工作的我感觉好多了:)感谢@Tim指出valueOf()技巧。

使用以下方法创建"class"的一般情况:

1
2
3
4
def ("ClassName") ({
    init: function() { .. },
    foo: function() { .. }
});

因为第一次调用def会返回一个接受一个对象的函数,并将传入的对象的属性复制到ClassName的原型中,因此是微不足道的。

使用<<子类的更有趣的情况依赖于表达式的求值顺序,以及通过对valueOf()的隐式调用尝试将任何对象强制转换为值。基本技巧基本上是一个共享变量,它记录超类和要应用于它的属性。表达方式,

1
def("ClassName") << ParentClass({ .. })

将评估如下:

  • 调用def("ClassName"),并创建一个全局对象ClassName并返回其构造函数。让我们调用这个返回的对象 - initializeMeLater
  • 调用ParentClass(..),它存储对ParentClass的引用,以及传入的对象/属性在共享变量中。
  • 调用initializeMeLater.valueOf(),它获取对父类的引用,以及该共享变量的属性,并设置原型。
  • 在步骤2的返回值上调用valueOf,这是无用的并且没有效果,因为我们已经在步骤3中设置了超类关系。
  • 代码试图模拟Ruby语法来创建子类,如下所示:

    1
    2
    3
    4
    5
    class Child < Parent
        def someMethod
            ...
        end
    end