您的位置:首页 > Web前端 > JavaScript

javascript 函数

2016-07-06 11:07 531 查看

arguments

函数的实参被保存在一个类似数组的arguments对象中。

arguments
变量只是 ”类数组对象“,并不是一个数组。称其为类数组对象是说它有一个索引编号和
Length
属性。尽管如此,它并不拥有全部的Array对象的操作方法。

函数参数的默认值是
undefined


参数支持设置不同的默认值:function test(arg1, arg2 = 5) {}。

原始参数(比如一个具体的数字)被作为传递给函数。

对象参数,传递的是对象的应用。

常用:

arguments

arguments.length

arguments.callee(ECMAScript (ES5) forbids use of
arguments.callee()
in strict mode.)

递归函数

形式1: 通过使用函数名

function factorial(num){
if(num <=1) {
return 1;
} else {
return num * factoral(num-1);
}
};


缺点:

var anotherFactorial = factorial;
factorial = null;
alert(anotherFactorial(4));  //VM367:5 Uncaught ReferenceError: factoral is not defined


形式2: 使用 arguments.callee



function factorial2(num){
if(num <=1) {
return 1;
} else {
return num * arguments.callee(num-1);
}
};
var anotherFactorial = factorial2;
factorial2 = null;
alert(anotherFactorial(4));  //24


闭包与变量

假设,函数A内部声明了个函数B,函数B引用了函数B之外的变量,并且函数A的返回值为函数B的引用。那么函数B就是闭包函数。

内部函数可以访问定义在外部函数中的所有变量和函数,以及外部函数能访问的所有变量和函数。

当内部函数生存周期大于外部函数时,由于内部函数可以访问外部函数的作用域,定义在外部函数的变量和函数的生存周期就会大于外部函数本身。

特点:

函数定义时的作用域链到函数执行时依然有效

闭包只取得包含函数中任何变量的最终值

形式1:

function func1() {
var result = new Array();
for (var i = 0; i < 10 ;i++) {
result[i] = function(){  // 外部函数变量得生命周期大于函数本身,闭包取到的总是外部函数最后的变量值 10
return i;
}
};
return result;
};
res = func1();
res[1]();  //10
res[9]();  //10


形式2:

function func2() {
var result = new Array();
for (var i = 0; i < 10 ;i++) {
result[i] = function(num){
return function(){
return num;
}
}(i);  //  创建一个匿名函数并立即执行,将执行结果赋值给变量,匿名函数的参数复制i的值并又在它的闭包中保持
};
return result;
};
res = func2();
res[1]();  //1
res[9]();  //9


this对象

this对象是在函数运行时基于函数执行环境绑定的:

在全局函数中,this等于window。

函数作为某个对象得方法调用时,this等于那个对象。

匿名函数的执行环境具有全局性。

this等于window示例:

/*
每个函数在被调用时,会自动获取两个特殊变量:this、arguments
内部函数在搜搜这两个变量时只会搜索到其活动对象为止
因此永远不可能直接访问外部函数中的这两个变量
*/
var name = "the Window";
var object = {
name: "the Object",
getNameFunc: function(){
return function(){
return this.name;
}
}
};
alert(object.getNameFunc()());  //the Window


this等于Object, that等于this示例:

var name = "the Window";
var object = {
name: "the Object",
getNameFunc: function(){
that = this;  //getNameFunc作为object的方法,在getNameFunc中this等于object
return function(){
return that.name;
}
}
};
alert(object.getNameFunc()());  //the Object


模仿块级作用域

javascript没有块级作用域:

function outputNumbers(count){
for (var i=0; i < count; i++) ;  //do nothing
alert(i); //块语句中定义的变量,在所在函数内都有效
}


模拟块级作用域:

function outputNumbers(count) {
(function(){
for (var i = 0; i<count; i++){
alert(i);
}
})();  //定义匿名函数并立即执行,执行完后其定义的变量也会销毁
alert(i);  //VM1909:7 Uncaught ReferenceError: i is not defined
}


访问私有变量

普通方式:

特点:

私有变量 name 在所有实例中都不同

每一个实例都会重新创建同样的一组私有方法(缺点)

function MyObject(){
//私有变量
var privateVariable = 10;
//私有方法
function privateFunction(){
return false;
}
//特权方法
this.publicMethod = function(){
privateVariable++;
return privateFunction();
}
}
var test = MyObject();
test.publicMethod();  //访问私有变量


静态私有变量:

特点:

只有1个私有作用域

特权方法是在原型上定义的,因此所有实例都使用同一个函数

特权方法,作为一个闭包,总是保存着对包含作用域的引用

由1和3结合,所以任何一个实例改了私有变量,所有实例都感应变化

var Person;
(function(){
var name = "";
Person = function(value){
name = value;
},
Person.prototype.getName = function(){
return name;
},
Person.prototype.setName = function(value){
name = value;
}
}
)();
var person1 = new Person("Nicholas");
alert(person1.getName());    //Nicholas
var person2 = new Person("Michael");
alert(person1.getName());  //Michael
alert(person2.getName());  //Michael


call()和apply()

call( thisArg[, arg1, arg2, ...]); //参数列表

call( thisArg[, argArray ]); //参数数组

两个函数内部的this指针,都会被赋值为 thisArg 对象,这可实现将函数作为另外一个对象的方法运行的目的。

obj = {
x: 2,
y: 5
};
function func(){
return this.x * this.y;
}

func.call(obj);       // 10
func.apply(obj);      // 10
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: