new()关键字的形式化代码
------
我们先来看“obj1 = new MyObject()”这行代码中的这个new关键字。 new关键字用于产生一个新的实例(说到这里补充一下,我习惯于把保留字叫关键
字。另外,在JavaScript中new关键字同时也是一个运算符),这个实例的缺省属性
中,(至少)会执有构造器函数的原型属性(prototype)的一个引用(在ECMA Javascript
规范中,对象的这个属性名定义为__proto__)。
每一个函数,无论它是否用作构造器,都会有一个独一无二的原型对象(prototype)。
对于JavaScript“内置对象的构造器”来说,它指向内部的一个原型。缺省时JavaScript
构造出一个“空的初始对象实例(不是null)”并使原型引用指向它。然而如果你给函
数的这个prototype赋一个新的对象,那么新的对象实例将执有它的一个引用。
接下来,构造过程将调用MyObject()来完成初始化。——注意,这里只是“初始
化”。
为了清楚地解释这个过程,我用代码形式化地描述一下这个过程:
//---------------------------------------------------------
// new()关键字的形式化代码
//---------------------------------------------------------
function new(aFunction) {
// 基本对象实例
var _this = {};
// 原型引用
var _proto= aFunction.prototype;
/* if compat ECMA Script
_this.__proto__ = _proto;
*/
// 为存取原型中的属性添加(内部的)getter
_this._js_GetAttributes= function(name) {
if (_existAttribute.call(this, name))
return this[name]
else if (_js_LookupProperty.call(_proto, name))
retrun OBJ_GET_ATTRIBUTES.call(_proto, name)
else
return undefined;
}
// 为存取原型中的属性添加(内部的)setter
_this._js_GetAttributes = function(name, value) {
if (_existAttribute.call(this, name))
this[name] = value
else if (OBJ_GET_ATTRIBUTES.call(_proto, name) !== value) {
this[name] = value // 创建当前实例的新成员
}
}
// 调用构造函数完成初始化, (如果有,)传入args
var ret=aFunction.call(_this);//
// 返回对象
if(typeof ret=="object")
//如果函数本身返回的是个对象,那么这个构造函数的意义就全无了
//返回的是构造器函数return的那个对象
return ret;
else return _this;
}
所以我们看到以下两点:
- 构造函数(aFunction)本身只是对传入的this实例做“初始化”处理,而
不是构造一个对象实例。
- 构造的过程实际发生在new()关键字/运算符的内部。
而且,构造函数(aFunction)本身并不需要操作prototype,也不需要回传this。
<script>
function Dog(name) {
this.name = name;
this.respondTo = function(name) {
if(this.name == name) {
alert("Woof");
}
};
this.toString=function(){return 1;}
return {};
}
var spot = new Dog("Spot");alert(spot);
spot.respondTo("Spot");
</script>
<script>
function _new(f)
{
var o={};
f.call(o);
return o;
}
function a()
{
this.p=1;
var obj={};
obj.p=2;
return obj;
//return this;
}
var o=_new(a);
alert(o.p);
var o2=new a;
alert(o2.p);
</script>
回复 更多评论