本篇文章聊聊函数属性和方法 。

四. 函数属性和方法

前面博文曾经提到过,ECMAScript 中的函数是对象,因此函数也有属性和方法。每个函数都包含两个属性:length 和 prototype。其中,length 属性表示函数希望接收的命名参数的个数,如下面的例子所示。

function sayName(name){alert(name);
}
function sum(num1, num2){return num1 + num2; }
function sayHi(){ alert("hi");
}
alert(sayName.length);  //1
alert(sum.length);      //2
alert(sayHi.length);    //0

以上代码定义了 3 个函数,但每个函数接收的命名参数个数不同。首先,sayName()函数定义了一个参数,因此其 length 属性的值为 1。类似地,sum()函数定义了两个参数,结果其 length 属性中保存的值为 2。而 sayHi()没有命名参数,所以其 length 值为 0。
在 ECMAScript 核心所定义的全部属性中,最耐人寻味的就要数 prototype 属性了。对于ECMAScript 中的引用类型而言,prototype 是保存它们所有实例方法的真正所在。换句话说,诸如toString()和 valueOf()等方法实际上都保存在 prototype 名下,只不过是通过各自对象的实例访问罢了。在创建自定义引用类型以及实现继承时,prototype 属性的作用是极为重要的(第 6 章将详细介绍)。在 ECMAScript 5 中,prototype 属性是不可枚举的,因此使用 for-in 无法发现。
每个函数都包含两个非继承而来的方法:apply()和 call()。这两个方法的用途都是在特定的作用域中调用函数,实际上等于设置函数体内 this 对象的值。首先,apply()方法接收两个参数:一个是在其中运行函数的作用域,另一个是参数数组。其中,第二个参数可以是 Array 的实例,也可以是arguments 对象。例如:

function sum(num1, num2){return num1 + num2;
}
function callSum1(num1, num2){return sum.apply(this, arguments);      // 传入 arguments 对象
}
function callSum2(num1, num2){ return sum.apply(this, [num1, num2]);   // 传入数组
}
alert(callSum1(10, 10));    //20
alert(callSum2(10, 10));    //20

在上面这个例子中,callSum1()在执行 sum()函数时传入了 this 作为 this 值(因为是在全局作用域中调用的,所以传入的就是 window 对象)和 arguments 对象。而 callSum2 同样也调用了sum()函数,但它传入的则是 this 和一个参数数组。这两个函数都会正常执行并返回正确的结果。

call()方法与 apply()方法的作用相同,它们的区别仅在于接收参数的方式不同。对于 call()方法而言,第一个参数是 this 值没有变化,变化的是其余参数都直接传递给函数。换句话说,在使用call()方法时,传递给函数的参数必须逐个列举出来,如下面的例子所示。

function sum(num1, num2) {return num1 + num2;
}
function callSum(num1, num2) {return sum.call(this, num1, num2);
}
alert(callSum(10, 10)); //20

在使用 call()方法的情况下,callSum()必须明确地传入每一个参数。结果与使用 apply()没有什么不同。至于是使用 apply()还是 call(),完全取决于你采取哪种给函数传递参数的方式最方便。如果你打算直接传入 arguments 对象,或者包含函数中先接收到的也是一个数组,那么使用 apply()肯定更方便;否则,选择 call()可能更合适。(在不给函数传递参数的情况下,使用哪个方法都无所谓。)
事实上,传递参数并非 apply()和 call()真正的用武之地;它们真正强大的地方是能够扩充函数赖以运行的作用域。下面来看一个例子。

window.color = "red";
var o = { color: "blue" };
function sayColor() {alert(this.color);
}
sayColor();                 //red
sayColor.call(this);        //red
sayColor.call(window);      //red
sayColor.call(o);           //blue

这个例子是在前面说明 this 对象的示例基础上修改而成的。这一次,sayColor()也是作为全局函数定义的,而且当在全局作用域中调用它时,它确实会显示"red"——因为对 this.color 的求值会转换成对 window.color 的求值。而 sayColor.call(this)和 sayColor.call(window),则是两种显式地在全局作用域中调用函数的方式,结果当然都会显示"red"。但是,当运行 sayColor.call(o)时,函数的执行环境就不一样了,因为此时函数体内的 this 对象指向了 o,于是结果显示的是"blue"。
使用 call()(或 apply())来扩充作用域的最大好处,就是对象不需要与方法有任何耦合关系。在前面例子的第一个版本中,我们是先将 sayColor()函数放到了对象 o 中,然后再通过 o 来调用它的;而在这里重写的例子中,就不需要先前那个多余的步骤了。
ECMAScript 5 还定义了一个方法:bind()。这个方法会创建一个函数的实例,其 this 值会被绑定到传给 bind()函数的值。例如:

window.color = "red";
var o = { color: "blue" };
function sayColor(){ alert(this.color);
}
var objectSayColor = sayColor.bind(o);
objectSayColor();    //blue 

在这里,sayColor()调用 bind()并传入对象 o,创建了 objectSayColor()函数。object-SayColor()函数的 this 值等于 o,因此即使是在全局作用域中调用这个函数,也会看到"blue"。

