2017.4.07 js 中的function 实现的方式

函数分为FD (函数定义),FE(函数表达式) ,函数构造器得到的函数
(1)  FD 的栗子:
function getTaste(){
 .......
}
解析器遇到上面的function关键字,会解析上面的代码为函数定义的情况,凡是不符合上述格式的,会报错。
(2)FE的栗子:
var fn = function (){
  ......
}

解析器会把上面的function关键字解析为表达式的情况。本例中的function后面可有函数名字,但是仅限于函数定义内调用。外面调用会用fn。
var fn = function sbfn(){
  ......
  sbfn();  //
}

把function解析为表达式的情况,有另外的栗子:
1, function () {
  alert('anonymous function is called');
}();
此处为逗号运算符情况,取值逗号后面的结果undefined。

!function () {
alert('ECMAScript');
}();
此处为!运算符情况,后面结果返回undefined 。!取反,结果为true。

(3)函数构造器的栗子
其主要特点在于这种函数的[[Scope]]属性仅包含全局对象(window)

var x = 10;

function f() {

var x = 20;
var y = 30;

var bar = new Function('alert(x); alert(y);');

bar(); // 10, "y" 未定义

}

f();
顺便提醒一句,Function构造器既可使用new 关键字,也可以没有,这样说来,这些变体是等价的。

创建函数的算法

下面的伪码描述了函数创建的算法(与联合对象相关的步骤除外)。这些描述有助于你理解ECMAScript中函数对象的更多细节。这种算法适合所有的函数类型。

F = new NativeObject();

// 属性[[Class]]是"Function"
F.[[Class]] = "Function"

// 函数对象的原型是Function的原型
F.[[Prototype]] = Function.prototype

// 医用到函数自身
// 调用表达式F的时候激活[[Call]]
// 并且创建新的执行上下文
F.[[Call]] = <reference to function>

// 在对象的普通构造器里编译
// [[Construct]] 通过new关键字激活
// 并且给新对象分配内存
// 然后调用F.[[Call]]初始化作为this传递的新创建的对象
F.[[Construct]] = internalConstructor

// 当前执行上下文的作用域链
// 例如,创建F的上下文
F.[[Scope]] = activeContext.Scope
// 如果函数通过new Function(...)来创建,
// 那么
F.[[Scope]] = globalContext.Scope

// 传入参数的个数
F.length = countParameters

// F对象创建的原型
__objectPrototype = new Object();
__objectPrototype.constructor = F // {DontEnum}, 在循环里不可枚举x
F.prototype = __objectPrototype

return F

注意,F.[[Prototype]]是函数(构造器)的一个原型,F.prototype是通过这个函数创建的对象的原型(因为术语常常混乱,一些文章中F.prototype被称之为“构造器的原型”,这是不正确的)。

posted @ 2017-04-07 11:27  a fine day  阅读(244)  评论(0编辑  收藏  举报