所以我正在使用javascript学习原型,并尝试了一些代码:
function Employee(name) { this.name= name; }
var m = new Employee("Bob");
var working= { isWorking: true };
Employee.prototype = working;
alert(m.isWorking);
不幸的是,我收到了一条未定义的消息,而不是真正的值。这个结果有理由吗?
我做了几次测试。我已经得出结论,重新分配原型对象会导致以前创建的Employee类实例无法访问新分配的原型中找到的任何属性。这准确吗?
答案 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);