CodeWeblog.com » implementation,quot,variables » js closure on

js closure on

Understanding of JavaScript closures

To become advanced JavaScript programmers, it is necessary to understand the closure.

In this paper, ECMA 262 specification explain the closure of the internal working mechanism for JavaScript programmers understanding of the closure from the "nested function" into "identifier resolution, the implementation of environmental and scope chain" and so on JavaScript object operating mechanism behind them, and truly comprehend the essence of the closure.

Printable Version: JavaScript closure brief introduction directory object name to resolve the value of property given to the value of the read identifier resolution, the implementation of environmental and scope chain implementation of environmental scope chain and [[scope]]
Analysis of closure identifier ARCS constitute closure through the closure can be done?
Example 1: In order to set the delay function invoked Example 2: The correlation function object instance method Example 3: Packaging-related functions of other examples of unexpected closure
Internet Explorer Memory Leak Problem

Brief introduction

Closure
The so-called "closure" refers to a lot of variables and bindings of these variables in the expression of the environment (usually a function), and thus these variables are also part of the expression.

Closure are ECMAScript (JavaScript) features one of the most powerful, but make good use of closure on the premise that it must be understood that closure. Closure creation is relatively easy, people will even inadvertently create a closure, but they do not intend to create the closure there are potential hazards, especially in the more common browser environment. If you want closure扬长避短use this feature, you must understand their working mechanisms. The working mechanism of closure of the implementation to a large extent depends on the identifier (or object property) to resolve the role of process scope.

About closure, the simplest description is to permit the use of internal ECMAScript function - that is, function definition and function expression of the function at another function in vivo. Moreover, these internal functions can access them where the external function declarations for all local variables, parameters and declarations other internal functions. When one of such an internal function that contains them outside of the external function is called, will lead to closure. In other words, the internal function will return after the implementation of external functions. And when the implementation of the internal function, it is still necessary to visit their external function local variables, parameters, as well as other internal functions. These local variables, parameters and function declarations (initially) the value of an external function value at the time of return, but it can also affect the internal functions.

Unfortunately, it is necessary to properly understand the closure must be understood on the closure of the mechanism behind the operation, as well as many technical details related. Although this article and the first half of the ECMA 262 specification does not address some of the specified algorithm, but there is still much can not be avoided or simplified content. Individual familiar with the object property name resolution for those who can skip the relevant content, but unless you are very familiar with the closure, otherwise it is best not to skip the following sections.

Object property name resolution

ECMAScript recognized two types of objects: Native (Native) objects and the host (Host) object, one of the host object contains a built-in objects known as the original sub-class object (ECMA 262 3rd Ed Section 4.3). Students who belong to the original language, while the host object by the environment, for example, may be the document object, DOM and other similar objects.

The original object with a loose and dynamic property name (for implementation of certain sub-categories of built-in objects, the dynamic nature are limited - but this is not too big a problem). Naming objects for the preservation of property value, which can be point to another object (Objects) reference (in this sense, the function is the object) or some basic data types, such as: String, Number, Boolean , Null or Undefined. Are one of rather exceptional Undefined type, because they can give the object Undefined property to specify a type of value, and will not delete the corresponding object property. Moreover, the property is kept undefined value.

Below is a brief introduction about how to set up and read the object property values, and to maximize the corresponding embodiment of the internal details.

Value given

Naming objects for the named property can be assigned to create a property or re-assignment. That is, for:

var objectRef = new Object (); / / create a normal JavaScript object.

By the following statement to create called "testNumber" of the property:

Java code

  1. objectRef.testNumber = 5;
  2. / * - Or - * /
  3. objectRef [ "testNumber"] = 5;

objectRef.testNumber = 5;
/* - 或- */
objectRef["testNumber"] = 5;


In the assignment before the object is not "testNumber" property, but after the assignment, then the creation of a property. After any assignment statements are not required to create this property, but they would only re-set its value:

Java code

  1. objectRef.testNumber = 8;
  2. / * - Or: - * /
  3. objectRef [ "testNumber"] = 8;

objectRef.testNumber = 8;
/* - or:- */
objectRef["testNumber"] = 8;


