Nodejs中javascript的这种坑怎么处理?

Nodejs中javascript的这种坑怎么处理?

var F = function (name) {
this.name = name;
};

F.prototype.show = { str: ‘我希望我不会被改变呢,因为我可是构造函数的原型的东西哦’ };

var a = new F(‘我是A’); a.show.str = ‘我是A,我改了自己的prototype’; console.log(a.show); // 你猜猜结果是什么?

var b = new F(‘我是B’); console.log(b.show); // 你猜猜结果是什么?


12 回复

在Node.js中使用JavaScript时,经常会遇到一些常见的陷阱。其中一个陷阱就是错误地将对象赋值给构造函数的原型,这会导致所有实例共享同一个对象。下面我们就来分析并解决这个问题。

问题描述

在提供的代码中,show属性被定义为一个对象字面量,并且被直接赋值给了F.prototype。这意味着所有通过new F()创建的实例都会共享同一个show对象。因此,当某个实例修改了show对象的属性时,所有其他实例中的show对象也会受到影响。

示例代码

var F = function (name) {
    this.name = name;
};

// 错误的做法:将对象字面量直接赋值给原型
F.prototype.show = {
    str: '我希望我不会被改变呢,因为我可是构造函数的原型的东西哦'
};

var a = new F('我是A');
a.show.str = '我是A,我改了自己的prototype';
console.log(a.show);    // { str: '我是A,我改了自己的prototype' }

var b = new F('我是B');
console.log(b.show);    // { str: '我是A,我改了自己的prototype' }

解决方案

为了避免这种情况,我们应该避免将对象字面量直接赋值给原型。相反,我们可以在构造函数内部初始化对象,这样每个实例都会有自己的独立副本。

修改后的代码

var F = function (name) {
    this.name = name;
    // 在构造函数内部初始化对象
    this.show = {
        str: '我希望我不会被改变呢,因为我可是构造函数的原型的东西哦'
    };
};

var a = new F('我是A');
a.show.str = '我是A,我改了自己的show';
console.log(a.show);    // { str: '我是A,我改了自己的show' }

var b = new F('我是B');
console.log(b.show);    // { str: '我希望我不会被改变呢,因为我可是构造函数的原型的东西哦' }

解释

  1. 问题原因:在原始代码中,show对象被直接赋值给了F.prototype,导致所有实例共享同一个对象。
  2. 解决方案:将show对象的初始化移到构造函数内部,确保每个实例都有自己的独立副本。

通过这种方式,我们可以避免由于共享对象而导致的问题,确保每个实例的行为符合预期。


原型prototype是多个对象共享的。

var F = function (name) { this.name = name; this.show={str:‘我希望我不会被改变呢,因为我可是构造函数的原型的东西哦’}; }; var a = new F(‘我是A’); a.show.str = ‘我是A,我改了自己的prototype’; console.log(a.show); // 你猜猜结果是什么?

var b = new F(‘我是B’); console.log(b.show);

用this

var F = function (name) {
    this.name = name;
};

F.prototype.show = { str: ‘我希望我不会被改变呢,因为我可是构造函数的原型的东西哦’ }; F.prototype.setShow=function(some){ this.show=some;

} var a = new F(‘我是A’);

console.log(a.show); // 你猜猜结果是什么?

var b = new F(‘我是B’); b.setShow({ str: ‘我是oo,我only改了自己的prototype’ });

console.log(b.show); // 你猜猜结果是什么?

console.log(a.show); // 你猜猜结果是什么? var c = new F(‘我是C’);

console.log(c.show);

good,以对象方式赋值对象属性

这个都算坑啊。。。 js 名声有这么差

这不是坑,这是js动态语言的特性 可以动态添加属性 楼主可能是写c或者java的

这为什么是坑。。

你了解了原型就不觉得它是坑了- -。。

我觉得你还没有think in javascript,javascript和C++都是受到抱怨最多的语言,C++是因为比较难,javascript是因为思维不一样。

楼主对于原型没有理解导致的这个问题,我觉得要填补这个坑可能需要楼主深入理解一下原型…的用处

是的是的,我发现了。:D

在这个例子中,问题出在 F.prototype.show 被定义为一个对象字面量(对象直接量),而不是一个函数。由于 show 是一个对象字面量,它会被所有通过 new F() 创建的新实例共享。因此,当其中一个实例修改了 show 对象的属性时,其他所有实例中的 show 对象也会受到影响。

为了修复这个问题,我们需要将 show 改写为一个函数,该函数返回一个对象。这样每个实例都会有自己独立的 show 对象,而不会相互影响。

以下是修复后的代码:

var F = function (name) {
    this.name = name;
    this.show = { // 每个实例都有自己的 show 对象
        str: '我希望我不会被改变呢,因为我可是构造函数的原型的东西哦'
    };
};

var a = new F('我是A');
a.show.str = '我是A,我改了自己的show对象';
console.log(a.show);    // 输出:{ str: '我是A,我改了自己的show对象' }

var b = new F('我是B');
console.log(b.show);    // 输出:{ str: '我希望我不会被改变呢,因为我可是构造函数的原型的东西哦' }

在这个修正后的版本中,show 属性在构造函数内部被初始化为一个新的对象。因此,ab 实例各自拥有独立的 show 对象,互不影响。

回到顶部