这些代码如何正常运行?

时间:2012-06-15 04:18:43

标签: javascript prototyping

我之前正在阅读如何“创建一个JavaScript库”,我偶然发现了这些代码,这些代码让我想脱掉我的头发。

以下是使我的大脑处于打结状态的代码:

if (window === this) {
    return new _(id);
}

_(id)只是包含此代码的函数名称。如果您需要自己查看代码,请参阅其余代码。

function _(id) {

// About object is returned if there is no 'id' parameter
var about = {
    Version: 0.5,
    Author: "Michael Jasper",
    Created: "Fall 2010",
    Updated: "23 November 2011"
};

if (id) {

    // Avoid clobbering the window scope:
    // return a new _ object if we're in the wrong scope
    if (window === this) {
        return new _(id);
    }

    // We're in the correct object scope:
    // Init our element object and return the object
    this.e = document.getElementById(id);
    return this;
  } else {
    // No 'id' parameter was given, return the 'about' object
    return about;
  }
};

我之前从未见过'返回新功能',但我很想了解它的功能。

另一段代码:

_.prototype = {
  hide: function () {
          this.e.style.display = 'none';
          return this;
  }

  show: function () {
           this.e.style.display = 'inherit';
           return this;
  }
};

我知道这段代码会为_对象添加新方法,但为什么他们会'返回'呢?我试过没有,它工作得很好。

最后一件事,该文章的链接是http://www.mikedoesweb.com/2012/creating-your-own-javascript-library/

2 个答案:

答案 0 :(得分:16)

第一部分代码基本上是试图检测“构造函数”函数的调用方式......

在javascript中,您可以使用函数以两种方式创建对象:

function _(id) {
    this.someProperty = "stuff";
    //Do more stuff to "this"
    return this;
}

//in this scenario, the "this" object will be the window object
var myObject = _(id);
console.log(window.someProperty); //outputs "stuff";
console.log(myObject.someProperty); //outputs "stuff";

//in this scenario, the "this" object is what get's actually returned...
var myObject = new _(id);
console.log(window.someProperty); //outputs "undefined"
console.log(myObject.someProperty); //outputs "stuff"

因此,检查

if (window === this) {
    return new _(id);
}

只是确保您不会在没有new关键字的情况下意外调用构造函数。这将是不好的,因为您将分配给对象的任何属性将立即被分配到window命名空间...这将是坏的。


关于您的第二个问题,作者在每个方法的末尾使用return this;作为fluent interface design pattern

这允许方便和漂亮的对象操作。一个常见的例子是jQuery,你可以将方法链接到一个单独的对象......

$(".some-css-selector").click(function() { 
    ... do something to the selected objects during the "click" event
}).keyup(function() {
    ... do something to the same objects during the "keyup" event
});

编辑:回应W3Geek以下评论的更多信息:

道格拉斯·克罗克福德(Douglas Crockford)的书“Javascript:The Good Parts”(如果你要进入JS,那就完全是一个很好的阅读......只有70页,但每一页都值得一读)。


Javascript的new运算符创建一个从操作数的原型成员继承的新对象,然后调用操作数,将新对象绑定到this。这使得操作数(最好是构造函数)有机会在将新对象返回给请求者之前自定义它。

如果你忘记使用`new运算符,你会得到一个普通的函数调用,它被绑定到全局对象而不是新对象。这意味着当您尝试初始化新成员时,您的函数将破坏全局变量。这是一件非常糟糕的事情。

...

构造函数是旨在与new前缀一起使用的函数。 new前缀基于函数的原型创建一个新对象,并将该对象绑定到隐含this参数的函数。如果忽略使用new前缀,则不会创建新对象,并且this将绑定到全局对象。这是一个严重的错误。


答案 1 :(得分:6)

return this使您能够链接方法调用。你可以做一些非常酷和有用的事情,比如_.show().hide()。 :)