简体   繁体   English

在JavaScript中扩展功能

[英]extend function in javascript

Ok, long story short, i have 2 classes(functions) and need extend one from second.. In the end of hard day, i wrote simply solution, but then i come home, i thought this is wrong.. But.. Actually it's working, only i don't understand why.. So for example i have 2 functions: 好吧,长话短说,我有2个类(功能),需要从第二个延伸一个..在艰难的一天结束时,我写了简单的解决方案,但后来我回家了,我认为这是错误的..但是..实际上它工作,只有我不明白为什么..所以例如我有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();

After i use this function to merge them: 在我使用此函数合并它们之后:

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

And this is work fine.. so question is why? 这工作正常..所以问题是为什么? I guess in 'merge' function, i just add to first object method of second, but this method used private variable what not defined in first object, why he sees it? 我猜在'merge'函数中,我只是添加第二个的第一个对象方法,但是这个方法使用的私有变量没有在第一个对象中定义,为什么他会看到它?

The r and e values are included in the scope of the method and method2 functions. re值包括在的范围methodmethod2的功能。 Even after these functions are moved around, they still maintain a reference to variables in the scope in which they were defined. 即使在移动这些函数之后,它们仍然保持对定义它们的范围中的变量的引用。 This is called a closure. 这称为闭包。 More: How do JavaScript closures work? 更多: JavaScript闭包如何工作?

Notice that you didn't copy the method2 function from one prototype to another - you added a reference to method2 in aa . 请注意,您没有将method2函数从一个原型复制到另一个原型 - 您在aa添加了对method2的引用。

As long as bb exists, method2 will be able to access bb 's variable e . 只要bb存在, method2就能访问bb的变量e Specially since e was declared in a scope that is visible to method2 . 特别因为e的范围是可见宣布method2

That is basically how closures work. 这基本上是关闭工作的方式。 Your code can be simplified to this: 您的代码可以简化为:

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

This is jQuery's deep copy method they use for their .extend() api 这是jQuery用于.extend()api的深层复制方法

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;
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM