Home > Web Front-end > JS Tutorial > Summary introduction to javascript functions and scope_javascript skills

Summary introduction to javascript functions and scope_javascript skills

WBOY
Release: 2016-05-16 17:16:13
Original
1060 people have browsed it

Note three points when using functions in js:

1. When a function is called, it runs in the syntax environment when it was declared. ;

2. The function cannot run by itself. It is always called by the object. When the function is running, the this pointer in the function body points to the object that calls the function. If the object is not explicitly specified when calling the function, this points to window by default (strict Except mode, this article does not cover strict mode);

3. A function is an object type data with executable code.

1. Declare function

1. Use the function keyword

Copy the code The code is as follows:

function myfun(a,b){ //Declare a function named myfun

return a b;

}


2. Declare anonymous function

function(a,b){ return a b;} The anonymous function itself cannot be saved. Since the function is a kind of object data in js, the anonymous function can be assigned to a variable to save it.

var myfun = function(a,b){ return a b;}

3. Use the function constructor Function //Note that the first letter is capitalized

Function is a function built into js. It is the constructor of all function objects. (Other data objects also have their own built-in constructors, such as Number, Object, etc. The constructors of these constructors are Function, because they are all functions).

var myfun = new Function('a,b','return a b;'); The last parameter is the function body, and the previous parameters are the formal parameter names of the function. The number is variable because strings are required. Construct by passing parameters. This method of writing is very inconvenient when the function is long and is rarely used. Maybe you will use it to construct a specific return value to replace the eval function.

It should be noted that both global variables and global functions can be regarded as attributes of the window object. If there are functions and variables with the same name, only one can take effect (actually there is only one attribute). Try the following code.

Copy code The code is as follows:

function a(){ alert('a'); }

alert(window.a); //You can also access the properties of the window object without writing the window

var a=1;

alert(window.a);


The declaration of functions and variables occurs during the code parsing period. The difference is that variables are only declared and not assigned values ​​during the parsing period. Therefore, within the same scope When there are functions and variables with the same name, the function with the same name takes effect before the variable is assigned during the execution of the code. After the variable with the same name is assigned (the original value of the window object attribute is overwritten with new data), the variable takes effect (but please note that Under Firefox, the function declared within the with pseudo-closure can only be called after the declaration, that is, there is no pre-declaration of the function in the with in Firefox).
Copy code The code is as follows:

with({}){
a() ; //Under firefox a is undeclared
function a(){ console.log("function a is called");}
}

If a function with the same name is called If declared multiple times, the later declaration will overwrite the previous declaration, such as:
Copy the code The code is as follows:

alert(func1);//pop up func1(){alert(2);}

func1(){

alert(1);

}

alert(func1); //pop up func1(){alert(2);}

func1(){ //This is the last declared func1, subject to this function

alert(2);

}

alert(func1); //pop up func1(){alert(2);}

var func1 = function(){ //Note, this is variable assignment, not function declaration

alert(3);

}

alert(func1); //Pop up function(){alert(3);}


Except for IE8 and browsers below, the function declaration in the expression will return an anonymous function. Will not successfully declare named function
Copy code The code is as follows:

if(function fun(){}){
alert(fun); // error, the function named fun will not be successfully declared, but it will be successful in IE8 and below browsers Declare a function fun

}

(function fun(){ });

alert(fun); //error But even in IE8, the named function in the expression cannot override the variable with the same name:

var fun = 1; //This variable cannot be overwritten by the function name in the function expression
var f = function fun(){};
alert(f); //function fun(){ };
alert(fun); //1


Note the difference:

if(fun = function (){}){
alert(fun); // ok, a variable is declared here, which stores an anonymous function

}

js functions are reference objects

var a = function(){};
var b=a;
b.x=2;
alert(a.x); //2

2. Function parameters

The js function does not check whether the number of parameters passed in when the function is called is consistent with the number of formal parameters when it is defined. Generally, the number of parameters that can be received when a js function is called is 25. Of course, different browsing The processors may be different, and the ECMAScript standard does not regulate this.

If you are not sure how many parameters are passed in when calling a function, you can use the arguments object of the function.

arguments is a bit like an array, arguments.length is the number of parameters passed in, arguments[0] is the first parameter, arguments[1] is the second parameter, and so on...

The length attribute of the function object: This attribute is rarely used, and few people even know that the length attribute of the function is the number of formal parameters when the function is defined.

Copy code The code is as follows:

function myfun(a,b){

alert(arguments.length); //The actual number of parameters passed in when popping up the call

alert(arguments[0]); //Corresponding parameter a

return a b;

}

alert(myfun.length); //The number of formal parameters, 2


arguments object also has other attributes, such as the commonly used arguments.callee, pointing to the function itself.

Note: If a subfunction with the same name as the formal parameter is declared inside the function (in the same scope, the function with the same name takes effect when the variable is not assigned a value), the corresponding value of arguments will also be modified. However, if the same name is declared using var in the scope The variable will not cause the parameter value of arguments to be replaced by the function (but firefox will still replace it).

Copy code The code is as follows:

function aa(a, b,c){ // A question from the js group
function a(){}

console.log(a); //function a
console.log(aa);

//If If there is no var a in the scope, then arguments[0] is function a (friefox(version 17)) then it must be function a)
console.log(arguments[0]);
var a = "ee"; / /Cancel this sentence, test arguments[0] will become a function
var aa = "444";
arguments = 6;
console.log(a);
console.log( aa);
console.log(arguments);
}
aa(1,2,3);

3. Return value of function

The js function uses the return statement to return a value.

All data types can be used as return values ​​of functions (including functions), and js functions can also have no return value.

4. Function call

The function itself will not run. When it runs, there is always an object that calls it.

By default, in any syntax environment, if the calling object of the function is not explicitly specified, the function is called through the window object. At this time, the this pointer in the function body points to the window object.

Copy code The code is as follows:

function myfun(a,b){

alert(this);

return a b;

}

myfun(1,2); // Call the function and pass in 2 parameters, which correspond to the formal parameters a and b respectively. When calling the function, if the number of parameters passed in exceeds the formal parameters, you can only use Arguments are received with subscripts.


Since the object calling the function is not explicitly specified, alert(this) will pop up the window object. This calling method is the most common.

There are three calling object methods for explicitly specifying functions:

1. If a function is assigned as an attribute value of an object, the function can only be accessed through the object (but it does not mean that the function can only be called by the object). The method of calling the function through the object is similar Called as a method in an object-oriented programming language (in fact, it is also customary to use the name method in js).

Copy code The code is as follows:

var obj={}; //Define an object

obj.fun=function(a,b){

alert(this); //pop this pointer

return a b;

} //Object attribute value is function

alert(obj.fun);//Access the fun function. This function can only be accessed through this object

obj.fun(1,2); //Call the fun function through the obj object, and the obj object will pop up. This method is also called calling the fun method of the obj object.


2. Arbitrarily specify the calling object of the function: In a certain syntax environment, if you can access the function fun and the object obj at the same time, you can specify to call the fun function through the obj object if you like. There are two designated methods: call method and apply method. (Because the window object is the top-level object in the browser environment, the window object can be accessed in any syntax environment, therefore, any function can be called through the window object)
Copy code The code is as follows:

function fun(a,b){

alert(this);

return a b;

}

var obj={};

fun.call(obj,1,2); //Call the fun function through the obj object and pass in 2 parameters. The pop-up pointer is the obj object.

var obj2={};

obj2.fun2 = function(a,b){ //The attribute fun2 of the obj2 object is a function

alert(this);

return a b;

};

obj2.fun2.call(obj,1,2); //Call the function stored in the fun2 attribute value of the obj2 object through the obj object. The pop-up this pointer is the obj object

//Relatively hidden method call: array calls a function [9, function(){ alert(this[0]); }][1]();

