内容简介:函数也是对象,使对象不同于其它对象的决定性特点是函数存在一个被称为类似于ECMAScript为JavaScript的对象定义了多种内部属性,这些
函数也是对象,使对象不同于其它对象的决定性特点是函数存在一个被称为 [[Call]]
的内部属性。
类似于 [[Call]]
这种内部属性无法通过代码访问,他只是定义了代码执行时的行为。
ECMAScript为JavaScript的对象定义了多种内部属性,这些 内部属性都用双重中括号来标注 。
[[Call]] 属性是函数独有的,表明该对象可以被执行。由于仅函数拥有该属性,ECMAScript 定义 typeof 操作符对任何具有 [[Call]] 属性的对象返回 "function"。
过去因某些浏览器曾在正则表达式中包含 [[Call]]
属性,导致正则表达式被错误鉴别为函数。
2.1 声明还是表达式
函数有两种字面形式:函数声明跟函数表达式。
两者的一个重要区别是:函数声明会被提升至上下文(要么是该函数被声明时所在的函数范围,要么是全局范围)的顶部。
2.2 函数就是值
函数是JavaScript的一大重点。
基本上只要是可以使用其他引用值的地方,你就可以使用函数。也就是说,你可以像使用对象一样使用函数(因为函数本来就是对象)。
2.3 参数
JavaScript函数另一个独特之处在于你可以给函数传递任意数量的参数却不造成错误。
这是因为函数参数保存在类数组对象 arguments
中。
如同一个普通JavaScript数组,arguments可以自由增长来包含任意个数的值,这些值可通过数字索引来引用。
虽然arguments类似数组,但是 Array.isArray(arguments)
返回 false
最后需要注意两点:
length
2.4 重载
大多数面向对象语言支持函数重载,它能让一个函数具有多个签名。函数签名由函数的名字、参数的个数及其类型组成。
而 JavaScript 可以接收任意数量的参数且参数类型完全没有限制。这说明 JavaScript 函数根本就没有签名,因此也不存在重载。
function sayMessage(message){ console.log(message); } function sayMessage(){ console.log("Default Message"); } sayMessage("Hello!"); // 输出"Default Message"; 复制代码
在 JavaScript 里,当你试图定义多个同名的函数时,只有最后的定义有效,之前的函数声明被完全删除(函数也是对象,变量只是存指针)。
var sayMessage = new Function("message", "console.log(message)"); var sayMessage = new Function("console.log(\"Default Message\");"); sayMessage("Hello!"); 复制代码
当然,你可以根据传入参数的数量来模仿重载。
2.5 对象方法
对象的值是函数,则该属性被称为方法。
2.5.1 this 对象
JavaScript 所有的函数作用域内都有一个 this
对象代表调用该函数的对象。
在全局作用域中, this
代表全局对象(浏览器里的 window)。
当一个函数作为对象的方法调用时,默认 this
的值等于该对象。
this在函数调用时才被设置。
function sayNameForAll(){ console.log(this.name); } var person1 = { name: "Nicholas", sayName: sayNameForAll } var name = "Jack"; person1.sayName(); // 输出 "Nicholas" sayNameforAll(); // 输出 "Jack" 复制代码
2.5.2 改变 this
有3种函数方法运行你改变 this
值。
- fun.call(thisArg[, arg1[, arg2[, ...]]]);
- fun.apply(thisArg, [argsArray]);
- fun.bind(thisArg[, arg1[, arg2[, ...]]])
使用 call
或 apply
方法,就不需要将函数加入每个对象——你显示地指定了 this
的值而不是让 JavaScript 引擎自动指定。
call
与 apply
的不同地方是, call
需要把所有参数一个个列出来,而 apply
的参数需要一个数组或者类似数组的对象(如 arguments
对象)。
bind
是 ECMAScript 5 新增的,它会创建一个新函数返回。其参数与 call
类似,而且其所有参数代表需要被 永久
设置在新函数中的命名参数(绑定了的参数(没绑定的参数依然可以传入),就算调用时再传入其它参数,也不会影响这些绑定的参数)。
function sayNameForAll(label){ console.log(label + ":" + this.name); } var person = { name: "Nicholas" } var sayNameForPerson = sayNameForAll.bind(person); sayNameForPerson("Person"); // 输出"Person:Nicholas" var sayName = sayNameForAll.bind(person, "Jc"); sayName("change"); // 输出"Jc:Nicholas" 因为绑定的形参,会忽略调用时再传入参数 复制代码
以上所述就是小编给大家介绍的《《JavaScript面向对象精要》之二:函数》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 《JavaScript面向对象精要》之四:构造函数和原型对象
- 《JavaScript面向对象精要》--构造函数和原型链读后总结
- 内存管理设计精要
- 网络爬虫精要
- 调度系统设计精要
- 《JavaScript面向对象精要》之五:继承
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。