1

高度なオプションを使用して、Closure Compiler で縮小しようとしている製品コードがあります。このコードは、Paul のクライアント側 Cookie ライブラリを使用しています。コンパイラは、次の 30 を超える警告を生成します。

JSC_USED_GLOBAL_THIS: dangerous use of the global this object

以下は、Paul のライブラリからのコード スニペットです (元のコードでは、無名関数ではなく、名前付き関数を使用しています)。

  var cookieObject = function (name, expires, accessPath) {
        var i, j
        this.name = name
        this.fieldSeparator = "#"
        // this.found = false
        this['found'] = false;  // don't allow Closure-Compiler to rename
        this.expires = expires
        this.accessPath = accessPath
        this.rawValue = ""
        this.fields = new Array()
        this.fieldnames = new Array() 
        if (arguments.length > 3) { // field name(s) specified
              j = 0
              for (i = 3; i < arguments.length; i++) {
                    this.fieldnames[j] = arguments[i]    
                    j++
              }
              this.fields.length = this.fieldnames.length 
        }
        this.read = ucRead            // function assignments
        this.write = ucWrite
        this.remove = ucDelete
        this.get = ucFieldGet
        this.put = ucFieldPut
        this.namepos = ucNamePos
        this.read()
  }; // cookieObject

uc関数は通常、次のように構成されます。

  var ucRead = function () {
        var search = this.name + "="
        var CookieString = document.cookie
        this.rawValue = null
        this.found = false
  }

「this」キーワードは JavaScript オブジェクト リテラル内でどのように機能しますか?を読みました。同様にClosure Compiler グローバルな「this」オブジェクトの危険な使用について警告しますか? およびJavaScript の Scopethisただし、上記のコードのスコープが何であるか、コンパイラの警告を排除するためにこのコードを書き直す方法はまだわかりません。

Q1: 誰かが私のためにスコープが何であるかを明確にすることができますかthis?

Q2: 上記を書き直してコンパイラの警告をなくす方法を示すコード スニペットを提供してもらえますか (の使用をthisなくす必要があると思います)。

ティア。

4

1 に答える 1

2

の範囲thisは、基本的に予測不可能です。関数がその特定thisの呼び出しで呼び出されているコンテキストを参照します。例えば:

var foo = function()//or function foo()
{
    console.log(this);
};
foo();//logs the window object
var anObj = {name:'someObject',method:foo};
anObj.method();//logs `anObj`

基本は簡単です:

[[someObject]].function();//call func
    /\            ||
    ||  implicit  ||
    |______________|

最初の例では明示的な所有者オブジェクトがなかったため、JS はデフォルトでグローバル オブジェクトにフォールバックします。(使用時を除くstrict mode)。2 番目の例では、オブジェクトから呼び出されるメソッドとして foo が使用されているため、thisそのオブジェクトを参照しています。

さて、これはすべて非常に簡単ですが、this参照がアドホックに決定され、関数がJS ( ) で緩やかにバインドされていることを考えると、これ常に期待するものを指すArray.prototype.slice.apply(arguments,[0]);という保証はありません。ECMAScript 5 はその方法を提供し、特定のコンテキストを関数オブジェクトにバインドできるようにします。また、これは長い間存在する「問題」であり、人々はさまざまな回避策を使用してきました。最も簡単なのはクロージャーの使用です。
bind

var MyConstructor = function()
{
    "use strict";//in strict mode, this'll throw errors when called without new keyword
    if (this === window || !this)
    {
        throw 'Omitted new keyword in older browsers, that don\'t support strict mode';
    }
    var that = this;//create closure reference to the new instance
    that.someProperty = 'Use that instead of this';
    that.especially = function()
    {
        console.log(this === that);//see later
        console.log('especially in methods, because they can be borrowed, at which point `this` could reference anything, but here: ' + that + ' Will always be what you expect');
    };
}
var foo = new MyConstructor();
foo.especially();//logs true, and 'especially in methods ...'
bar = [];
foo.especially.apply(bar,[]);//logs false, but the second log will still be the same
于 2012-10-28T14:12:17.597 に答える