Later on, we will introduce, Javascript has a prototype object (prototypes) property, which itself is a prototype object, which can also be a named property. However, the prototype of the role of the object named property is not reflected in the assignment stage. Similarly, at the value assigned to its name property, if the object is not the property will create the named property, or else they will reset the property value.

Value read

When reading the object property value, the role of the prototype object will be reflected. If the object is included in the prototype property accessor (property accessor) used by property name, then the value of the property will return:

Java code

  1. / * Assignment for the named property. If the object does not pre-assign the corresponding property, then after the assignment will be a: * /
  2. objectRef.testNumber = 8;
  3. / * Read from the property value * /
  4. var val = objectRef.testNumber;
  5. / * Now, - val - Medium preserved object naming just assign the value of property 8 * /

/* 为命名属性赋值。如果在赋值前对象没有相应的属性,那么赋值后就会得到一个:*/
objectRef.testNumber = 8;

/* 从属性中读取值 */
var val = objectRef.testNumber;

/* 现在, - val - 中保存着刚赋给对象命名属性的值 8*/


Moreover, because of all the objects have a prototype, and the prototype itself is the object, so the prototype could also have a prototype, and this constitutes the so-called prototype chain. Prototype chain termination in the prototype chain for the null object. Object of the default constructor, a null prototype prototype, so:

Java code

  1. var objectRef = new Object (); / / create a normal JavaScript object.

var objectRef = new Object(); //创建一个普通的 JavaScript 对象。


Created a prototype for Object.prototype object, and the prototype itself will have a value of null prototype. In other words, objectRef prototype chain contains only one object - Object.prototype. But for the purposes of the following code:

Java code

  1. / * Create - MyObject1 - the type of object function * /
  2. function MyObject1 (formalParameter) (
  3. / * Create the object to add a name - testNumber - the property
  4. And passed to the constructor's first parameter specifies the property's value: * /
  5. this. testNumber = formalParameter;
  6. )
  7. / * Create - MyObject2 - the type of object function * /
  8. function MyObject2 (formalParameter) (
  9. / * Create the object to add a name - testString - the property
  10. And passed to the constructor's first parameter specifies the property's value: * /
  11. this. testString = formalParameter;
  12. )
  13. / * The next operation MyObject1 category with examples of the replacement of all the categories and examples of MyObject2 associated prototype. Moreover, for the transmission of MyObject1 constructor parameters - 8 - and therefore - testNumber - have been given the property value: * /
  14. MyObject2.prototype = new MyObject1 (8);
  15. / * Finally, there will be a string as a constructor of the first parameter, create a - MyObject2 - examples, and point to the object reference is assigned to the variable - objectRef -: * /
  16. var objectRef = new MyObject2 ( "String_Value");

/* 创建 - MyObject1 - 类型对象的函数*/
function MyObject1(formalParameter){
/* 给创建的对象添加一个名为 - testNumber - 的属性
并将传递给构造函数的第一个参数指定为该属性的值:*/
this.testNumber = formalParameter;
}
/* 创建 - MyObject2 - 类型对象的函数*/
function MyObject2(formalParameter){
/* 给创建的对象添加一个名为 - testString - 的属性
并将传递给构造函数的第一个参数指定为该属性的值:*/
this.testString = formalParameter;
}

/* 接下来的操作用 MyObject1 类的实例替换了所有与 MyObject2 类的实例相关联的原型。而且,为 MyObject1 构造函数传递了参数 - 8 - ,因而其 - testNumber - 属性被赋予该值:*/
MyObject2.prototype = new MyObject1( 8 );

/* 最后,将一个字符串作为构造函数的第一个参数,创建一个 - MyObject2 - 的实例,并将指向该对象的引用赋给变量 - objectRef - :*/
var objectRef = new MyObject2( “String_Value” );


Was variable objectRef cited examples of MyObject2 have a prototype chain. The chain's first in the creation of an object are MyObject2 was assigned to the constructor's prototype property MyObject1 of a case in point. MyObject1 examples also have a prototype, that is, with the object of quoted Object.prototype corresponding default Object prototype object. Finally, Object.prototype has a value of null prototype, so that the end of the prototype chain.

