函数对象,函数对象。前一章讲函数,这一章讲讲对象。函数时候还是比较严肃的讲说,毕竟有一等公民在,不能随便放肆。现在讲对象了,反倒是放开了。
大驼峰帕斯卡命名,通常就是“作为”对象了。像什么Object,String云云。但凡是对象,总要new的。坊间开个玩笑说,今年过节又没有对象吧,自己给自己new一个不就完事了,谁叫js是面向对象编程的呢。
言归正传,下面就定义一个对象来:
function Foo (){ }
不知道为什么要选foo
,可能因为别的示例也用foo吧,就照猫画虎的用了,反正是没有版权的。
这个乍一看和函数是一样的,没错,他就是和函数一样的。只是因为命名上的人为区分,所以主观上分成了两类,一类叫函数一类叫对象。实际上他们都是Function。
作为对象,自然要new出来的:
var foo = new Foo();
var foo2 = new Foo;
提示:在无参数情况下,使用new Foo() 和new Foo 是等同行为,但是如果是普通的函数调用就不可以了。
在new 操作符标准中,叙述了具体创建流程,那我这里就简述一下流程:
- 创建一个新对象,它的__proto__属性指向 Foo.prototype (这个之前在继承一章中讲过)
- 使用指定的参数调用Foo构造函数(其实就是Foo函数),并将this绑定到新的对象上
- 如果在函数内部有return值,则使用新的值作为返回值,否则使用 1 创建的对象作为返回值。
这三步,完全解释了一个函数转对象的具体流程。
我们按照这个规则可以自己仿照一个函数构造过程:
function Template(name){
this.name=name;
}
var b = {};
b.__proto__ = Template.prototype;
b.constructor = Template;
var tempObj = Template.call(b,'templateB');
if( tempObj != undefined ){
b = tempObj ;
}
虽然实际上并不是这么简单的构造,但是的确可以仿造出一个new对象来。
再说一下this
上一章函数结尾说了this,这一章同样要说一下this,毕竟我们在Template里面也是用了this。
这里用到了一个函数 call。这个函数就是执行并更改this指向的操作。
call这个函数来自于 Function.prototype.call
第一个参数代表 : this所指向的对象,
其余参数代表:函数本身执行时所需要的参数了,如果没有参数,自然是不需要的。
同样操作的还有apply来自于Function.prototype.apply
第一个参数代表 : this所指向的对象,
第二个参数代表:是一个数组,按数组元素顺序传递函数本身所需的参数,如果没有参数,自然是不需要的
还有一个只绑定不执行的bind来自于Function.prototype.bind
第一个参数代表 :this所指向的对象,
其余参数代表 :当函数被执行时所优先传递的参数内容,
摘自MDN的bind:
function list() {
return Array.prototype.slice.call(arguments);
}
var list1 = list(1, 2, 3); // [1, 2, 3]
// Create a function with a preset leading argument
var leadingThirtysevenList = list.bind(null, 37);
var list2 = leadingThirtysevenList();
// [37]
var list3 = leadingThirtysevenList(1, 2, 3);
// [37, 1, 2, 3]