prototype属性,只有function对象中才具有的显式属性;
网上三种理解:
1:通过构造函数创建的普通对象,通过其constructor属性引用它的构造函数对象,从而间接引用(拥有)了构造对象中的prototype对象;
如图:
此观点的文章: 参看 jimichan的文章:
详解javascript类继承机制的原理 中的:
“(说成间接的是因为每个object都有一个 constructor 属性指向它的构造函数)。” 非常感谢在此问题上,作者对我的回信;如有冒犯,敬请原谅; 2:构造函数创建对象时,copy prototype中的属性和代码给所创建的对象。从而使创建的对象拥有了prototype中的所有功能和属性;
如图:
此观点的文章: 参看 yiding_he的文章:
领悟 JavaScript 中的面向对象 中的:
“ 在 JavaScript 中,用 new 关键字创建对象是执行了下面三个步骤的:
1. 创建一个新的普通对象;
2. 将方法对象的 prototype 属性的所有属性复制到新的普通对象中去。
3. 以新的普通对象作为上下文来执行方法对象。” 此观点在回贴中被 xieye反对 3:构造函数在创建对象时,把构造函数中的prototype引用赋给创建的普通对象;也就是说由构造函数创建的对象,都有一个指针指向prototype对象;
如图:
此观点的文章: 参看 李站的文章:
悟透javascript中的
" 我们已经知道,用 var anObject = new aFunction() 形式创建对象的过程实际上可以分为三步:第一步是建立一个新对象;第二步将该对象内置的原型对象设置为构造函数prototype引用的那个原型对象;第三步就是将该对象作为this参数调用构造函数,完成成员设置等初始化工作。对象建立之后,对象上的任何访问和操作都只与对象自身及其原型链上的那串对象有关,与构造函数再扯不上关系了" 以及
“语法甘露 中的:上面代码的最后一句证明,新创建的对象的constructor属性返回的是Object函数。其实新建的对象自己及其原型里没有constructor属性,那返回的只是最顶层原型对象的构造函数,即Object。”
综上所述:根据贴子:
领悟 JavaScript 中的面向对象 中作者 afcn0的回贴
“其实还有补充,就是如果构造函数返回object类型,那new对象无效,prototype问题是楼主还不太了解prototype继承方式,__proto__属性,以及isPrototypeOf方法所至 ” 的提示,查阅了文章:
javascript中的继承
- 此文中提到:jane = new Engineer("Doe, Jane", ["navigator", "javascript"], "belau");
-
- 调用这句时,都发生了什么:
-
- 1 当js看见new操作符,它创建一个新的普通对象,并且设置它的__proto__ 属性为Engineer.prototype。
-
- 2 new 操作符传递这个新的对象作为Engineer 构造器的this的值。
-
- 其实最主要做的事就是上面的两件,剩下的都是很简单的函数调用.
此文中提到:jane = new Engineer("Doe, Jane", ["navigator", "javascript"], "belau");
调用这句时,都发生了什么:
1 当js看见new操作符,它创建一个新的普通对象,并且设置它的__proto__ 属性为Engineer.prototype。
2 new 操作符传递这个新的对象作为Engineer 构造器的this的值。
其实最主要做的事就是上面的两件,剩下的都是很简单的函数调用.
根据上文的提示作了简单测试:
- function person(name,b){
- this.name=name;
- }
-
- person.prototype.sayHello=function(a){
-
- alert(this==a);
- }
-
-
- function employee(name, salary)
- {
- person.call(this, name);
- this.salary = salary;
- };
-
- var p=new person("yangsp",p);
-
-
-
-
- alert(p.__proto__==person);
- alert(p.__proto__==person.prototype))
-
-
function person(name,b){
this.name=name;
}
person.prototype.sayHello=function(a){
//alert("hello,i am "+this.name);
alert(this==a);
}
function employee(name, salary)
{
person.call(this, name); //调用上层构造函数
this.salary = salary; //扩展的成员
};
var p=new person("yangsp",p);
//p.sayHello(p);
//alert(p.constructor);
//下面两句验证了普通对象中确有_proto_属性,且引用的是prototype对象;(在ff下调试,ie下不可);
alert(p.__proto__==person);
alert(p.__proto__==person.prototype))
//alert("p有prototype属性吗? "+p.prototype); //表明普通对象中没有prototype属性;
总结:
- 比较赞同第三种理解;
- 即:prototype是function对象中专有的属性。
- _proto_是普通对象的隐式属性,在new的时候,会指向prototype所指的对象;
- 普通对象中的constructor属性指向构造函数,因此一个用构造函数创建的对象可能有两种方式关联到prototype.但继承应该是根据_proto_关联到prototype属性;
比较赞同第三种理解;
即:prototype是function对象中专有的属性。
_proto_是普通对象的隐式属性,在new的时候,会指向prototype所指的对象;
普通对象中的constructor属性指向构造函数,因此一个用构造函数创建的对象可能有两种方式关联到prototype.但继承应该是根据_proto_关联到prototype属性;
另外:
ecma-262中提到:every object created by that constructor has an implicit reference to the prototype (called the object's prototype) associated with its constructor 以及其图示;不敢肯定它的implicit reference间接还是隐式链接;