When a property accessor attempts to read from objectRef cited object property value, the entire prototype chain will be english. In the following simple case:

var val = objectRef.testString;

Since objectRef cited examples of MyObject2 have a "testString" of the property, it is set to "String_Value" the value of the property was assigned to the variable val. However:

Java code

  1. var val = objectRef.testNumber;

var val = objectRef.testNumber;


While MyObject2 examples from their own should not be read to the corresponding named property value, because the examples do not have this property. However, the value of the variable val is still set to 8, rather than undefined - This is because in the instance of the corresponding named property search failed to explain the procedure will continue to check its prototype object. The prototype object instances are examples of MyObject1, this example has a "testNumber" the property and a value of 8, so the property accessor to obtain the final value will be 8. Moreover, although MyObject1 and MyObject2 are not defined toString method, but when the property accessor objectRef read through the toString value of the property:

Java code

  1. var val = objectRef.toString;

Then, the distribution of scope for the implementation of the environment. Scope from the target list (chain) components. Each function object has an internal [[scope]] property (the property we will go into the detail later), this property from the target list (chain) components. Assigned to a function call to implement the scope of the environment by the object function [[scope]] property of the referenced object list (chain) comprising at the same time, the activities of the target object was added to the top of the list (the front-end chain ).

It will happen by the ECMA 262 in the so-called "variable" object to complete the "variable instantiation" process. Events at this time the object is only used as a variable object (in this case is very important, please note: they are the same object). At this point the form will function as the variable parameters to create the object named property, if the function is called when the transmission line parameters and form parameters, the corresponding value of the parameter will be assigned to these naming attributes (Otherwise, the property will be named given the value undefined ). For the definition of the internal functions, its statement will be used when the name of the variable object property to create the same name and the corresponding internal function was created for the function object and assign to the property. Variable instantiation of the final step is to function at an internal statement of all local variables to create variable object for the property name.

According to a statement of the local variables created variable object property in the process of variable instantiation will be given the undefined value. Function in vivo in the implementation of the code, and calculate the corresponding expression before the assignment will not be local variables of the implementation of real examples.

In fact, with arguments object and property activities with function local variables corresponding to the variable object property names are the same object. Therefore, arguments can be the identifier of the local variables as the function to look at.

Finally, we must use this keyword for the assignment. If the value given by an object reference, then the prefix to this keyword property accessor is to invoke the object's property. If the given (internal) value is null, then this keyword is cited global object.

Create the overall implementation of the environmental process will be slightly different, because it does not have parameters, so no need for the adoption of the definition of the activities of the object to invoke these parameters. However, the overall implementation of the environment also need to have a scope, but in fact it's scope chain by only one object - global object - component. The overall implementation of environmental variables will also have examples of the process, its internal function that is involved in most of JavaScript code, the conventional top-level function declaration. Moreover, in the process of variable instantiation is a global object variable object, which is why overall function declarations are the causes of global object property. Overall statement of the variables the same.

The overall implementation of the environment may also use this object to invoke the global object.

Scope chain with the [[scope]]

Call function to create the execution environment will include a scope chain, the scope chain is through the implementation of environmental activities (variable) is added to the object stored in the object function is called [[scope]] property of the scope chain consisting of front-end. Therefore, understanding the target function within the [[scope]] property essential to the definition of the process.

In ECMAScript, the function is also a target. Function objects in the variable instantiation process to create a function declaration in accordance with, or are in the calculation of function expression or constructor function Function call to create.

By calling the Function constructor to create a function object, its internal [[scope]] property referenced scope chain always contains only global object.

Through the function declaration or function expression to create a function object, its internal [[scope]] property cited is the creation of their scope chain execution environment.

At the simplest cases, such as the following statement on global function: --

Java code

  1. function exampleFunction (formalParameter) (
  2. ... / / Function body code
  3. )

function exampleFunction(formalParameter){
… // 函数体内的代码
}


- When to create the overall implementation of the environment variable instantiation will function in accordance with the above statements to create the corresponding function objects. Since the overall implementation of the environmental scope chain contains only global object, so it created for himself, and called "exampleFunction" of the property cited in the function object's internal [[scope]] property, given the overall situation contains only scope chain object.

