JS简记-原型二

上一节我们以Object函数对象的prototype为例观察了一个对象的__proto__,这节我们再来看一下Function函数对象。

var f1 = new Function("name", "console.log(name);");
f1("zyong");
function f2(name){
    console.log(name);
}
f2("zyong2");

 我们可以看到两种方式声明的函数内容是一致的,且其都存在arguments(实参,函数运行前由引擎设置)、caller(调用者对象,函数运行前由引擎设置)、length(形参个数)、name(函数名?通过Object.getOwnPropertyDescriptor发现该属性不可写但可配置,所以将其改为可写后更新属性的值,属性值确实更新了,但最终呈现的函数名依旧是anonymous)等属性。

 每一个函数对象都会存在prototype和__proto__属性,下面以f1为例来看:

prototype中有两个属性,constructor其实就是指向函数自身,__proto__则指向Object.prototype。

__proto__提供了许多我们常见的属性,比如bind、call、apply等函数。

_proto__中的get arguments/set arguments和get caller/set caller顾名思义是存取arguments和caller的,首先无法直接对两个属性进行设置(设置无效),然后通过Object.getOwnPropertyDescriptor观察到二者都是不可写且不可配置的,也就意味着无法手动使用Object.defineProperty通过修改value或setter更新二者的值,可以猜测,js试图防止人为的更新这两个属性,不但将“属性描述符”设置为不可写且不可配置,而且将setter方法设为空函数(函数内部无逻辑)。

1 function f(name){
2     console.log(f.caller);
3     console.log(f.caller.a);
4     console.log(f.arguments);
5 }
6 (function f2(){
7     f2.a = 1;
8     f("zyong");
9 })();

 控制台打印如下:

 

我们看到了f1函数对象的__proto__,那么可以肯定Function.prototype一定也是这个样子的,下面来可能Function的结构:

首先Function同样是一个函数,其同样拥有caller、arguments、length、name、prototype、__proto__属性,如期望的那样,prototype就是我们所预料的,而由于Function本身也是一个函数,所以其也需要call、apply、bind等属性,所以其__proto__如其他函数对象一样,也就是说Function的prototype和__proto__是一致的。

posted @ 2018-05-02 23:14  holoyong  阅读(138)  评论(0编辑  收藏  举报