使用原型[javascript]的未定义结果

时间:2015-12-08 05:01:25

标签: javascript prototype

所以我正在使用javascript学习原型,并尝试了一些代码:

function Employee(name) { this.name= name; }
var m = new Employee("Bob");
var working= { isWorking: true };
Employee.prototype = working; 
alert(m.isWorking);

不幸的是,我收到了一条未定义的消息,而不是真正的值。这个结果有理由吗?

我做了几次测试。我已经得出结论,重新分配原型对象会导致以前创建的Employee类实例无法访问新分配的原型中找到的任何属性。这准确吗?

4 个答案:

答案 0 :(得分:2)

更改原型不会影响已创建的对象。它只会影响基于该对象创建的对象。

有一个属性__proto__可以用来更改原型,但不需要它的实现。 ES6确实定义了setPrototypeOf方法来更改原型,但由于它仅在ES6中,因此支持可能会有所不同。

答案 1 :(得分:1)

简单的解决方法是正确分配它。

function Employee(name) {
  this.name = name;
}
var m = new Employee("Bob");
var working = {
  isWorking: true
};
Employee.prototype.working = working;
alert(m.working.isWorking);

对MULTIPLE员工的一个更好的解决方法是创建一个类,然后创建它的实例:在这里玩它:http://jsfiddle.net/MarkSchultheiss/p6jyqbgv/1/

"use strict";
function makeClassStrict() {
  var isInternal, instance;
  var constructor = function(args) {
    if (this instanceof constructor) {
      if (typeof this.init == "function") {
        this.init.apply(this, isInternal ? args : arguments);
      }
    } else {
      isInternal = true;
      instance = new constructor(arguments);
      isInternal = false;
      return instance;
    }
  };
  return constructor;
}
var EmployeeClass = makeClassStrict();
EmployeeClass.prototype.init = function(employeeName, isWorking) {
  var defaultName = 'notbob';
  this.name = employeeName ? employeeName : defaultName;
  this.working = !!isWorking;
};
// call this to get the name property
EmployeeClass.prototype.getName = function() {
  return this.name
};
//note no "new" needed due to the makeClassStrict that does that
var m = EmployeeClass("Bob");
alert(m.working +":"+ m.name);
m.working = true;
alert(m.working +":"+ m.name);
var notbob =  EmployeeClass("Charlie",false);
alert(notbob.working +":"+ notbob.name);
alert(notbob.getName()+ m.getName());

答案 2 :(得分:1)

首先,您在设置原型之前已经创建了Employee的实例,因此该对象不会继承新的原型值。

接下来,在设置原型后创建的任何对象都将继承新的原型对象。

最后,该对象将具有isWorking属性,而不是working属性。

所以要重做你的例子:

function Employee(name) { this.name= name; };

var m1 = new Employee("Bob");

var working= { isWorking: true };
Employee.prototype = working; 

var m2 = new Employee("Sam");

alert(m1.isWorking); // undefined
alert(m2.isWorking); // true

答案 3 :(得分:1)

您无法覆盖整个原型属性,并希望现有实例能够正常工作。 JavaScript不会那样工作。但是你可以循环遍历原型对象并取消设置已设置的任何内容,然后循环遍历新对象,并将其设置为其他对象。

function Employee(name) { this.name= name; }
var m = new Employee("Bob");
var working= { isWorking: true };
for(var j in Employee.prototype){delete Employee.prototype[j];}//unset all properties, the same as setting to {}
for(j in working){Employee.prototype[j]=working[j];}//set the properties
alert(m.isWorking);