请教原型中定义成员的疑问?
发布于 12 年前 作者 hhuai 4428 次浏览 最后一次编辑是 8 年前

有书《Node.js开发指南》这书的看一下162页,没书的,我给出代码和相关语句。

以下为书中原话: 尽量在构造函数内定义一般成员,尤其是对象或数组,因为用原型定义的成员是多个 实例共享的。

经我测试(下面是测试用例),就算在原型中定义的成员,并不是共享的,而是各有一份,这个怎么说?

function Foo () {
	var innerVar = 'hello';
	this.prop1   = 'BYVoid';

	this.func1   = function() {
		innerVar = '';
	};
}

Foo.prototype.prop2 = 'Car';
Foo.prototype.func2 = function() {
	console.log(this.prop2);
};

var foo1 = new Foo();
var foo2 = new Foo();

console.log(foo1.func1 == foo2.func1); //false
console.log(foo1.func2 == foo2.func2); //true

foo1.prop2 = 'Mobile';
foo1.func2(); //Mobile
foo2.func2(); //Car
7 回复

console.log(foo1.func2 == foo2.func2); 输出 true 了这还不能证明么?

呃, 你是想说

foo1.prop2 = 'Mobile';

这句有问题么? 你可以试试

console.log(foo1); // { prop1: 'BYVoid', func1: [Function], prop2: 'Mobile' }
console.log(foo2); // { prop1: 'BYVoid', func1: [Function] } 没有 prop2!

其实 foo2 自身是没有 prop2 这个属性的, 但因为之前那一句 foo1 有了. js 解释器发现某个对象自身没这个属性时, 会往它的构造方法原型上找

console.log(foo2.constructor.prototype); // { prop2: 'Car', func2: [Function] }

如果能找到, 这个就作为属性值.

所以实际上是 this.prop2 这个表达式求值在两个对象上结果不一导致的.

说得有道理。 还有一个疑问就是为什么foo1.prop2 不直接使用Foo原型中的prop2,而会去新生成一个prop2属性呢?

因为不能通过实例重写prototype的属性

foo1.prop2 = 'Mobile';

只是屏蔽了prototype的prop2属性。你可以通过__proto__访问原型链上的prop2属性:

foo1.__proto__.prop2 == "Car"

谢谢大家,终于明白了。

正解. 一个是原型的属性值,一个是对象自身的属性(动态添加的),造成了使用this求值的区别.

//假想的new操作符 function New (f) { var n = { ‘proto’: f.prototype }; return function () { f.apply(n, arguments); return n; }; } // 顺序:先使用prototype创建对象,再使用构造函数处理创建的对象

回到顶部