这个 JavaScript 语法我到现在都没见过,它到底有啥作用?

Posted

技术标签:

【中文标题】这个 JavaScript 语法我到现在都没见过,它到底有啥作用?【英文标题】:This JavaScript syntax I haven't seen till now, what does it do really?这个 JavaScript 语法我到现在都没见过,它到底有什么作用? 【发布时间】:2011-03-15 19:26:07 【问题描述】:

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

def('Person') (
  init: function(name) this.name=name;
  ,speak: function(text) alert(text || 'Hi, my name is ' + this.name);
);

,和

def('Ninja') << Person (
  kick: function() this.speak('I kick u!');
);

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

2:同样的事情,但使用了我从未见过的&lt;&lt; 运算符(我想!)。这是怎么回事?

代码来自http://gist.github.com/474994,Joe Dalton 在那里做了一个小的 JavaScript-OO-inheritance 事情(它显然是别人工作的一个分支,但看起来相当彻底地重写了)。也许您想在那里查看def 函数引用的内容,我在这里给您:

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;

【问题讨论】:

原文好像是Tobias Schneiders github.com/tobeytailor/def.js 【参考方案1】:

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

function x() 
  return function(y)  alert(y); 


x()('Hello world!');

2:&lt;&lt; 运算符是左移运算符。它将整数值向左移动特定位数。我还没有找到任何其他用途的参考,并且 Javascript 中没有运算符重载,所以我无法在函数上使用它。到目前为止,这对我来说似乎是一个错字。

编辑:

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

【讨论】:

啊,当然。整洁的。谢谢。但是运营商的事情呢? @npup:我无法理解运营商的事情。看看我在上面的补充。 操作员(其基本用法对我来说并不陌生):是的,它看起来很奇怪。也许它只是在这里用来使子类声明看起来像某种方式的无操作?嗯。感谢您的回答! 返回的对象已经定义了函数valueOf,该函数在对象左移时调用。显然 valueOf 他们能够劫持左移操作来执行超类,同时获得漂亮的语法。我想你可以换掉另一个在两个对象上调用 valueOf 的运算符并获得类似的效果。 @Guffa:该代码似乎确实是操作员滥用的极端案例......诚然,我希望我永远不会在其他任何地方看到它,呵呵,但我确信这是一厢情愿的想法。 【参考方案2】:

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

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

def ("ClassName") (
    init: function()  .. ,
    foo: function()  .. 
);

很简单,因为对def 的第一次调用会返回一个接受对象的函数,并将传入对象的属性复制到ClassName 的原型中。

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

def("ClassName") << ParentClass( .. )

将按如下方式评估:

    def("ClassName") 被调用,并创建一个全局对象ClassName 并返回其构造函数。我们称这个返回的对象 - initializeMeLaterParentClass(..) 被调用,它将对 ParentClass 的引用以及传入的对象/属性存储在共享变量中。 initializeMeLater.valueOf() 被调用,它获取对父类的引用,以及来自该共享变量的属性,并设置原型。 valueOf 在步骤 2 的返回值上被调用,这是无用的,没有任何效果,因为我们已经在步骤 3 中设置了超类关系。

代码试图模拟 Ruby 语法来创建子类,如下所示:

class Child < Parent
    def someMethod
        ...
    end
end

【讨论】:

以上是关于这个 JavaScript 语法我到现在都没见过,它到底有啥作用?的主要内容,如果未能解决你的问题,请参考以下文章

竟然还有带气垫的 React Element 87!这几双鞋你都没见过!

你没见过的python语法

sql SQL语法我以前没见过

见过一个一个拉新地推没见过这么多一起推

见过一个一个拉新地推没见过这么多一起推

函数调用时,参数带形参及冒号