//The following methods of calling functions using window objects are equivalent
fun(1,2);
window.fun(1,2); //If the fun function is a global function
fun.call(window,1,2);
fun.call(this,1,2); //If this code is in the global environment (or within the function body called by the window object), because of this syntax This in the environment points to the window object.
func.call(); //If the function does not need to pass parameters
func.call(null,1,2);
func.call(undefined,1,2);var name = "window ";
function kkk(){
console.log(this.name); // not ie
}
kkk(); //window
kkk.call(kkk); //kkk function was called by itself


Another error that is easy to overlook is that in the method of object A, a method call using object B is executed, and an attempt is made to use the method of object B This is used to access the A object, which is common in various callback functions. The most common situation is the use of this in the ajax callback function.
Copy code The code is as follows:

var obj = {
data:null,
getData:function(){
$.post(url,{param:token},function(dataBack){ //jQuery ajax post method
this.data = dataBack; //Trying to return data from the server The data is assigned to obj.data, but this here already points to the ajax object of jQuery
      },'json');
//Correct approach
var obj = { data:null,

getData:function(){
var host = this; //Save the reference of the obj object
$. post(url,{param:"token"},function(dataBack){
                         host.data = dataBack;
3. Apply method call:

The only difference between the apply method and the call method is the method of passing function parameters.

obj2.fun2.call(obj,1,2); Change to apply method is obj2.fun2.apply(obj,[1,2]);

apply uses an array-like method to pass parameters. In addition to arrays, you can also use arguments and HTMLCollection to pass parameters, but arguments are not arrays, such as:

var obj={};

function fun_1(x,y){

function fun_2(a,b){

return a b;

}

fun_2.apply(obj,arguments); //Use the arguments object of fun_1 to pass parameters, which actually receives x, y

} There are 2 problems with applying parameters in IE8 and browsers below IE8

In call and apply calls, if scalar data (true/false, string, number) is passed in, the function will wrap the basic data they passed in into an object when running, and then point this to the wrapped object. Try Try the code below.
function a(){

alert(typeof this);

alert(this.constructor);

alert(this);

}

a.call(false);

a.call(100);

a.call('hello');

You can even use this feature to pass parameters, but this usage is not recommended:

function a(){ alert(1 this); } //The object automatically performs type conversion during operation

a.call(100); //101

4. Function as object constructor

When a function uses the new operation as an object constructor, this points to the newly constructed object. If the return value of the constructor is not an object other than null, the constructor will return the object pointed to by this after running, otherwise it will return to the original definition. object.

Copy code The code is as follows:

function Fun(){

this.a = 1;

this.b = 3;

console.log(this); //{a:1,b:2}

// return {a:999}; //With this step, it will return {a:999}

}

var obj = new Fun(); //obj = {a:1,b:2}, if there are no parameters, it can also be written as var obj = new Fun;


5. Function scope

The variable scope of js is at the function level. There is no block-level scope in js similar to the c language.

The top-level scope of the js programming environment is the scope under the window object, which is called the global scope. The variables in the global scope are called global variables.

Variables within a js function cannot be accessed outside the function, but variables outside the function can be accessed within the function. Variables within the function are called local variables.

JS functions can be nested. The nesting of multiple functions constitutes the nesting of multiple scopes. This is called the scope chain of JS.

The variable access rules of js scope chain are: if the variable to be accessed exists in the current scope, use the variable of the current scope, otherwise search in the upper scope until the global scope, if not found, The variable is undeclared.

Note that the declaration of variables is completed during the code parsing period. If the declaration and assignment statement of the variable in the current scope are written after the variable access statement, the js function will think that the variable to be accessed already exists in the current scope and will no longer affect the upper level. Domain lookup, however, since the variable assignment occurs during code runtime, the variable accessed will be undefined.

For example:

Copy code The code is as follows:

var c=1000;

function out(){

var a=1;

var b=2;

function fun(){

alert(a); //undefined

var a=10;

alert(a); //10

alert(b); //2

alert(c); //1000

}

fun();

}

out();


6. Calling anonymous functions

The use of anonymous functions is very important in js. Since all data in js are objects, including functions, functions are often used as parameters or return values ​​of another function.

If the anonymous function is not saved, it will be released from memory after running.

The way to call an anonymous function is to directly place the anonymous function in parentheses instead of the function name. Such as:

(function(a,b){ return a b;})(1,2); //Declare and execute the anonymous function, passing in two parameters during runtime: 1 and 2

//or

(function(a,b){ return a b;}(1,2));

//The following way of writing is wrong:

function(a,b){ return a b;}(1,2);

Since the semicolon at the end of the statement in js can be omitted, the js engine will think that function(a,b){ return a b;} is the end of a statement, so the anonymous function is only declared and not called. If the statement does not pass parameters ( 1,2) written as () will also cause errors. Empty brackets in js are a grammatical error.

The following way of writing is correct.

var ab = function(a,b){ return a b;}(1,2); // ab=3

When js parses grammar, if an expression appears in an assignment operation or operator operation, it is a "greedy match" (try to evaluate as much as possible)

function(t){ return 1 t;}(); //error
var f = function(t){ return t 1;}(); // ok

~ function(t){return t 1;}(); //ok
function(t){return t 1;}(); //ok

If you just want to assign an anonymous function to a variable, remember to add a semicolon after the assignment statement. Otherwise, if it is followed by parentheses, it will become a function call, especially between the parentheses and the end of the function. This error is often difficult to find when multiple lines are separated by spaces.

In actual development, anonymous functions may return in the form of operation values. This situation may not be easy to see, such as

var a =1;
var obj = {a:2,f:function(){ return this.a;}};

(1,obj.f)(); //1 The comma expression returns an anonymous function. When this anonymous function is called, thsi in the function body points to window

Declaring and immediately running an anonymous function is called a "self-executing function". Self-executing functions are often used to encapsulate a piece of js code. Due to the characteristics of function scope, variables within a self-executing function cannot be accessed externally. Code placed within the function will not affect external code, thus avoiding variable pollution. JS development can easily cause variable pollution. Code developed by other coders is often introduced during development. If different coders define global variables or functions with the same name but different meanings, variable pollution occurs. Variables with the same name appear in the same scope. or functions, the later ones will overwrite the earlier ones.

(function(){

//Your own code....

})(); Anonymous functions can also release memory in time: because the variables are declared within the anonymous function, if these variables are not referenced outside the anonymous function, then the function is finished running, and the variables inside occupy The memory will be released immediately.

The name of the function: In browsers such as Firefox, the function has a name attribute, which is the function name of the function, but this attribute does not exist in IE. In addition, the name of the anonymous function is empty.

var a=function(){}
alert(a.name); //undefined, a is a variable that stores an anonymous function
function b(){}
alert(b .name); //b ,but undefined for IE

7. When a function is called, it runs in the environment in which it was defined

No matter where the function is called or by whom, it cannot change the syntax environment when it is declared, which determines the running environment of the function

Copy code The code is as follows:

var x=99;

var inerFun=null;

function fun1(){

alert(x);

}

function holder(){

var x = 100;

var fun2 = fun1;

inerFun = function(){ alert(x);}

fun1(); //99

fun2();//99

inerFun(); //100

}

holder();

fun1(); //99

inerFun(); //100

//Another example:

var x = 100;
var y=77;
var a1={
x:99,
xx:function(){
//var y=88; / /If you comment this variable, y will be the global variable 77
alert(y); //Without this pointer, the object calling the function cannot affect the value of y. When the function is running, it will step by step in the scope chain from here. Search value
alert(this.x); //Using this pointer, calling function
}
}

a1.xx();
a1.xx.call(window);

var jj = a1.xx;

jj(); //The effect is the same as a1.xx.call(window); //Try the following code

var x=99;
function xb(){
this.x=100;
this.a = (function(){return this.x}).call(this); / /new is executed, the anonymous function is called by the instantiated object
this.b = (function(){return this.x})(); //new is executed, the anonymous function is called by window
this.method = function(){return this.x;}
}


var xbObj = new xb();
console.log(xbObj.x);
console.log(xbObj.a);
console.log(xbObj.b);
console.log(xbObj.method());


Pay attention to distinguishing the concepts of the object calling the function, the syntax environment when the function is declared, and the syntax environment of the function call statement

1. The object calling the function (or the method of calling the function) determines who the this pointer in the function body points to when the function is running

2. The syntax environment when the function is declared determines the access permissions when the function is run

3. The syntax environment of the function call statement determines whether and when the function can really be called (only if the function is visible in a certain syntax environment, this function can be called)

When the function is running, an arguments object is generated to access the parameters passed into the function. arguments has an attribute that can point to the function itself: arguments.callee.

When a function is running, the caller attribute of the function can point to the function where the function call statement is located. For example, function a is called within the body of function b, then when function a is running, a.caller points to function b. If function a If called in the global environment, a.caller=null

The values ​​of arguments and a.caller are directly related to each call of the function. They are generated when the function is running and can only be accessed within the function body.

In IE8 and below browsers, the arguments.caller in a function (this attribute is removed after IE9) points to the arguments when a.caller is executed (arguments.caller.callee === a.caller),

7. Function calls in real-time string parsing: eval(), new Function(), setTimeout(), setInterval()

eval() and window.eval()

Copy code The code is as follows:

function a(){
console.log('out of b');
}
function b(){
function a(){ console.log("in b"); }
var f = function(){ a(); };
eval('a()'); // in b
window.eval('a()'); //out of b ,ie 678 in b, ie 9 out of b
(new Function('a();'))(); //out of b
setTimeout('a()',1000); / / out of b
setTimeout(f,2000);// in b
}
b(); The code in

eval() is executed in the eval() statement Within the scope:
Copy the code The code is as follows:

var Objinit = function(){
  var param = 123;
  return {
          execute:function(codes){
                eval(codes);
          },
          setCallback:function(f){
               this.callback = f;
          },
          fireCallback:function(){
               this.callback && this.callback.call(this);
          },
         getParam:function(){
             return param;
         }
   }
};

var obj = Objinit ();
var param = 'outerParam';
console.log(param,obj.getParam()); //outerParam 123
obj.execute('param = 456');
console.log(param,obj.getParam()); //outerParam 456
obj.setCallback(function(){ eval("param = 8888")});
obj.fireCallback();
console.log(param,obj.getParam()); //8888 456
obj.setCallback(function(){ eval("eval(param = 9999)")});
obj.fireCallback();
console.log(param,obj.getParam()); //9999 456eval()


字符串中解析出的代码运在 eval 所在的作用域,window.eval() 则是运行在顶级作用域(低版本 chrome 和 低于IE9 则同 eval()).

IE 中 ,window.execScript();  相当于 window.eval()

new Function()、setTimeout()、setInterval()  的第一个字符串参数所解析得到的代码,都是在顶级作用域执行。

八、函数闭包

要理解函数闭包,先了解 js 的垃圾自动回收机制。

number、string、boolean、undefined、null 在运算和赋值操作中是复制传值,而对象类型的数据按引用传值,

js 的同一个对象型数据可能被多次引用,如果某个对象不再被引用,或者两个对象之间互相引用之外不在被第三方所引用,浏览器会自动释放其占用的内存空间。

函数被引用:函数被赋为其他对象的属性值,或者函数内部定义的数据在该函数外被使用,闭包的形成基于后一种情形。

复制代码 代码如下:

var f;

function fun(){

var a =1;

f = function(){ return a;};

}

fun(); //产生一个闭包

f(); //  闭包中 a=2

f(); // 闭包中 a =3  ,模拟静态变量


在 fun 内 声明的匿名函数赋给 fun 外的变量 f,该匿名函数内使用了在 fun 内声明的变量 a,于是 f可以访问 变量 a,为了维持这种访问权限(f执 行时需要访问a,但何时执行未定), fun() 执行完毕产生的变量 a 不能被释放(除非f 中的函数被释放),于是产生了一个闭包(变量 a 被封 闭了,供 f 使用)。

产生闭包的关键是,一个在函数 A内的声明的函数 B被传出 A 之外,并且 B 函数内使用了在 函数A 内生成的数据(声明或按值传参),

函数B传出函数A之外的方式有多种,如:

复制代码 代码如下:

function fun(){   
var a =1;

return {a:123,b:456, c: function(){ return a;} };

}

var f = fun();

f.c(); //a=2

广义上来说,函数运行时都会形成闭包,没有数据在函数外被引用时,闭包的生命周期很短:函数执行完毕即释放。

闭包的独立性:即使由同一个函数产生的多个闭包也是相互独立的

复制代码 代码如下:

function fun(){

var a =1;

return function(){ return a;};

}

var f1 =  fun(); //一份闭包

var f2 = fun(); //另一份闭包

alert(f1()); //2

 alert(f1()); //3

 alert(f2()); //2

 alert(f2()); //3


The variable a in the two closures is different data. Each time a closure is generated, fun() is executed once, and the variable declaration statement is also executed once.

In js oop programming, closures can be used to simulate private members and construct single classes

Copy code The code is as follows:

function MakeItem(name,val){
var myName,myVal; //Private attribute

//Private method
function setName(name){
myname=name;
}

//Private method
function setVal(val){
myVal=val;
}

//Call the internal private method when executing new to construct the object
setName(name);
setVal(val);

//Public method
this.getName=function(){
return myName;
}

this.getVal=function(){
return myVal;
}
}

var obj = new MakeItem("name",100);
obj.myname; //undefined Private properties cannot be accessed from outside
obj.getName(); //ok


The following is a single class construction method
Copy the code The code is as follows:

var Singleton = (function(){

    var instance = null; //在闭包中保存单体类的实例

    var args = null;

    var f = function(){

        if(!instance){

            if(this===window){               

               args = Array.prototype.slice.call(arguments,0);               

                instance = new arguments.callee();

            }else{

               this.init.apply(this,args||arguments);

                instance = this;

            }

        }

        return instance;

    };

    f.prototype = {

        init:function(a,b,c){

            this.a = a;

            this.b = b;

            this.c = c;      

            this.method1 = function(){ console.log("method 1"); };

            this.method1 = function(){ console.log("method 1"); };

            console.log("init instance");

        }

    };

    f.prototype.constructor = f.prototype.init;

    return f;

 

})();


//单体的使用
var obj1 =  Singleton(1,2,3);

var obj2 = new Singleton();

var obj3 = new Singleton();

console.log(obj1===obj2,obj2===obj3); //true

console.log(obj1);

//一个单体类声明函数

var SingletonDefine= function(fun){

    return (function(){

        var instance = null;

        var args = null;      

        var f = function(){

            if(!instance){

                if(this===window){

                    args = Array.prototype.slice.call(arguments,0);                   

                    instance = new arguments.callee();

                }else{

                    fun.apply(this,args||arguments);                   

                    instance = this;

                }

            }

            return instance;

        };

 

        f.prototype = fun.prototype;

        f.prototype.constructor = fun;            

        return f;

    })();

};

var fun = function(a,b,c){

    this.a = a;

    this.b = b;

    this.c = c;

this.method1 = function(){ console.log("method 1"); };

console.log("init instance");

};

fun.prototype.method2 = function(){ console.log('method 2'); };


//Single class declaration function usage
var Singleton = SingletonDefine(fun);

var obj1 = Singleton(8,9,10);

var obj2 = new Singleton();

var obj3 = new Singleton(3,2,1);

console.log(obj1===obj2,obj2===obj3);

console.log(obj1);

//console.log(obj1.toSource()); //firefox

obj1.method1();

obj1.method2();


Memory leaks and closures in IE6

In IE 6, circular references to non-native js objects (DOM, etc.) will cause memory leaks. When using closures, be careful when using non-js native object references.

function fun(){

var node = document.getElementById('a');
node.onclick = function(){ alert(node.value); };

node = null; //Break circular references to prevent memory leaks

node saves DOM objects, which exist outside fun (and always exist, even if deleted, they are only removed from the document tree). After fun is executed, a closure is generated, which also constitutes a circular reference between the DOM object and the callback function ( node-function-node), a memory leak occurs under IE 6.

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template