When calculated at the overall situation of the environment function expression, it will also happen similar to the designated scope of the process chain: --

Java code

  1. var exampleFuncRef = function () (
  2. ... / / Function body code
  3. )

var exampleFuncRef = function(){
… // 函数体代码
}


In this case, the difference is in the overall implementation of the environment variable instantiation process, will create a global object for the named property. And assignment statements in the calculation of the time being until the creation of function objects is not, nor will the function object reference assigned to the global object naming property. However, ultimately the overall execution environment will create the function object (when calculating the function expression when. Translator's Note), and for the creation of a function of the object [[scope]] property designated scope chain still contains only global object. Within the function declaration or expression that contains lead in their implementation of external functions to create an environment corresponding function objects, these objects function scope chain would be slightly more complicated. In the following code defines a first internal function declaration with external functions, then call the external function:

Java code

  1. / * Create a global variable - y - it quoted an object: - * /
  2. var y = (x: 5); / / with a property - x - the object of a direct volume
  3. function exampleFuncWith () (
  4. var z;
  5. / * The global object - y - referenced object added to the scope chain of the front-end: - * /
  6. with (y) (
  7. / * Evaluation of the function expression to create a function object and the function object is assigned to local variables - z -: - * /
  8. z = function () (
  9. ... / / Internal function expression of the code;
  10. )
  11. )
  12. ...
  13. )
  14. / * Implementation - exampleFuncWith - function: - * /

 /* 创建全局变量 - y - 它引用一个对象:- */
var y = {x:5}; // 带有一个属性 - x - 的对象直接量
function exampleFuncWith(){
  var z;
  /* 将全局对象 - y - 引用的对象添加到作用域链的前端:- */
  with(y){
  /* 对函数表达式求值,以创建函数对象并将该函数对象的引用指定给局部变量 - z - :- */
  z = function(){
  ... // 内部函数表达式中的代码;
  }
}
...
}
/* 执行 - exampleFuncWith - 函数:- */


exampleFuncWith (); at exampleFuncWith function call to create the execution environment contains a target followed by its activities constitute a global object scope chain. With statements in the implementation of the same time, global variables will be the object y references added to the front of the scope chain. At one of the function expression of the evaluation process, the creation of the object function [[scope]] property and the creation of its scope the implementation of the environment in line - that is, the property would be invoked by the object y followed by a call to the external function execution environment created by the activities of the target, followed by global object scope chain.

When and with statements related to the implementation of the statement block at the end of the scope of the implementation of the environment to restore (y will be removed), but have created a function object (z. Translator Note) [[scope]] property cited scope chain is located at the top is still the object y.

Example 3: Packaging-related functions

Closure can be used to create extra scope, through the scope can be related and dependent code to organize themselves in order to keep accidents to a minimum the risk of interaction. Assuming there is a string used to build a function to connect in order to avoid repetitive operations (and the creation of a large number of middle string), our desire is to use an array in order to store the various parts of the string, and then use the Array. prototype.join Ways (to empty string as its parameter) output. This array will serve as the output buffer, but will be an array as a function of local variables will lead to function at each call when they re-create a new array, which function at each call, only to re-designate an array of variable content circumstances is not necessary.

One solution is to this statement for the global variable array so that you can reuse the array, without having to set up a new array every time. However, the results of this program are, in addition to the global variable reference function will use the buffer array, but also many a global array to quote their own property. So not only become easier to manage code, and at other places If you want to use this array, the developer must be re-defined functions and arrays. In this way, also makes the code is not easy to integrate with other code, because at this time not only to ensure that the use of the function names in the global namespace is the only, but also to ensure that rely on an array of functions at global namespace also must be unique.

Through the closure allows the array as a buffer and to rely on its function associated with (gracefully packing), but also be able to maintain the global namespace outside the designated buffer array of property name, the name of eliminating conflicts and accidents interaction dangerous.

One of the key skills is through the implementation of a one-way (in-line) function expression to create an additional execution environment, and the function expression of an internal function as a back at the use of external code function. At this point, the buffer array is defined as the function expression of a local variable. The function expression only once, while the array is only created once, you can rely on it for a function of repeated use.

The following code defines a function, the function used to return a HTML string, most of which the content of these constants, but they need constant sequence of characters interspersed some variable information, and the variable information from the call when the transfer function parameters provided.

Through the implementation of one-way function expression of an internal function back, and will return the function assigned to a global variable, so this function can also be known as global function. The buffer array is defined as an external function expression of a local variable. It will not exposed to the global namespace, but any time a function call to rely on it do not need to re-create the array.

Java code

  1. / * Declare a global variable - getImgInPositionedDivHtml --
  2. And a call to an external function expression function assigned to the internal return it.
  3. This internal function will return one for the express absolute positioning DIV element
  4. Surrounded by an IMG element of HTML strings, so that
  5. All variable property value by calling the function parameters to provide:
  6. * /
  7. var getImgInPositionedDivHtml = (function () (
  8. / * External function expression of the local variables - buffAr - kept the array buffer.
  9. This array will be created once, to generate an array of examples of internal functions are available in terms of Forever
  10. Therefore, for each call to use this internal function.
  11. One of the empty string placeholder for the data, the corresponding data
  12. Internal function to be inserted into this array:
  13. * /
  14. var buffAr = [
  15. '<div id = &quot;',
  16. '', / / Index 1, DIV ID property
  17. ' &quot;Style =&quot; position: absolute; top:',
  18. '', / / Index 3, DIV at the top position
  19. 'px; left:',
  20. '', / / Index 5, DIV left position
  21. 'px; width:',
  22. '', / / Index 7, DIV width
  23. 'px; height:',
  24. '', / / Index 9, DIV height
  25. 'px; overflow: hidden; \ &quot;> <img src = \&quot;',
  26. '', / / Index 11, IMG URL
  27. '\ &quot;Width = \&quot;',
  28. '', / / Index 13, IMG width
  29. '\ &quot;Height = \&quot;',
  30. '', / / Index 15, IMG height
  31. '\ &quot;Alt = \&quot;',
  32. '', / / Index 17, IMG alt text
  33. '\ &quot;> </ div>'
  34. ];
  35. / * Return as a function expression is evaluated after the results of the internal function object.
  36. This internal function is a function of the implementation of each call
  37. - GetImgInPositionedDivHtml (...) --
  38. * /
  39. return (function (url, id, width, height, top, left, altText) (
  40. / * Different parameter buffer array inserted into the corresponding position: * /
  41. buffAr [1] = id;
  42. buffAr [3] = top;
  43. buffAr [5] = left;
  44. buffAr [13] = (buffAr [7] = width);
  45. buffAr [15] = (buffAr [9] = height);
  46. buffAr [11] = url;
  47. buffAr [17] = altText;
  48. / * Return by using the empty string (equivalent to connect the array elements)
  49. Connecting each element of the array after the string formation:
  50. * /
  51. return buffAr.join ('');
  52. )); / /: The End of internal function expression.
  53. })();
  54. /*^^-: Single external function expression. * /

/* 声明一个全局变量 - getImgInPositionedDivHtml -
并将一次调用一个外部函数表达式返回的内部函数赋给它。      

   这个内部函数会返回一个用于表示绝对定位的 DIV 元素
   包围着一个 IMG 元素 的 HTML 字符串,这样一来,
   所有可变的属性值都由调用该函数时的参数提供:
*/
var getImgInPositionedDivHtml = (function(){
    /* 外部函数表达式的局部变量 - buffAr - 保存着缓冲数组。
     这个数组只会被创建一次,生成的数组实例对内部函数而言永远是可用的
     因此,可供每次调用这个内部函数时使用。      

    其中的空字符串用作数据占位符,相应的数据
    将由内部函数插入到这个数组中:
    */
    var buffAr = [
        '<div"',
        '',   //index 1, DIV ID 属性
        '""position:absolute;top:',
        '',   //index 3, DIV 顶部位置
        'px;left:',
        '',   //index 5, DIV 左端位置
        'px;width:',
        '',   //index 7, DIV 宽度
        'px;height:',
        '',   //index 9, DIV 高度
        'px;overflow:hidden;\"><img src=\"',
        '',   //index 11, IMG URL
        '\" width=\"',
        '',   //index 13, IMG 宽度
        '\" height=\"',
        '',   //index 15, IMG 高度
        '\" alt=\"',
        '',   //index 17, IMG alt 文本内容
        '\"></div>'
    ];
    /* 返回作为对函数表达式求值后结果的内部函数对象。
     这个内部函数就是每次调用执行的函数
	- getImgInPositionedDivHtml( ... ) -
    */
    return (function(url, id, width, height, top, left, altText){
        /* 将不同的参数插入到缓冲数组相应的位置:*/
        buffAr[1] = id;
        buffAr[3] = top;
        buffAr[5] = left;
        buffAr[13] = (buffAr[7] = width);
        buffAr[15] = (buffAr[9] = height);
        buffAr[11] = url;
        buffAr[17] = altText;
        /* 返回通过使用空字符串(相当于将数组元素连接起来)
	连接数组每个元素后形成的字符串:
        */
        return buffAr.join('');
    }); //:内部函数表达式结束。
})();
/*^^- :单行外部函数表达式。*/


If a function relies on another (or more) other functions, while other functions were also there is no need to directly call other code, then the same technology can be used to package these functions, and through an open exposure function to call them. In this way, will be a complex function of many has become a package deal with the process of a transplant unit of code.
Other examples

Packet has a turn off is probably the most well-known applications are Douglas Crockford's technique for the emulation of private instance variables in ECMAScript objects. Such applications can be extended to a variety of nested includes accessibility (or visibility) of the scope structure, including the emulation of private static members for ECMAScript objects.

Closure possible uses are limitless, you may understand its working principle is to grasp how to use it the best guide.

Accident closure

In the creation of the internal functions can access the function outside the body to resolve the internal function would constitute a closure. This indicates that the closure can easily be created, but so may lead to an outcome that fails to recognize that closure is a characteristic of the JavaScript language authors, will be in accordance with its internal function to complete multiple tasks to use the internal function of mind. However, they use an internal function of the results are not clear, but less than the creation of the fundamental sense of closure, or what it means to do so.

As the next section, talking about memory leaks in IE when the problem mentioned, the accident created closures could lead to serious adverse effects, but also affect the performance of the code. The problem is not the closure itself, if truly be able to use them carefully, but will help to create efficient code. In other words, the use of an internal function will affect the efficiency.

The most common use of the internal function of a situation is as DOM elements case processor. For example, the following code for a link element to add onclick event handler:

/ * Define a global variable through the following function to its value as part of query string added to the link - href - Medium:
* /
var quantaty = 5;
/ * When this function to send a link (as a function of the parameters - linkRef -) when
An onclick event handler will be assigned to the link, the Event Processor to global variables - quantaty - the value as string added to the link - href --
Property, and then return true to make the link in the post-click positioning by the - href --
Property included in the query string specified resources:
* /

Java code

  1. function addGlobalQueryOnClick (linkRef) (
  2. / * If the parameters can be - linkRef - through type conversion for ture
  3. (Note that it quoted an object):
  4. * /
  5. if (linkRef) (
  6. / * For a function expression is evaluated, and the function object reference
  7. Assigned to the link element onclick event handler:
  8. * /
  9. linkRef.onclick = function () (
  10. / * This internal function expression to query string
  11. Additional processors added to the case of the elements - href - property in:
  12. * /
  13. this. href + = ( '? quantaty =' + escape (quantaty));
  14. return true;
  15. );
  16. )
  17. )

function addGlobalQueryOnClick(linkRef){
    /* 如果可以将参数 - linkRef - 通过类型转换为 ture
      (说明它引用了一个对象):
    */
    if(linkRef){
        /* 对一个函数表达式求值,并将对该函数对象的引用
           指定给这个链接元素的 onclick 事件处理器:
        */
        linkRef.onclick = function(){
            /* 这个内部函数表达式将查询字符串
               添加到附加事件处理器的元素的 - href - 属性中:
            */
            this.href += ('?quantaty='+escape(quantaty));
            return true;
        };
    }
}


Whenever addGlobalQueryOnClick function call will create a new internal function (through the assignment constitutes a closure). From the efficiency point of view, if only one or two calls addGlobalQueryOnClick function and impede Nothing big, but if frequent use of the function, will lead to the creation of lot of different function objects (each of the internal function expression for a value, will produce a new function object).

Above example the code is not concerned about the internal function in the creation of its functions can access external (or constitute a closure) this fact. In fact, the same effect can be another way to complete. That is, to define a separate processor for the case of the function, then invoke the function assigned to the case deal with property elements. In this way, simply create a function object, and all processors use the same case elements can be shared on the function reference:

Java code

  1. / * Define a global variable through the following function to its value
  2. As part of the query string added to the link - href - Medium:
  3. * /
  4. var quantaty = 5;
  5. / * When a link (as a function of the parameters - linkRef -) passed to this function,
  6. This link will add a onclick event handler, the processor will be case
  7. To global variables - quantaty - the value as part of query string added to the
  8. Link - href - Medium, and then return true, so click the link by positioning
  9. As the - href - property values specified in the query string resources:
  10. * /
  11. function addGlobalQueryOnClick (linkRef) (
  12. / * If - linkRef - parameters can type is converted to true
  13. (Note that it quoted an object):
  14. * /
  15. if (linkRef) (
  16. / * Will be a global function reference assigned to this link
  17. Deal with the case property, so that function to become link elements Case Processor:
  18. * /
  19. linkRef.onclick = forAddQueryOnClick;
  20. )
  21. )
  22. / * Declare a global function, as a link element case processor,
  23. This function will be a global variable's value to be added as a case processor
  24. Link element - href - the value of a part of:
  25. * /
  26. function forAddQueryOnClick () (
  27. this. href + = ( '? quantaty =' + escape (quantaty));
  28. return true;
  29. )

/* 定义一个全局变量,通过下面的函数将它的值
   作为查询字符串的一部分添加到链接的 - href - 中:
*/
var quantaty = 5;
/* 当把一个链接(作为函数中的参数 - linkRef -)传递给这个函数时,
   会给这个链接添加一个 onclick 事件处理器,该事件处理器会
   将全局变量  - quantaty - 的值作为查询字符串的一部分添加到
   链接的 - href -  中,然后返回 true,以便单击链接时定位到由
   作为 - href - 属性值的查询字符串所指定的资源:
*/
function addGlobalQueryOnClick(linkRef){
    /* 如果 - linkRef - 参数能够通过类型转换为 true
    (说明它引用了一个对象):
    */
    if(linkRef){
        /* 将一个对全局函数的引用指定给这个链接
           的事件处理属性,使函数成为链接元素的事件处理器:
        */
        linkRef.onclick = forAddQueryOnClick;
    }
}
/* 声明一个全局函数,作为链接元素的事件处理器,
   这个函数将一个全局变量的值作为要添加事件处理器的
   链接元素的  - href - 值的一部分:
*/
function forAddQueryOnClick(){
    this.href += ('?quantaty='+escape(quantaty));
    return true;
}


In the above example the first version, the internal function as the closure does not play its due role. In that case, it is not more efficient use of closure, because do not create a lot of duplicate essentially the same function object.

Similar considerations apply equally to the object constructor. With the following code in the framework of a similar constructor code is not uncommon:

Java code

  1. function ExampleConst (param) (
  2. / * By function expression is evaluated to create the object method,
  3. And evaluation function from the object reference is assigned to create the object property:
  4. * /
  5. this. method1 = function () (
  6. ... / / Method body.
  7. );
  8. this. method2 = function () (
  9. ... / / Method body.
  10. );
  11. this. method3 = function () (
  12. ... / / Method body.
  13. );
  14. / * The constructor parameters assigned to the object of a property: * /
  15. this. publicProp = param;
  16. )

function ExampleConst(param){
    /* 通过对函数表达式求值创建对象的方法,
      并将求值所得的函数对象的引用赋给要创建对象的属性:
    */
    this.method1 = function(){
        ... // 方法体。
    };
    this.method2 = function(){
        ... // 方法体。
    };
    this.method3 = function(){
        ... // 方法体。
    };
    /* 把构造函数的参数赋给对象的一个属性:*/
    this.publicProp = param;
}


Every time through the new ExampleConst (n) use the constructor to create an object, it will create a set of new, object-oriented method as a function of the object. Therefore, the object instance to create more a function of the corresponding object is also more.

Douglas Crockford proposed private members imitate JavaScript object technology, on the use of the internal function at the reference assigned to the object constructor in the structure of public property and the formation of the closure. If the object did not make use of structural function in the formation of closure, then instantiate each object created when a number of function objects, examples of the process will slow down, but will also have more resources to be occupied to meet the create more of the required function objects.

This is the kind of circumstances, only to create a function object, and put them assigned to the corresponding constructor prototype property is clearly more efficient. In this way, they can be constructor create all objects in shared:

Java code

  1. function ExampleConst (param) (
  2. / * The constructor parameters assigned to the object of a property: * /
  3. this. publicProp = param;
  4. )
  5. / * By function expression is evaluated and the results function object reference
  6. Assigned to the constructor's prototype property to create the corresponding object method:
  7. * /
  8. ExampleConst.prototype.method1 = function () (
  9. ... / / Method body.
  10. );
  11. ExampleConst.prototype.method2 = function () (
  12. ... / / Method body.
  13. );
  14. ExampleConst.prototype.method3 = function () (
  15. ... / / Method body.
  16. );

function ExampleConst(param){
    /* 将构造函数的参数赋给对象的一个属性:*/
    this.publicProp = param;
}
/* 通过对函数表达式求值,并将结果函数对象的引用
      指定给构造函数原型的相应属性来创建对象的方法:
*/
ExampleConst.prototype.method1 = function(){
    ... // 方法体。
};
ExampleConst.prototype.method2 = function(){
    ... // 方法体。
};
ExampleConst.prototype.method3 = function(){
    ... // 方法体。
};


Internet Explorer Memory Leak Problem

Internet Explorer Web browser (in IE 4 to IE 6 in the verification of) the garbage collection system, there is a problem, that is, if ECMAScript and some host objects constitutes a &quot;circular reference&quot;, then these objects will not be treated as garbage collection . At this point the so-called host object refers to any DOM node (including the document element object and its offspring), and ActiveX objects. If a circular reference includes one or more of these objects, then these objects until the turn off the browser will not be released, and they occupied the same memory in the browser will not return before the turn off system reuse.

When two or more objects to the way linked to each other, both quoted, it constitutes a circular reference. One object such as a property reference object 2, object 2, a property reference object 3, while an object property 3 also refers to one object. For pure ECMAScript object is concerned, as long as there is no other object reference object 1,2,3, meaning that they only quoted between, then will still be garbage collection system to identify and deal with. However, in Internet Explorer, if the circular reference to any DOM nodes or objects are ActiveX objects, garbage collection system will not be found in the cycle of relationship between them and the systems are isolated from other objects and release them. Eventually they will be retained in memory until the browser turn off.

Closure is easy to constitute a circular reference. If a component of the function closure object is assigned to, such as a DOM node processor case, and the reference node has been assigned to the function of a domain object role activities (or variable) object, then there is a circular reference. DOM_Node.onevent -> function_object. [[Scope]] -> scope_chain -> Activation_object.nodeRef -> DOM_Node. The formation of such a circular reference is easy, but a slight glance at the code contains a similar circular reference site (usually appear in every web page), will consume a large amount (or even all) of system memory.
Digg Technorati StumbleUpon Mixx del.icio.us Reddit BlinkList Furl YahooMyWeb feedburner

Tags: implementation (RSS), quot (RSS), variables (RSS), object instance (RSS), scope (RSS), premise (RSS), programmers (RSS), expression (RSS), extent (RSS), browser environment (RSS), memory leak problem (RSS), internet explorer (RSS), correlation function (RSS), mechanisms (RSS), instance method (RSS), unexpected closure (RSS), directory object (RSS), arcs (RSS)

Permalink: http://www.codeweblog.com/js-closure-on/

Leave a reply