当前位置: 首页 > news >正文

网站站建设建设中页中页网站备案 更换接入商

网站站建设建设中页中页,网站备案 更换接入商,php网站是什么,wordpress管理员登陆不上http://www.cnblogs.com/royalroads/p/4418587.html 在JS中,Function(函数)类型实际上是对象;每个函数都是Function类型的实例#xff0c;而且都与其他引用类型一样具有属性和方法。由于函数是对象,因此函数名实际上也是一个指向函数对象的指针。 一 函数的声明方式 //1.函数声…http://www.cnblogs.com/royalroads/p/4418587.html 在JS中,Function(函数)类型实际上是对象;每个函数都是Function类型的实例而且都与其他引用类型一样具有属性和方法。由于函数是对象,因此函数名实际上也是一个指向函数对象的指针。 一 函数的声明方式 //1.函数声明方式function add(num1,num2){return num1num2;}//2.函数表达式定义函数var add function(num1,num2){   // 通过变量box即可引用函数;return num1num2;};             // 注意函数末尾有一个分号,就像声明其他变量时一样;var another add;         // 使用不带圆括号的函数名是访问函数指针;而非调用函数;console.log(another(10,10));   //3.使用Function构造函数var add new Function(num1,num2,return num1num2); // 第三种方式不推荐,这种语法会导致解析两次代码(第一次解析常规JS代码,第二次解析传入构造函数中的字符串),从而影响性能; // 可以通过这种语法来理解函数是对象,函数名是指针的概念;   通常来说在全局作用域内声明一个对象只不过是对一个属性赋值而已比如上例中的add函数事实上只是为全局对象添加了一个属性属性名为add而属性的值是一个对象即function(x, y){return xy;}理解这一点很重要这条语句在语法上跟 var str This is a string;   并没有什么区别。都是给全局对象动态的增加一个新的属性如此而已。 二 作为值的函数 // JS中的函数名本身就是变量,所以函数也可以作为值来使用; // 也就是说,不仅可以像传参数一样把一个函数传递给另一个函数,而且可以将一个函数作为另一个函数的结果返回;function box(sumFunction,num){    // 无论第一个参数传递进来的是什么函数,return sumFunction(num);     // 它都会返回执行第一参数后的结果;}function sum(num){return num10;}// 传递函数到另一个函数里;// 要访问函数的指针不执行函数的话,须去掉函数名后的圆括号;var result box(sum,10); // 20;   三、函数的内部属性 // 函数内部有两个特殊的对象:arguments和this;// 1.arguments:包含着传入函数中的所有参数,arguments并不是一个数组只是与数组相似。除了拥有length属性数组的所有属性和方法都不具备。 // arguments这个对象还有一个名叫callee的属性,该属性是一个指针,指向拥有这个arguments对象的函数;function box(num){if(num1){return 1;}else{return num*arguments.callee(num-1); // 使用arguments.callee来执行box本身;}}// 2.this:引用的是函数据以操作的对象,或者说函数调用语句所处的作用域; // 当在全局作用域调用函数时,this对象引用的就是window;window.color red;alert(this.color); // 打印全局的color;red;var box {color:blue,sayColor:function(){alert(this.color); // 打印局部的color;blue;}}; 四 函数属性和方法 // JS中的函数是对象,因此函数也有属性和方法;包含length和prototype;// length属性:表示函数希望接收到命名参数的个数;function box(name,age){alert(nameage);}alert(box.length); // 2s// prototype属性:它是保存所有实例方法的真正所在,也就是原型; // prototype包含两个方法:apply()和call(),每个函数都包含这两个非继承而来的方法; // 这两个方法的用途都在特定的作用域中调用函数,实际上等于设置函数体内this对象的值;var color red;var box {color blue;}function sayColor({alert(this.color);});sayColor(); // 作用域在window;sayColor.call(this); // 作用域在window;sayColor.call(window); // 作用域在window;sayColor.call(box); // 作用域在box,对象冒充;red; // 使用call(box)方法的时候,sayColor()方法的运行环境已经变成了box对象里了; // 使用call()或apply()来扩充作用域的最大好处,就是对象不需要与方法发生任何耦合关系; // 耦合:相互关联的意思,扩展和维护会发生连锁反应; // 也就是说,box对象和sayColor()方法之间不会有多余的关联操作,比如:box.sayColor sayColor;function Animal(){ this.name Animal; this.showName function(){ alert(this.name); } } function Cat(){ this.name Cat; } var animal new Animal(); var cat new Cat(); //通过call或apply方法将原本属于Animal对象的showName()方法交给对象cat来使用。 //输入结果为Cat animal.showName.call(cat,,); //animal.showName.apply(cat,[]); 函数返回值return 当一个函数被调用通常会从函数的开始执行到结束。如果想提前结束该函数的执行可以使用return语句此时return语句后面的所有语句将永远不会执行。如 function test(){alert(first);return;alert(second); // 该语句永远被不会执行 } test(); // 一个函数总是会返回值如果没有使用return返回值默认返回undefined。如 function test(){alert(first); } alert(test()); // 输出undefined // 如果函数前使用new方式调用且返回值不是一个对象则返回this新对象。如 function test(){alert(first); } var t new test(); alert(typeof t); // 输出‘object alert(t instanceof test); // 输出true 异常exception     异常是干扰程序正常流程的非正常事故可能人为有意的。当检查出这样的事故应当抛出异常。如 function add(a, b){ // 定义一个加法函数// 如果传递的参数不是数字类型则抛出一个异常信息if(typeof a ! number || typeof b ! number){throw {name : typeError, // 属性是自定义的名字可以任意取message: add方法必须使用数字作为参数};}return a b; } (function(){// 捕获add方法可能产生的异常try{add(10, );} catch(e){ // 一个try语句只有一个catch语句如果要处理多个异常则通过异常的name属性来区别// 判断异常的类型if(e.name typeError){alert(e.message);}} })(); 给类型添加方法    javascript中允许给基本类型添加方法。如boolean、string、Number    实例在Function中添加一个method函数该函数为Function添加其他自定义的函数避免使用prototype然后利用method函数想Function中添加一个add函数最后测试add函数在Function中确实存在。该方法将func函数添加到Function中以name命名。然后返回Function的对象 Function.prototype.method function(name, func){// 避免覆盖已有的方法if(!this.prototype[name]){this.prototype[name] func;}return this; }; // 通过Function.method方法添加一个加法函数到Function该函数的名称为“add” Function.method(add, function(a, b){if(typeof a ! number || typeof b ! number){throw {name : typeError,message : add方法必须传入数字};}return a b; }); // 调用Function的add方法是否存在 (function(){try{alert(Function.add(1, 3)); // 输出4} catch(e){if(e.name typeError){alert(e.message);}} })(); // 去除字符串两端的空白 String.method(trim, function(){return this.replace(/^\s|\s$/g, ); }); alert(| hello world .trim() |); // 输出 |hello world| // 添加数字的取整函数 Number.method(integer, function(){// 可以通过此种方式调用函数如Math.random() Math[random]() Math[random]()return Math[this 0 ? ceil : floor](this); }); alert((-10 / 3).integer()); // 输出-3 递归调用arguments.callee    递归调用就是自己调用自己。调用分为直接调用和间接调用下面展示使用递归调用来计算指定值的斐波那契数列。 // 求i的阶乘 function factorial(i){if(i 2){return 1;}return i*factorial(i-1); // 递归调用 } alert(factorial(5)); // 求5的阶乘 // 以上方式存在一个问题如下 var factorial function(i){if(i 2){return 1;}return i*factorial(i-1); // factorial还能被调用吗不能 } var test factorial; factorial null; alert(test(2)); // 解决方案 var factorial function(i){if(i 2){return 1;}return i*arguments.callee(i-1); // arguments.callee返回正被执行的 Function 对象也就是所指定的 Function 对象的正文 } var test factorial; factorial null; alert(test(5)); 函数的作用域 作用域的概念在几乎所有的主流语言中都有体现在JavaScript中则有其特殊性JavaScript中的变量作用域为函数体内有效而无块作用域我们在Java语言中可以这样定义for循环块中的下标变量 public void method(){ for(int i 0; i obj1.length; i){ //do something here; } //此时的i为未定义 for(int i 0; i obj2.length; i){ //do something else; } } 而在JavaScript中 function func(){ for(var i 0; i array.length; i){ //do something here. } //此时i仍然有值及I array.length print(i);//i array.length; }   再看一个例子 // 在程序中作用域控制着变量的可见性和生命周期。 var name default; // 全局作用域 function getName(){var name getName; // getName作用域下for(var i0; i2; i){var inName inName;}alert(i , inName); // 2,inName 注意在js中没有块级作用域及if、for、while中声明的变量是放在块所在的作用域下return name; } alert(getName()); // getName 注意js存在函数作用域所以在函数内部定义的变量在外部是不可见的 alert(name); // default 注意在现代的很多语言中推荐将变量尽可能的延迟声明。如java而在js中却不推荐这样做因为js不支持块级作用域。推荐在函数的开始就将所有用到的变量进行声明。 JavaScript的函数是在局部作用域内运行的在局部作用域内运行的函数体可以访问其外层的(可能是全局作用域)的变量和函数。JavaScript的作用域为词法作用域所谓词法作用域是说其作用域为在定义时(词法分析时)就确定下来的而并非在执行时确定如下例 var str global; function scopeTest(){ print(str); var str local; print(str); } scopeTest();   运行结果是什么呢?初学者很可能得出这样的答案globallocal而正确的结果应该是undefinedlocal因为在函数scopeTest的定义中预先访问了未声明的变量str然后才对str变量进行初始化所以第一个print(str)会返回undifined错误。那为什么函数这个时候不去访问外部的str变量呢?这是因为在词法分析结束后构造作用域链的时候会将函数内定义的var变量放入该链因此str在整个函数scopeTest内都是可见的(从函数体的第一行到最后一行)由于str变量本身是未定义的程序顺序执行到第一行就会返回未定义第二行为str赋值所以第三行的print(str)将返回”local”。 函数上下文在Java或者C/C等语言中方法(函数)只能依附于对象而存在不是独立的。而在JavaScript中函数也是一种对象并非其他任何对象的一部分理解这一点尤为重要特别是对理解函数式的JavaScript非常有用在函数式编程语言中函数被认为是一等的。函数的上下文是可以变化的因此函数内的this也是可以变化的函数可以作为一个对象的方法也可以同时作为另一个对象的方法总之函数本身是独立的。可以通过Function对象上的call或者apply函数来修改函数的上下文 call和applycall和apply通常用来修改函数的上下文函数中的this指针将被替换为call或者apply的第一个参数我们不妨来看看JavaScript入门之对象与JSON中的例子   //定义一个人名字为jack var jack { name : jack, age : 26 } //定义另一个人名字为abruzzi var abruzzi { name : abruzzi, age : 26 } //定义一个全局的函数对象 function printName(){ return this.name; } //设置printName的上下文为jack, 此时的this为jack print(printName.call(jack)); //设置printName的上下文为abruzzi,此时的this为abruzzi print(printName.call(abruzzi)); print(printName.apply(jack)); print(printName.apply(abruzzi));   apply和call的区别   // 定一个对象包含一个add方法返回a、b的和 var Person {add : function(a, b){return a b;} }; // 显示a、b的和 function showInfo(a, b){alert(this.add(a, b)); } // 通过apply方法改变showInfo方法的this指向 //showInfo(1, 3); // 对象不支持次对象 showInfo.apply(Person, [1, 3]); showInfo.call(Person, 1, 3); // 从上面可以看出apply和call的区别是apply接受一个数组作为被调函数的参数 // 而call是通过将被调函数的所有参数以逗号分隔的形式展开   匿名函数和嵌套函数 在JavaScript可以声明一个没有名称的函数称为匿名函数Anonymouse Function。同时JavaScript还允许在函数内部声明函数称为嵌套函数Nested Function嵌套函数的作用域为整个父函数。在前面函数声明的部分就看到了匿名函数和嵌套函数的一种用法由于匿名函数没有名称不会引入新的变量污染上下文环境而且会带来新的变量作用域因此匿名函数常被用来防止全局环境污染。JavaScript运行时中有一个特殊的全局环境global object这个对象上面存放全局的函数和变量实际开发中经常会使用若干第三方的库或多个js文件若不小心在全局对象引入重复的变量或函数声明则会造成代码执行混乱。例如先后引入两个js文件分别定义了自己的函数log作为内部使用则第二引入的函数会覆盖第一个的定义且不会抛出任何错误在后续的执行中调用log函数可能会造成错误。这时候使用一个匿名函数将整个js内的逻辑包装起来就可以避免这种错误这种方法已经被绝大多数开源js库使用。 (function() { // 匿名函数 function log(msg) { console.log(msg); } // 其他代码 }()); // 立即执行 以上代码就是一个简单的示例log函数的作用域被限制在这个匿名函数之内而匿名函数则因为被外面一对小括号()包括起来形成一个函数表达式表达式的值是一个函数紧接着一对小括号表示立即执行这个函数让原有的代码正常执行一次。不过这种方式声明的函数、通过var声明的变量等等都是内部的不能被任何匿名函数以外的代码访问到。如果你需要对外暴露一些函数作为接口的话有如下几种方法 var mylib (function(global) { function log(msg) { console.log(msg); } log1 log; // 法一利用没有var的变量声明的默认行为在log1成为全局变量不推荐 global.log2 log; // 法二直接在全局对象上添加log2属性赋值为log函数推荐 return { // 法三通过匿名函数返回值得到一系列接口函数集合对象赋值给全局变量mylib推荐 log: log}; }(window)); 高阶函数High-order Function 如果函数作为参数或返回值使用时就称为高阶函数JavaScript中的函数都可以作为高阶函数来使用这也是第一类函数的特征。下面我们就分别分析一下这两种使用方法。 function negative(n) { return -n; // 取n的相反值 } function square(n) { return n*n; // n的平方 } function process(nums, callback) { var result []; for(var i 0, length nums.length; i length; i) { result[i] callback(nums[i]); // 对数组nums中的所有元素传递给callback进行处理将返回值作为结果保存 } return result; } var nums [-3, -2, -1, 0, 1, 2, 3, 4]; var n_neg process(nums, negative); // n_neg [3, 2, 1, 0, -1, -2, -3, -4]; var n_square process(nums, square); // n_square [9, 4, 1, 0, 1, 4, 9, 16]; 以上代码展示了把函数作为参数传入另一个函数process调用的示例在process函数的实现中把callback作为一个黑盒子看待负责把参数传给它然后获取返回值在调用之前并不清楚callback的具体实现。只有当执行到20行和22行时callback才被分别代表negative或square分别对每个元素进行取相反值或平方值的操作。   function generator() { var i 0; return function() { return i; }; } var gen1 generator(); // 得到一个自然数生成器 var gen2 generator(); // 得到另一个自然数生成器 var r1 gen1(); // r1 0 var r2 gen1(); // r2 1 var r3 gen2(); // r3 0 var r4 gen2(); // r4 1 上面的代码展示了把函数作为返回值的示例generator是一个自然数生成器函数返回值是一个自然数生成函数。每次调用generator时都会把一个匿名函数作为结果返回这个匿名函数在被实际调用时依次返回每个自然数。在generator里的变量i在每次调用这个匿名函数时都会自增1这其实就是一个闭包。下面我们来介绍一下闭包.   类构造函数JavaScript的函数同时作为类的构造函数因此只要声明一个函数就可以使用new关键字创建类的实例。 在一些面向对象的语言如Java、C、PHP中构造函数是很常见的。在Javascript中构造函数首先是一个普通的函数它可以使用new 操作符来调用并生成一个特殊类型的对象。 function Benjamin(username, sex) {this.username username;this.sex sex; } var benjamin new Benjamin(zuojj, male); //Outputs: Benjamin{sex: male,username: zuojj} console.log(benjamin); 正如我们所看到的“Benjamin”构造函数仅仅是接收传递过来的参数并把它们赋值给this对象。这是因为当构造函数被new操作符调用时构造函数的this对象赋值为new操作返回的对象。这意味着上面的代码等同于 benjamin {username: zuojj,sex: male } function Person(name) {this.name name;this.toString function() {return Hello, this.name !;};}var p new Person(Ghostheaven);alert(p); // Hello, Ghostheaven! 在以上实例中Person函数作为类的构造函数使用此时this指向新创建的实例对象可以为实例增加属性和方法关于详细的面向对象的JavaScript编程可以参考这篇文章。这里我想要说的是JavaScript函数作为类构造函数使用时的返回值问题。 function MyClass(name) { this.name name; return name; // 构造函数的返回值? } var obj1 new MyClass(foo); var obj2 MyClass(foo); var obj3 new MyClass({}); var obj4 MyClass({}); 上面的构造函数比较特别有返回语句那么obj1~obj4分别指向什么对象呢实际结果是这样的 obj1 MyClass对象 obj2 foo obj3 {} obj4 {}   具体原因这篇文章有解释本文不再赘述由于带返回值的构造函数会产生奇怪的结果因此不要在构造函数中调用有返回值的返回语句空return可以。 为什么使用构造函数有以下几个方面的原因1.使用构造函数意味着所有的这些对象都可以使用相同的基本结构创建2.使用构造函数意味着“benjamin”对象被明确的标记为“Benjamin”函数的实例 function Benjamin(username, sex) {this.username username;this.sex sex; } var benjamin new Benjamin(zuojj, male); var ben {username: zuojj,sex: male } //Outputs: true console.log(benjamin instanceof Benjamin); //Outputs: false console.log(ben instanceof Benjamin); 3.使用构造函数意味着我们可以在原型上定义公共方法供多个实例共享 function Benjamin(username, sex) {this.username username;this.sex sex; } Benjamin.prototype.getName function() {return this.username; } var benjamin new Benjamin(zuojj, male); var ben new Benjamin(lemon, female); //Outputs: zuojj console.log(benjamin.getName()); //Outputs: lemon console.log(ben.getName()); 1.new 关键字在实例化构造函数的时候一定不要忘了使用new关键字是否使用new关键字对this对象的影响很大不用new关键字的情况下this对象会指向全局对象window in browser and global in node。因此定义构造函数时建议函数名称首字母大写。2.如果被调用的函数没有显式的 return 表达式则隐式的会返回 this 对象 – 也就是新创建的对象否则将会影响返回的结果但仅限于返回的是一个对象 function Bar() {return 2; } var bar new Bar(); //返回新创建的对象 //Outputs: Bar {} console.log(bar); function Test() {this.value 2;return {foo: 1}; } var test new Test(); //返回的对象 //Outputs: Object {foo: 1} console.log(test); 我们需要注意的是a) new Bar() 返回的是新创建的对象而不是数字的字面值 2。 因此 new Bar().constructor Bar但是如果返回的是数字对象结果就不同了;b) 这里得到的 new Test()是函数返回的对象而不是通过new关键字新创建的对象如下所示 function Bar() {return 2; } var bar new Bar(); function BarN() {return new Number(2); } var barn new BarN(); //Outputs: true console.log(bar.constructor Bar); //Outputs: Number {} console.log(barn); //Ouputs: false console.log(barn.constructor BarN); //Outputs: true console.log(barn.constructor Number); /* -------------------------------------- */ function Test() {this.value 2;return {foo: 1}; } var test new Test(); //Outputs: undefined console.log(test.value); //Ouputs: 1 console.log(test.foo);   闭包 var myObject {value : 0,increment : function(inc){this.value typeof inc number ? inc : 1;},getValue : function(){return this.value;} }; myObject.increment(10); alert(myObject.value); alert(myObject.getValue()); // 上面使用字面常量方式定义了一个myObject对象。但是value变量可以被外部对象访问 var myObject function(){var value 0;return {increment: function(inc){value typeof inc number ? inc : 1;},getValue : function(){return value;}}; }(); myObject.increment(10); alert(myObject.value); // 不能被外部对象访问 alert(myObject.getValue()); // 10 // 渐变body的背景色黄色到白色 var fade function(node){var level 1;var step function(){var hex level.toString(16);node.style.backgroundColor #FFFF hex hex;if(level 15){level 1;setTimeout(step, 500); // 如果level小于15则内部函数自我调用}};setTimeout(step, 1); // 调用内部函数 }; fade(document.body); // 下面是一个很糟糕的例子 a href# nametest点击我.../abr // 点击时显示3 a href# nametest点击我.../abr // 点击时显示3 a href# nametest点击我.../abr // 点击时显示3 var add_the_handlers function(nodes){var i;for(i 0; i nodes.length; i 1) {nodes[i].onclick function(e){ // 函数构造时的ialert(i);};} }; var objs document.getElementsByName(test); add_the_handlers(objs); // 造成上面的原因是a标签的事件函数绑定了变量i则不是函数在构造时的i值。 // 解决方案如下 var add_the_handlers function(nodes){var i;for(i 0; i nodes.length; i 1) {nodes[i].onclick function(i){return function(e){alert(i); // 输出的i是构造函数传递进来的i不是事件处理绑定的i。};}(i);} }; var objs document.getElementsByName(test); add_the_handlers(objs);   回调 // data表示参数而call_function则表示回调函数 function sendRequest(data, call_function){// setTimeout来模仿客户端请求服务端中传输数据的时间。// 当3秒钟后就调用回调函数有客户端实现回调函数setTimeout(function(){call_function(data); // 调用回调函数}, 3000); } // 测试sendRequest函数 sendRequest(参数, function(context){alert(context context); });   模块 模块是一个提供接口而隐藏状态和实现的函数或对象。    一般形式一个定义了私有变量和函数的函数利用闭包创建可以访问私有变量和函数的特权函数最后返回这个特权函数或者把他们保存到一个可以被访问到的地方。 Function.prototype.method function(name,func){this.prototype[name] func;return this; }; String.method(deentityify,function(){var entity {quot : ,lt : ,gt : };return function(){return this.replace(/([^;]);/g, function(a, b){ // 怎样知道a、b的值了解正则表达式var r entity[b];return typeof r string ? r : a;});}; }()); alert(.deentityify()); // 测试 注模块模式通常结合单例模式使用JavaScript的单例模式就是用对象字面量方式创建的对象对象的属性值可以是数值或函数并且属性值在该对象的生命周期中不会发生变化。 级联链式操作    对于一些不返回值的方法我们返回this而不是undefined那么我们就可以启动以级联链式去操作该对象。如下 var $ function(id){var obj document.getElementById(id);obj.setColor function(color){this.style.color color;return this;};obj.setBgColor function(color){this.style.backgroundColor color;return this; // 返回this对象启动级联};obj.setFontSize function(size){this.style.fontSize size;return this;};return obj; }; $(test).setColor(red).setFontSize(30px).setBgColor(blue); // 改进后的代码 (function(id){var _$ function(id){this.element document.getElementById(id);};_$.prototype {setColor : function(color){this.element.style.color color;return this;},setBgColor : function(color){this.element.style.backgroundColor color;return this;},setFontSize : function(size){this.element.style.fontSize size;return this;}};// 添加到window原型链中window.$ function(id){return new _$(id);}; })(); $(test).setColor(red).setFontSize(30px).setBgColor(blue); 套用    所谓套用就是将函数与传递给它的参数相结合产生一个新的函数。如下面代码中定义一个add()函数该函数能够返回一个新的函数并把参数值传递给这个新函数从而实现连加操作。 // 第一种方式 var add function(a){return function(b){return a b;} }; alert(add(1)(2)); // 3 // 第二种方式用arguments实现 var add function(){var arg arguments;return function(){var sum 0;for(var i0; iarg.length; i){sum arg[i];}for(i0; iarguments.length; i){sum arguments[i];}return sum;} }; alert(add(1,2,3)(4,5,6)); // 21 // 第三种方式通过一个套用方法curry实现 var add function(){var sum 0;for(var i0; iarguments.length; i){sum arguments[i];}return sum; }; // 添加方法到Function的原型链上 Function.prototype.method function(name, func){this.prototype[name] func;return this; }; // 套用方法 Function.method(curry, function(){// 通过数组Array的slice方法使得arguments也具有concat方法var slice Array.prototype.slice,args slice.apply(arguments), that this;return function(){return that.apply(null, args.concat(slice.apply(arguments)));}; }); alert(add.curry(1,2)(3,4)); // 10   记忆    函数可以用对象去记住先前操作的结果从而能避免无谓的运算。这种优化被称为记忆。 var fibonacci function(){var mome [0,1]; // 存放计算后的数据var fib function(n){var result mome[n];// 如果不存在被计算过的数据则直接计算。然后在将计算结果缓存if(typeof result ! number){result fib(n-1) fib(n-2);mome[n] result;}return result;};return fib; }(); for(var i0; i10; i){document.writeln(// i : fibonacci(i) br/); } // // 创建一个具有记忆的函数 // var memoizer function(memo, fundamental){var shell function(n){var result memo[n];if(typeof result ! number){result fundamental(shell, n);memo[n] result;}return result;};return shell; }; // 通过记忆函数memoizer完成斐波那契数列 var fibonacci memoizer([0,1], function(shell, n){return shell(n-1) shell(n-2); }); // 通过记忆函数memoizer完成阶乘 var factorial memoizer([1,1], function(shell, n){return n * shell(n-1); }); for(var i0; i15; i){document.writeln(// i : factorial(i) br/); } 自更新函数Self-update Function在很多语言中函数一旦声明过就不能再次声明同名函数否则会产生语法错误而在JavaScript中的函数不仅可以重复声明而且还可以自己更新自己。自己吃自己的妖怪来了 function selfUpdate() { window.selfUpdate function() { alert(second run!); }; alert(first run!); } selfUpdate(); // first run! selfUpdate(); // second run! 这种函数可以用于只运行一次的逻辑在第一次运行之后就整个替换成一段新的逻辑。 使用函数前面已经提到在JavaScript中函数可以◆ 被赋值给一个变量   //声明一个函数接受两个参数返回其和 function add(x, y){ return x y; } var a 0; a add;//将函数赋值给一个变量 var b a(2, 3);//调用这个新的函数a print(b);   这段代码会打印”5”因为赋值之后变量a引用函数add也就是说a的值是一个函数对象(一个可执行代码块)因此可以使用a(2, 3)这样的语句来进行求和操作。◆ 被赋值为对象的属性 var obj { id : obj1 } obj.func add;//赋值为obj对象的属性 obj.func(2, 3);//返回5 事实上这个例子与上个例子的本质上是一样的第一个例子中的a变量事实上是全局对象(如果在客户端环境中表示为window对象)的一个属性。而第二个例子则为obj对象由于我们很少直接的引用全局对象就分开来描述。◆ 作为参数被传入别的函数   //高级打印函数的第二个版本 function adPrint2(str, handler){ print(handler(str)); } //将字符串转换为大写形式并返回 function up(str){ return str.toUpperCase(); } //将字符串转换为小写形式并返回 function low(str){ return str.toLowerCase(); } adPrint2(Hello, world, up); adPrint2(Hello, world, low);   运行此片段可以得到这样的结果HELLO, WORLDhello, world应该注意到函数adPrint2的第二个参数事实上是一个函数将这个处理函数作为参数传入在adPrint2的内部仍然可以调用这个函数这个特点在很多地方都是有用的特别是当我们想要处理一些对象但是又不确定以何种形式来处理则完全可以将“处理方式”作为一个抽象的粒度来进行包装(即函数)。 ◆ 作为函数的结果被返回   function currying(){ return function(){ print(curring); } }   函数currying返回一个匿名函数这个匿名函数会打印”curring”简单的调用currying()会得到下面的结果 function (){print(curring);} 如果要调用currying返回的这个匿名函数需要这样currying()();第一个括号操作表示调用currying本身此时返回值为函数第二个括号操作符调用这个返回值则会得到这样的结果currying2、函数的四种调用模式及this的初始化 第一种方法调用模式    以下事例证明通过方法调用模式调用时this绑定到拥有该方法的对象。如 var person {name: defaultName,setName : function(name){this.name name;} }; person.setName(zhangsan); alert(person.name); 第二种函数调用模式    以下事例证明通过函数调用模式调用时this绑定到全局对象上。如 var test add(value1, value2); var name defaultName; var person {name: zhangsan, // person中定义的namegetName : function(){// 通过此方法可以将test函数的this改变为person的this对象var that this; // 解决方案// getName中定义的namevar name lisi;var test function(){// 通过that来访问person中的对象// this指向Global对象// this.name defaultName// that.name zhangsanalert([this.name, that.name]);};test(); // 函数调用模式} } person.getName(); 第三种构造器调用模式 // 定义一个Person的构造器在调用时一定要用new调用 var Person function(name){this.name name; } // 添加一个方法到Person Person.prototype.getName function(){return this.name; }; // 构造一个Person对象 var person new Person(zhangsan); alert(person.getName()); // 调用getName获取person对象中name属性的值 第四种Apply调用模式 script typetext/javascript// 定一个累加方法。如sum(1,2,3,4...)// 该方法位于window执行环境中。var displayName function(){alert(sum的执行环境: typeof(this));alert(Name: this.name); // 取出当前执行环境中name属性}// 定一个Person对象var Person {name: zhangsan};displayName.apply(Person); /script 转载于:https://www.cnblogs.com/dlgood/p/6560820.html
http://www.pierceye.com/news/345593/

相关文章:

  • 主域名进入网站广告标识标牌制作厂家
  • 网站建设基础流程摘要专题网站建设策划
  • 滁州网站建设电话网站建设与网站优化
  • 慈溪做网站公司哪家好淘宝商城的网站建设
  • 安徽建设厅网站怎么打不开太原网络搭建
  • idea 网站开发最好的免费推广平台
  • 专业排名优化网站怎么建网站教程视频app
  • 全国八大员报名官方网站支付宝小程序开发工具
  • 怎么查看vps网站服务器时间中国建设会计协会网站
  • 门户网站上的广告怎么做深圳服装网站建设
  • 公司网站上线的通知抚州营销型网站建设
  • 中国住房城乡和城乡建设部网站小广告文案
  • 做带字头像的网站wordpress 翻页设置
  • 网站横幅js代码公众号如何申请
  • 找网站建设需要问什么软件物联网平台功能
  • 含山县城市建设有限公司网站成都中高风险地区名单最新
  • 鄂州手机网站建设深圳seo网站设计
  • 网站内容的实现方式建筑设计人才招聘
  • 网站做优化效果怎样iis怎么做网站空间
  • 重庆市建设局网站郑州网站建设哪一家好
  • wordpress指定分类广告金融网站排名优化
  • 美妆网站建设方案陕西网络公司网站建设
  • 北京地铁建设的网站深圳建网站兴田德润可信
  • 平台门户网站建设企业战略规划方案
  • 北京网站备案的地址住房和城乡建设部网站质保金
  • 网络营销自学网站腾讯云服务器cvm
  • 建设旅行网站策划书浙江省职业能力建设处网站
  • 网站项目建设的组织机构wordpress做登录
  • 定制杯子岳阳优化营商环境
  • 中学院新校区建设专题网站如何搭建网络教学平台