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
相关文章推荐
- 原生JS的事件绑定
- js设计模式之建造者模式
- js去空格 回车 制表符 换页符
- js 验证数字的正则表达式集
- json对象与字符串转换操作
- js第二天知识总结
- js模拟map实现原理终极版
- (javascript)浅析js函数表达式和函数声明以及闭包
- js定时器setInterval()与setTimeout()区别、10秒自动跳转
- HTML+css+js定义好的字体忽大忽小,乱变,js切换文字内容
- js中几种实用的跨域方法原理详解
- 关于js中正则的使用
- JavaScript跨域
- jsp笔记
- HTML与DOM BOM javascript
- ZTree学习(三),ztree树扩展
- js中window.open的参数及注意注意事项
- DOM事件
- 快速解决js动态改变dom元素属性后页面及时渲染的问题
- C#json数据的序列化和反序列化(将数据转换为对象或对象集合)