JavaScript的进阶之路(六)理解函数
函数:定义一次,多次调用;用于对象的属性则称为对象的方法;在JavaScript中,函数即对象;嵌套的函数形成闭包;
定义函数和简单调用函数:
- //函数定义
- function f1(){ //没有参数的函数
- return true;
- }
- function f2(x,y){//有参数的函数
- return x+y;
- }
- var f3=new Function("x","y","return x+y"); //new方法定义函数
- var f4 = function(x,y){return x+y;} //表达式定义函数
- var f5 = function fac(x){if(x<=1) return 1;return x*fac(x-1);} //表达式定义一个有名字的函数f5,递归调用函数
- //函数的用法
- console.log(f5(5)); //直接调用
- var f6 = (function(x){return x*x;})(10); //定义后立即调用执行,此时f6是number 100
- var data = [1,3,2,5,4];
- var sort = data.sort(function(a,b){return a-b;}); //函数作为值传递给其他函数
- function f7(x,y){
- function square(a){ return a*a};
- return square(x)+square(y); //内部函数square可以直接访问外部函数f7的参数x,y
- }
- console.log(f7(2,3));
函数的形参和实参
- //实例:给数组中添加元素
- function addElement(e,a){
- a = a || []; //注意这句 : 未定义则为空数组,这样在调用函数的时候第二个参数可以不传
- a.push(e);
- return a;
- }
- var arr = [1,2,3];
- console.log(addElement(4));
- console.log(addElement(4,arr));
- //arguments参数数组
- var factorial = function (x){
- if(x<=1) return 1;
- return x*arguments.callee(x-1); //arguments.callee递归的调用自身
- }
作为值得函数:将函数赋值给变量,赋值给对象的属性,作为其他函数的参数,都是函数作为值得表现。
函数作用域:在函数中声明的变量,在函数体内都是可见的(包括嵌套函数内),在函数外部是不可见的,要想在函数外部访问,需要用到闭包;
关于闭包:
理解闭包:闭包是一种特性:通过作用域链,函数体内部的变量都可以保存在函数作用域内。这个变量作用域是在函数定义时就决定的。
但是:调用时的变量作用域和定义函数时的变量作用域不一样的时候呢?答案是:总是返回定义函数时的变量作用域。
闭包的用途:
1、访问函数作用域内的变量
- //嵌套函数的词法作用域规则
- var str="global";
- function check(){
- var str="local";
- function f(){return str};
- return f();
- }
- console.log(check()); //local
- var str1="global";
- function check1(){
- var str1="local";
- function f(){return str1};
- return f;
- }
- //这里看似调用潜逃的函数f() 在函数作用域外没有这个函数,但是同样返回local;因为变量作用域链在函数定义的时候就创建了
- console.log(check1()()); //local
2、防止变量污染
- var count = 1; //这里的变量可以影响函数体common的结果
- function common(){
- return count++;
- }
- common();
- console.log(count); // 2
- var a = 3; //这里变量a可以随意定义,不会污染影响now函数体内的变量
- //定义一个函数并立即调用
- var now=(function f(){
- var a=1;
- return function(){
- return ++a;
- }
- })();
- console.log(now());
函数的属性、方法
- //函数的属性、方法和构造函数
- //属性length和prototype
- function f(x,y,z){
- return x+y+z;
- }
- console.log(f.call(this,1,3,4)); //
- console.log(f.apply(this,[1,2,3])); //
- var array=[1,2,3,4,5];
- var max=Math.max.apply(this,array);
- var max1=Math.max(1,2,3,4,5);
- var max2=Math.max.call(this,1,2,3,4,5);
- console.log(max+" "+max1+" "+max2); / 5 5 5
- //bind()方法 给对象绑定一个自定义的函数
- var o={x:1}; //待绑定的对象
- function fn(y){return this.x+y};//待绑定的函数
- var g= fn.bind(o);
- console.log(g(2)); // 3
- function obf(f,o){
- if(f.bind){
- return f.bind(o);
- }else{
- return function(){
- return f.apply(o,arguments);
- }
- }
- }
- var g1=obf(fn,o);
- console.log(g1(2)); //3
- var sum=function(x,y){return x+y};
- var sum1=sum.bind(null,1);
- console.log(sum1(2)); //
- var sum2=function(y,z){return this.x+y+z};
- var sum3=sum2.bind({x:1},2); //绑定this和y
- console.log(sum3(3));
JavaScript的进阶之路(六)理解函数的更多相关文章
- JavaScript的进阶之路(五)理解数组1
数组是值得有序结合,每个值叫做一个元素,每个元素的位置称为索引,索引从0开始. 在JavaScript中,数组是对象的特殊形式.继承自Array.prototype中的属性,有丰富的数组操作方法. 通 ...
- JavaScript的进阶之路(四)理解对象2
对象的三个属性 原型属性 1.var v={}的原型是Object.prototype;继承了一个constructor属性指代Object()构造函数,实际的原型是constructor.proto ...
- JavaScript的进阶之路(四)理解对象1
对象是JavaScript的基本数据类型.简单的名值对组成了对象,BUT:还可以从一个被称为原型的对象继承属性,对象的方法通常就是继承的属性. 对象最常见的用法有:创建.设置.查找.删除.检测.枚举它 ...
- JavaScript的进阶之路(二)函数简介,变量、作用域和内存问题
<h3>ECMAScript中函数不存在函数签名的概念,没有重载</h3><h3>无需指定返回值,可以在任何时候返回任何值.未指定返回值的函数,返回的是一个特殊的u ...
- JavaScript的进阶之路(五)理解数组2
数组方法 //定义一个测试数组 var array1 = [1,2,5,null,"a"]; //join()方法是String.split()方法的逆操作,后者是将字符串分割成若 ...
- JavaScript的进阶之路(一)
JavaScript由ECMAScript BOM DOM三部分组成 ECMAScript重要版本1,3,5,6,提供核心语言功能 DOM提供访问和操作网页内容的方法和接口 BOM提供与浏览器交互的的 ...
- JavaScript正则进阶之路——活学妙用奇淫正则表达式
原文收录在我的 GitHub博客 (https://github.com/jawil/blog) ,喜欢的可以关注最新动态,大家一起多交流学习,共同进步,以学习者的身份写博客,记录点滴. 有些童鞋肯定 ...
- PHP 进阶之路 - 深入理解 FastCGI 协议以及在 PHP 中的实现
在讨论 FastCGI 之前,不得不说传统的 CGI 的工作原理,同时应该大概了解 CGI 1.1 协议 传统 CGI 工作原理分析 客户端访问某个 URL 地址之后,通过 GET/POST/PUT ...
- JavaScript的进阶之路(七)客户端JavaScript知识点总结
一.客户端JavaScript主要是BOM DOM的操作和js脚本的兼容性.互用性.可访问性.安全性的应用.以及一些框架的引用. 二.BOM:浏览器对象模型 主要介绍window对象 1.定时器:se ...
随机推荐
- Vultr VPS建站攻略 – 一键安装宝塔面板架设LNMP/LAMP Web环境
我们选择VULTR VPS建站的还是比较多的,其主要原因在于商家的稳定,毕竟我们用来建站选择服务器价格考虑的不是主要的(当然VULTR价格也是比较便宜),最为主要的是因为VULTR商家比较稳定,而且多 ...
- TeamView 连接2、3事
问题1: 客户通过本地远程上服务器开TeamView让我们连,我们连上后发现开户一把她的远程关掉就卡住了. 如图,原来TeamView会启动多用户增强支持. 原来用的是用户ID连的,用户断掉远程后就不 ...
- 【Python】解析Python的标准数据类型
目录结构: contents structure [-] 数值(Number) 数值类型 类型转化 Python中的Decimal数据类型 Python中的分数 Python中的算术方法 字符串(St ...
- 1091 N-自守数 (15 分)
// 建一个判断函数,接受两个整形的变量,再通过循环按位判断相等与否,主体函数中调用被调函数,建立一个判断变量.#include <iostream> using namespace st ...
- Android Studio 学习笔记1.1 创建自己的第一个安卓项目并且打包APK
自从上一次安装完安卓开发工具Android Studio后抽时间看视屏尝试编写自己的第一个安卓项目约两周的时间 每天下班后会花上1~2小时的时间去学习 目前的成果如下:次元宅的我.apk 嘛 总而 ...
- 思科 ISR路由器登录内置交换模块的方式
ISR2900/3900系列 登录:Router#service-module gigabitethernet1/0 session 退出: control+shift+6 x disconnect ...
- 常见的错误:FTP连接时出现“227 Entering Passive Mode”
FTP的主动模式(PORT Mode)及被动模式(Passive Mode) FTP的特殊性: 大多数的TCP服务是使用单个的连接,一般是客户向服务器的一个周知端口发起连接,然后使用这个连接进行通讯. ...
- 剑指offer——面试题26:判断二叉树B是否为二叉树A的子结构
#include"iostream" #include"stdio.h" #include"math.h" using namespace ...
- div实现高度自适应的textarea
textarea使我们常常使用的一种表单形式,多用于大段文字的输入,大多数情况下,textarea都是可以满足需求的,但是当我们希望这个输入框高度自适应的时候,textarea就很难做到了. ok,主 ...
- C# 委托的一些使用上的小技巧
1.委托是一种数据类型,我们可以在任何定义类的地方定义委托,在任何声明类的地方声明委托 2.初始化委托有两种方式,代码如下: (1).像类一样初始化委托 public delegate void Sa ...