检索原型属性时出现TypeError
TypeError while retriving prototype properties
我有以下代码:
function inheritPrototype (sup, sub) {
var proto = Object.create(sup.prototype);
Object.defineProperty(proto, "constructor", {value : sub});
sub.prototype = proto;
}
function Person (name, age) {
this.name = name;
this.age = age;
if (!Person.prototype.getName) {
Person.prototype.getName = function () { return this.name; }
Person.prototype.getAge = function () { return this.age; }
}
}
function Employee (name, age, skills) {
Person.call(this, name, age);
this.skills = skills;
if (!Employee.prototype.getSkills) {
inheritPrototype(Person, Employee);
Employee.prototype.getSkills = function () { return this.skills; }
}
}
var person = new Person ("Dave", 21);
var employee = new Employee ("David", 22, ["C", "C++", "Java", "Python", "PHP"]);
console.log(employee.getSkills());
inheritPrototype
的定义只是为了防止父类(Person
)构造函数的双重调用。为了保持清晰,我在构造函数中分配原型属性,并防止每次创建新实例时发生这种情况,我正在检查原型属性是否存在。如果有,我们就不想重新分配属性,否则我们就重新分配。问题是,我得到一个TypeError说' employee.getName is not a function
'。这只发生在我试图使用雇员实例访问雇员的原型属性时。person构造函数有相同的方式来分配Prototype属性,但它工作得很好。
console.log(person.getName()); // "Dave"
console.log(employee.getSkills()); // or getName or anything, TypeError
我猜我在那里做了一些愚蠢的事情,但我没有发现它。那么,怎么了?
在外面调用inheritPrototype
怎么样?
这个对我有效:
function inheritPrototype (sup, sub) {
var proto = Object.create(sup.prototype);
Object.defineProperty(proto, "constructor", {value : sub});
sub.prototype = proto;
}
function Person (name, age) {
this.name = name;
this.age = age;
if (!Person.prototype.getName) {
Person.prototype.getName = function () { return this.name; }
Person.prototype.getAge = function () { return this.age; }
}
}
function Employee (name, age, skills) {
Person.call(this, name, age);
this.skills = skills;
if (!Employee.prototype.getSkills) {
Employee.prototype.getSkills = function () { return this.skills; }
}
}
inheritPrototype(Person, Employee); // <= FIX
var person = new Person ("Dave", 21);
var employee = new Employee ("David", 22, ["C", "C++", "Java", "Python", "PHP"]);
console.log(person.getName()); // returns "Dave"
console.log(employee.getSkills()); // returns ["C", "C++", "Java", "Python", "PHP"]
console.log(employee.getName()); // returns David
这个问题主要是由于当inheritPrototype方法被调用时原型引用不匹配。
在inheritPrototype方法中,你有object .create(sup.prototype),它试图从原型中创建一个新实例,该实例与创建Employee对象时使用的对象引用不同。
这可以在为Employee prototype打印的控制台日志中看到,其中为prototype创建了一个新引用,其中不调用inheritPrototype方法的EmployeeOne具有相同的引用。
所以,您看到异常的原因是因为引用不匹配。即使你在引用原型,在调用inheritMethod之前和之后的引用也是不同的。
我没有文档来支持我的理论,但是,我相信在inheritPrototype方法调用的情况下,原型引用已经改变,这就是为什么新添加的方法getSkills在该对象的原型链查找中不可见的情况。
然而,一旦原型值在第一个员工调用期间更新,后续的员工对象就能够看到新的getSkills,因为原型引用现在指向早期调用的原型引用。
function inheritPrototype(sup, sub) {
var proto = Object.create(sup.prototype);
Object.defineProperty(proto, "constructor", {
value: sub
});
sub.prototype = proto;
}
function Person(name, age) {
this.name = name;
this.age = age;
if (!Person.prototype.getName) {
Person.prototype.getName = function () {
return this.name;
}
Person.prototype.getAge = function () {
return this.age;
}
}
}
function Employee(name, age, skills) {
Person.call(this, name, age);
this.skills = skills;
var p = Employee.prototype;
if (!Employee.prototype.getSkills) {
inheritPrototype(Person, Employee);
Employee.prototype.getSkills = function () {
return this.skills;
}
}
console.log("Employee with inheritPrototype invocation : " + (p === Employee.prototype));
}
function EmployeeOne(name, age, skills) {
Person.call(this, name, age);
this.skills = skills;
var p = EmployeeOne.prototype;
if (!EmployeeOne.prototype.getSkills) {
EmployeeOne.prototype.getSkills = function () {
return this.skills;
}
}
console.log("EmployeeOne without inheritPrototype invocation : " + (p === EmployeeOne.prototype));
}
var person = new Person("Dave", 21);
var employee = new Employee("David", 22, [
"C",
"C++",
"Java",
"Python",
"PHP"
]);
var employeeOne = new EmployeeOne("DavidOne", 22, [
"C",
"C++",
"Java",
"Python",
"PHP"
]);
var employeeTwo = new Employee("David", 22, [
"C",
"C++",
"Java",
"Python",
"PHP"
]);
console.log(employeeTwo.getSkills());
我试图在继承原型方法后查找Employee构造函数的引用,我上面对原型的新引用的解释证明是正确的。
function inheritPrototype(sup, sub) {
var proto = Object.create(sup.prototype);
Object.defineProperty(proto, "constructor", {
value: sub
});
sub.prototype = proto;
}
function Person(name, age) {
this.name = name;
this.age = age;
if (!Person.prototype.getName) {
Person.prototype.getName = function() {
return this.name;
}
Person.prototype.getAge = function() {
return this.age;
}
}
}
function Employee(name, age, skills) {
Person.call(this, name, age);
this.skills = skills;
var p = Employee.prototype;
if (!Employee.prototype.getSkills) {
inheritPrototype(Person, Employee);
Employee.prototype.getSkills = function() {
return this.skills;
}
} else {
inheritPrototype(Person, Employee);
}
if (employeeTwoPrototype !== undefined) {
console.log("Employee with 2nd inheritPrototype invocation : " + (p === employeeTwoPrototype));
console.log("Employee with 2nd inheritPrototype invocation : " + (p === Employee.prototype));
} else {
console.log("Employee with inheritPrototype invocation : " + (p === Employee.prototype));
}
}
function EmployeeOne(name, age, skills) {
Person.call(this, name, age);
this.skills = skills;
var p = EmployeeOne.prototype;
if (!EmployeeOne.prototype.getSkills) {
EmployeeOne.prototype.getSkills = function() {
return this.skills;
}
}
console.log("EmployeeOne without inheritPrototype invocation : " + (p === EmployeeOne.prototype));
}
var person = new Person("Dave", 21);
var employee = new Employee("David", 22, [
"C",
"C++",
"Java",
"Python",
"PHP"
]);
var employeeOne = new EmployeeOne("DavidOne", 22, [
"C",
"C++",
"Java",
"Python",
"PHP"
]);
var employeeTwo = new Employee("David", 22, [
"C",
"C++",
"Java",
"Python",
"PHP"
]);
var employeeTwoPrototype = Employee.prototype;
var employeeThree = new Employee("David", 22, [
"C",
"C++",
"Java",
"Python",
"PHP"
]);
console.log(employeeTwo.getSkills());
- 使用“;这个“;JavaScript原型方法中的关键字
- TypeError:无法读取属性'推'未定义的JavaScript
- 未捕获的TypeError无法读取未定义的属性socialsharing
- 扩展SVGTextElement时出现Typescript Uncaught TypeError
- TypeError:在不兼容的接收器nodejs上调用了方法Uint8Array.length
- 引用类变量中的原型方法
- 如何从对象的原型方法访问JavaScript对象属性
- 为什么要包装每一个原型“;类“;JS中具有匿名函数的对象
- TypeError:_this.store.getState在使用来自Redux的连接时不是函数
- Node.js中的JavaScript原型对象效率
- gulp Iconify任务抛出错误TypeError:Path必须是字符串.收到false
- 重载JS'firefox中的对象原型
- Uncaught TypeError:undefined不是函数-ember js
- 得到"TypeError:无法读取属性'filename'未定义的“;调用“npm start
- “util.inherits”和在NodeJS中扩展原型之间的区别
- Uncaught TypeError:对象原型在Symfony 2中只能是Object或ExtJS为null
- Uncaught TypeError:向Date原型添加函数时,这不是Date对象
- Javascript-在原型中添加函数会导致TypeError
- 检索原型属性时出现TypeError
- & # 39;原型# 39;抛出TypeError: info未定义