1

簡単に言えば、2 つのクラス (関数) があり、2 番目から 1 つを拡張する必要があります..ハードな一日の終わりに、単純な解決策を書きましたが、家に帰って、これは間違っていると思いました..しかし..実際にはそれは機能していますが、理由がわかりません..たとえば、2つの機能があります。

function aa() {
  var r = "aaaa";
  this.method = function(){
    console.log(r);
  }
}

function bb() {
  var e = "bbbb";
  this.method2 = function(){
    console.log(e);
  }
}

var a = new aa();
var b = new bb();

この関数を使用してそれらをマージした後:

var merge = function(one, two) {
  for(var method in two) {
    one[method] = two[method];
  }
  return one;
}
var c = merge(a, b);

そして、これはうまくいきます..だから質問はなぜですか? 「マージ」関数では、2番目の最初のオブジェクトメソッドに追加するだけだと思いますが、このメソッドは最初のオブジェクトで定義されていないプライベート変数を使用しました。なぜ彼はそれを見るのですか?

4

4 に答える 4

4

randの値は、 and関数eのスコープに含まれます。これらの関数が移動された後でも、定義されたスコープ内の変数への参照が維持されます。これを閉鎖と呼びます。詳細: JavaScript クロージャーはどのように機能しますか?methodmethod2

于 2013-09-05T20:48:53.727 に答える
1

method2関数をあるプロトタイプから別のプロトタイプにコピーしていないことに注意してください。 method2inへの参照を追加しましたaa

bbが存在する限り、の変数method2にアクセスできます。特にが に見えるスコープで宣言されて以来。bbeemethod2

于 2013-09-05T20:49:31.863 に答える
0

それが基本的にクロージャーの仕組みです。コードは次のように簡略化できます。

var bar;
(function foo () {
    var x = 10;
    bar = function () {
        alert(x);
    }
})();

// Now that we're outside of foo:
bar(); // bar can still see "x".

// Even if you do this:
var x = 0;
bar(); // bar still sees x=10
于 2013-09-05T20:51:14.933 に答える
-1

これは、.extend() API に使用する jQuery のディープ コピー メソッドです。

function() {
var src, copyIsArray, copy, name, options, clone,
    target = arguments[0] || {},
    i = 1,
    length = arguments.length,
    deep = false;

// Handle a deep copy situation
if ( typeof target === "boolean" ) {
    deep = target;
    target = arguments[1] || {};
    // skip the boolean and the target
    i = 2;
}

// Handle case when target is a string or something (possible in deep copy)
if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
    target = {};
}

// extend jQuery itself if only one argument is passed
if ( length === i ) {
    target = this;
    --i;
}

for ( ; i < length; i++ ) {
    // Only deal with non-null/undefined values
    if ( (options = arguments[ i ]) != null ) {
        // Extend the base object
        for ( name in options ) {
            src = target[ name ];
            copy = options[ name ];

            // Prevent never-ending loop
            if ( target === copy ) {
                continue;
            }

            // Recurse if we're merging plain objects or arrays
            if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
                if ( copyIsArray ) {
                    copyIsArray = false;
                    clone = src && jQuery.isArray(src) ? src : [];

                } else {
                    clone = src && jQuery.isPlainObject(src) ? src : {};
                }

                // Never move original objects, clone them
                target[ name ] = jQuery.extend( deep, clone, copy );

            // Don't bring in undefined values
            } else if ( copy !== undefined ) {
                target[ name ] = copy;
            }
        }
    }
}

// Return the modified object
return target;
};
于 2013-09-05T20:48:41.397 に答える