每个函数继承的 toLocaleString()和 toString()方法始终都返回函数的代码。返回代码的格式则因浏览器而异——有的返回的代码与源代码中的函数代码一样,而有的则返回函数代码的内部表示,即由解析器删除了注释并对某些代码作了改动后的代码。由于存在这些差异,我们无法根据这两个方法返回的结果来实现任何重要功能;不过,这些信息在调试代码时倒是很有用。另外一个继承的valueOf()方法同样也只返回函数代码。

好了,本篇文章就介绍到这儿,欢迎大家留言交流;喜欢或有帮助到您的话,点个赞或推荐支持一下!

转载于:https://www.cnblogs.com/johnvwan/p/9552112.html

ECMAScript 5 —— Function 类型 (四)相关推荐

  1. 【js实例】Array类型的9个数组方法,Date类型的41个日期方法,Function类型

    前文提要:[js实例]js中的5种基本数据类型和9种操作符 Array类型的9个数组方法 Array中有9个数组方法: 1.检测数组 2.转换方法 3.栈方法 4.队列方法 5.冲排序方法 6.操作方 ...

  2. 「译」ECMAScript 提案:类型注解(TypeScript 在未来可能被纳入 ECMAScript 中)

    原文标题:ECMAScript proposal: Type Annotations 原文链接:github.com/tc39/propos- ECMAScript 关于类型注解的提案已进入 stag ...

  3. Function类型(JS高程3)—— JS学习笔记2015-6-29(第70天)

    Function 类型 函数是对象 具有属性和方法,函数名实际上是一个指向函数对象的指针 没有重载: 函数声明和函数表达式 函数声明: function sum (num1, num2){ retur ...

  4. JavaScript面向对象之Function类型

    JavaScript面向对象之Function类型 下面是我对Function类型的总结,希望对您有帮助. "函数式编程"是一种"编程范式"(programmi ...

  5. 《JavaScript高级程序设计 (第3版)》学习笔记14:chapter_5 - 5 Function类型

    这是第14篇笔记! 让学习"上瘾",成为更好的自己! <!DOCTYPE html> <html lang="en"> <head ...

  6. 【笔记】js Function类型 内部方法callee

    运用function实现阶乘 以往的做法是如下的 function factorial(num){if(num <= 1){return 1;}else{return num * factori ...

  7. JavaScript之function类型

    每个函数都是function类型的实例 function name() var name= function() 转载于:https://www.cnblogs.com/anderson0/p/482 ...

  8. Function类型(函数)

    Function类型 1.函数实际上是对象,函数名是指向函数对象的指针,因此函数名与其他指向该函数的变量没有什么不同. 比如: function func (){console.log("f ...

  9. JavaScript的Function 类型

    一,Function定义 Function实际上是对象,与其他引用类型一样具有属性和方法.Function可以通过三种方法进行定义,分别是函数声明语法定义,函数表达式定义和Function构造函数定义 ...

最新文章

  1. 推荐一个XNA的学习站点
  2. linux多线程基本编程
  3. C# Winform 窗体美化(七、Win7 Aero 毛玻璃效果)
  4. 信息学奥赛一本通 1220:单词接龙 | 1913:【00NOIP普及组】单词接龙 | OpenJudge NOI 2.5 8783 | 洛谷 P1019 [NOIP2000 提高组] 单词接龙
  5. svn常用命令与分支操作
  6. 关于TensorFlow的MNIST数据集下载脚本input_data.py的坑
  7. 小米 MIUI 主题制作
  8. matlab画矩阵中的两列,matlab 图例 两列
  9. CSDN去广告,超清爽界面
  10. Mac/Linux/Ubuntu下 视频 显示双语/中英字幕 的方法
  11. 新番 | 万万没想到,Hulu有一天也开始推新番了
  12. 纯js实现减速滚动置顶效果
  13. 【时间之外】面向监狱的编程?该学学网络安全法了(2)
  14. 浅谈远心镜头选择十大参数
  15. TCP原理,Socket与网络编程入门
  16. 对象,构造函数,构造函数小练习
  17. onMeasure(int widthMeasureSpec, int heightMeasureSpec)
  18. 别让虚拟化成为“永恒之蓝”的下一个攻击目标
  19. 携职教育:财政部最新发文!初级会计持证人数规模预计将达900万
  20. Manjaro无法启动?别急,试试grub 命令加载系统。

热门文章

  1. UVA10294项链和手镯(等价类计数问题)
  2. hdu3074 线段树求区间乘积(单点更新)
  3. hdu4861 找规律了
  4. 【Android 逆向】Android 进程注入工具开发 ( 注入代码分析 | 注入工具收尾操作 | 关闭注入的动态库 | 恢复寄存器 | 脱离远程调试附着 )
  5. 【错误记录】Android Studio 配置 GitHub 报错 ( Can‘t login using given credentials: Request response: 401 Una )
  6. 【Android 插件化】VirtualApp 源码分析 ( 添加应用源码分析 | LaunchpadAdapter 适配器 | 适配器添加元素 | PackageAppData 元素 )
  7. 【Android 应用开发】AndroidUI设计之 布局管理器 - 详细解析布局实现
  8. vue邪道玩法 : 把vue实例存在别的地方,以及可能会遇到的问题
  9. NSAssert的使用
  10. python学习 day19