这些代码如何正常运行?

W3G*_*eek 7 javascript prototyping

我之前正在阅读如何"创建一个JavaScript库",我遇到了这些代码,这些代码让我想把我的头发撕掉.

这是让我的大脑处于结的代码:

if (window === this) {
    return new _(id);
}
Run Code Online (Sandbox Code Playgroud)

_(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;
  }
};
Run Code Online (Sandbox Code Playgroud)

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

另一段代码:

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

  show: function () {
           this.e.style.display = 'inherit';
           return this;
  }
};
Run Code Online (Sandbox Code Playgroud)

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

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

Lel*_*son 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"
Run Code Online (Sandbox Code Playgroud)

因此,检查

if (window === this) {
    return new _(id);
}
Run Code Online (Sandbox Code Playgroud)

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


至于你的第二个问题,作者return this;在每个方法的末尾使用一个流畅的界面设计模式

这允许方便和漂亮的对象操作.一个常见的例子是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
});
Run Code Online (Sandbox Code Playgroud)

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

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


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

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

...

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


  • 注意:这里似乎有一些不错的答案[将"泄漏"变量放入全局命名空间](http://stackoverflow.com/questions/5951228/what-is-meant-by-leaking-into-global-scope) .关于它的讨论通常很多,不适合评论:) (2认同)
  • 作为相关代码的作者,我赞同你的答案,并授予你一个upvote. (2认同)

xia*_*owl 6

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