当代码new Animal("cat")
执行时:html
var obj=Object.create(Animal.prototype);
前端
传入cat参数,构造函数Animal执行。同时构造函数内部的this被指定为obj。函数
若是构造函数返回了一个“对象”,那么这个对象就是new出来的结果。若是构造函数没有返回对象(即返回一个非对象值,例如数值,或者无返回值
),那么new出来的结果为obj对象。通常状况下构造函数不返回值,除非你想要覆盖正常建立的对象(即obj)。this
例如:spa
function A(name){ this.name=name; return 3; } var new1=new A("aa"); new1;//A {name: "aa"} function B(name){ this.name=name; return {}; } var new2=new B("aa"); new2;//new2为一个空对象。
JS权威指南中有一句很精辟的描述: “JavaScript中的函数运行在它们被定义的做用域里
,而不是它们被执行的做用域里。”简单来讲,就是函数被调用时,它是运行在当时定义该函数时的环境中的。prototype
当定义函数a的时候,js解释器会将函数a的做用域链(scope chain)设置为定义a时所在的“环境”
,并为a添加scope属性,a.scope=a的做用域链。若是a定义在全局环境,那么scope chain中只有window对象。code
当函数被调用时,会建立一个活动对象(call object)(也就是一个对象), 而后把全部函数a的局部变量和函数定义添加为该活动对象的属性
, 并将该活动对象添加到a的做用域链的最顶端,此时a的做用域链包含2个对象:a的活动对象和window对象。htm
为何调用func1(10)和func2(10)时,引用到了两个不一样的i?对象
function outerFn(i, j) { var x = i + j; return function innerFn(x) { return i + x; } } var func1 = outerFn(5, 6); var func2 = outerFn(10, 20); alert(func1(10)); //返回15 alert(func2(10)); //返回20
调用outerFn (5, 6)的时候定义了一个新的函数对象innerFn,而后该函数对象成为了outerFn函数的活动对象的一个属性。这时innerFn的做用域链是由outerFn的活动对象和全局对象组成的.。这个做用域链存储在了innerFn函数的内部属性[[scope]]中,而后返回了该函数,变量func1就指向了这个innerFn函数。blog
在func1被调用时,它自身的活动对象被建立,而后添加到了[[scope]]中存储着的做用域链的最前方。这时的做用域链才是func1函数执行时用到的做用域链。从这个做用域链中,能够看到变量‘i’的值实际上就是在执行outerFn(5,6)时产生的活动对象的属性i的值。下图显示了整个流程。
下图是func2执行时的状况。由于在定义func1和func2时,函数outerFn中产生过两个不一样的活动对象,因此才致使调用func1(10)和func2(10)时,引用到了两个不一样的i。
一个活动对象在函数执行的时候建立,同时被添加到该函数的做用域链的最前端。当函数执行完毕时,活动对象会被从该做用域链上删除。
可是该活动对象是否会被垃圾回收器销毁,还要看其余地方是否还有使用到该活动对象。