[英]Why can't I refer to the inherited method from JavaScript prototype within method
当我使用 JavaScript 原型来继承一个对象并想通过以下方式使用它的方法时:
var Father = { name:'Father', act:function(){ console.log('the name is '+this.name); } } var Son = function(){ act(); } Son.__proto__ = Father; Son();
这不起作用,当 Js 引擎运行Son()
,它应该通过它的原型链搜索act()
。
但为什么它只能以下列方式工作:
var Father = { name:'Father', act:function(){ console.log('the name is '+this.name); } } var Son = { name:'Son' } Son.__proto__=Father; Son.act();
总而言之,当您尝试使用它时,函数act()
不存在。
仅仅因为您希望Son
从Father
那里继承并不意味着 JS 知道您想要这样做。 当您尝试使用act()
JS 不知道您想要将Son
与Father
……就 JS 而言,它们是完全不同的函数/对象/等......并且对于所有 JS 知道的人来说都具有绝对零关系.
同样,您需要在适当的范围内使用实际的act
函数 - JS 不知道您的意图是什么 - 您如何期望 JS 知道从哪个对象中提取act()
......如果有一个Mother
对象一种act
方法?...
第一个片段:要解决这个问题,只需构建一个act()
函数...
var Father = { name:'Father', act:function(){ console.log('the name is '+this.name); } } function act() { return this.name; } var Son = function(){ act(); } Son.__proto__ = Father; Son.act();
第二个片段:这与尝试没有什么不同:
var Father = { name:'Father', act:function(){ console.log('the name is '+this.name); } } var Son = function(){ // using 'act();' here is no different than trying: somethingThatDoesntExist(); } Son.__proto__ = Father; try { Son(); } catch { console.log("Oh no error\\r\\n\\r\\n"); } // If you don't assign anything.. // It will work... because of inheritence.. Son = {} // MAKING SON AN OBJECT NOT A FUNCTION Son.__proto__ = Father; // If you don't change the name, it will log: 'the name is Father' Son.name = "Son"; console.log("Son as an object {} ... we had to do `Son.name = 'Son'` here"); Son.act(); console.log(""); // But if you change Son to be a function, then inherit, you dont have to // change the name... 2 completely different things.... Son = function(){} Son.__proto__ = Father; console.log("Son as an function(){} ... we DID NOT have to do `Son.name = 'Son'` here since Son.name will be the name of the function, which is Son"); Son.act();
第三个片段:或者如果你这样做了:
var Father = { name: 'Father', act: function() { console.log('the name is ' + this.name); } } var Son = function() { function act() { return this.name; } } Son.__proto__ = Father; Son.act();
第四个片段或者你可以这样做:
var Father = { name:'Father', act:function(){ console.log('the name is '+this.name); } } var Son = { name:'Son' } Son.__proto__ = Father; Son.act();
第五个片段或..
var Father = { name:'Father', act:function(){ console.log('the name is '+this.name); } } var Son = { anythingYouWantHere: function() { console.log("anythingYouWantHere " + this.name); } } try { Son.act() // YOU WILL GET AN ERROR HERE } catch { console.log("YOU WILL GET AN ERROR HERE"); } Son.__proto__ = Father; Son.act(); // the name is Father Son.anythingYouWantHere(); // anythingYouWantHere Father Son.name = "Son"; Son.act(); // the name is Son Son.anythingYouWantHere(); // anythingYouWantHere Son Son.act = function() { console.log("I have now changed act! the name is " + this.name); } Son.act(); // I have now changed act! the name is Son
你需要做两件事:
1) 编写Son
的prototype
对象,而不是__proto
。 有关差异的讨论,请参阅此问题。 (TL;DR: prototype
是设置为对象/函数继承源的对象__proto__
是用于查找和解析对方法/属性的引用的结果原型链。)
2) 用new
关键字实例化Son
。
var Father = {
name:'Father',
act:function(){
return 'hello';
}
}
var Son = function(){}
Son.prototype = Father; //<-- prototype, not __proto__
let foo = new Son(); //<-- instantiate with 'new'
foo.act(); //"hello";
使用您当前的代码:
var Son = function(){
act();
}
act()
需要在Son
范围内本地定义的函数,而不是在其原型树上定义的函数。
act 不是对象的任何属性。 它只是一个指向函数的变量。
当您尝试访问对象的属性时,只有 Javascript 首先检查该属性是否存在于该对象中,如果不存在,则仅在其原型中搜索,直到原型为空。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.