【问题标题】:Calling a method of an object's prototype调用对象原型的方法
【发布时间】:2017-02-17 20:36:11
【问题描述】:
我是 JS 新手,遇到以下问题:
为什么这不起作用/这段代码在做什么?
var Test = {};
Test.prop = "test property";
Test.Class1 = function () {
}
Test.Class1.prototype = {
m1: function() {
console.log(this.prop);
}
}
Test.Class1.m1();
我对这段代码的理解是:
- 创建一个名为 Test 的新对象
- 将属性 prop 添加到 Test
- 在 Test 中创建一个名为 Class1 的新对象
- 将方法 m1 添加到 Class1
- 在Test中调用Class1的m1方法
【问题讨论】:
标签:
javascript
oop
prototype
【解决方案1】:
在 JavaScript 中,即使是函数的原型属性也是一个对象。在创建原型是您定义的对象之前,Test1.Class1.prototype 只是一个常规对象。基本上它的工作方式与以下代码 sn-p 相同:
var Test1 = { prototype { m1: function() {} } };
// You're trying to call an undefined function!
Test.m1();
// This is fine
Test1.prototype.m1();
另一方面,当您使用new 运算符时,您正在创建一个新对象,其原型是构造函数的集合。 魔法从这里开始:
var Test1 = function() {};
Test1.prototype = {
doStuff: function() {}
};
var object1 = new Test1();
// This works!
object1.doStuff();
当您访问一个属性时,JavaScript 的运行时会检查该对象以查找是否有一个名为 doStuff 的函数,否则它会在对象的原型上查找它,否则它会在原型的原型上查找,等等。 .
实际上new 运算符是syntactic sugar。 ECMA-Script 5 引入了Object.create,让一切变得更加清晰:
var Test1 = {
doStuff: function() {
}
};
// The first parameter of Object.create is
// the object that's going to be the prototype of
// Test1 object!
var object1 = Object.create(Test1);
// This works too!
object1.doStuff();
也许您应该查看其他问答:How does JavaScript .prototype work?
【解决方案2】:
您需要先创建原型的实例,然后才能使用其方法:
var instance = new Test.Class1();
console.log(instance.m1());
即便如此,Test.prop 不是实例的一部分,m1 也无法访问
编辑:这是一个工作示例:
var test = function() {
this.prop = "A property";
}
test.prototype.m1 = function() {
console.log(this.prop);
}
var instance = new test();
console.log(instance.m1());
【解决方案3】:
prototype 链接仅适用于使用 new 运算符创建的实例。
否则你将不得不显式调用原型来访问该方法。
let testClass = new Test.Class1();
testClass.m1();
另外,因为您正在尝试访问 prop 属性。
Test.Class1.prototype = {
m1: function() {
console.log(this.prop);
}
}
呼叫站点是Test.Class1,prop 应该是Test.Class1 的一部分,而不是Test 的一部分
【解决方案4】:
我更改了事物的名称,但这应该可以。
var Person = function(){
this.message = "Hello, world!";
};
Person.prototype = Object.create(Object.prototype);
Person.prototype.constructor = Person;
Person.prototype.greet = function(){
console.log(this.message);
alert(this.message);
};
var tom = new Person();
tom.greet();