我正在创建两个对象(继承),它们都继承自 Base。 第二个对象的属性分配覆盖第一个对象中的值。
有什么想法吗?如何进行适当的继承,以便基类将包含其继承后代的公共(public)成员,但后代可以在不相互干扰的情况下分配自己的值。
var testParams1 = { title: "john" };
var testParams2 = { title: "mike" };
Function.prototype.inheritsFrom = function (baseClass)
{
this.prototype = new baseClass;
this.prototype.constructor = this;
this.prototype.base = baseClass.prototype;
return this;
};
function Base() {
this.viewModel = {};
this.viewModel.title = (function ()
{
var savedVal = "";
return function (newVal)
{
if (typeof (newVal) === "undefined")
{
return savedVal;
}
savedVal = newVal;
};
})();
}
function Inherits(params) {
this.viewModel.title(params.title);
}
Inherits.inheritsFrom(Base);
///// preparing code:
var testObj1 = new Inherits(testParams1);
var testObj2 = new Inherits(testParams2);
///// testing code:
equals(testObj1.viewModel.title(), testParams1.title, "first instance ok"); // returns "john"
equals(testObj2.viewModel.title(), testParams2.title, "second instance ok"); // also returns "john"
最佳答案
Base 类构造函数被调用一次且仅调用一次。this 对象,因为这些方法是在构造函数中创建的(仅调用一次)。Function.prototype)。请特别注意 inherits 函数和 ParentClass.call(this, title); 行。
要查找的构造函数是 ParentClass 和 ChildClass
/**
* Allows a child constructor to safely inherit the parent constructors prototype chain.
* @type {Function}
* @param {!Function} childConstructor
* @param {!Function} parentConstructor
*/
function inherits(childConstructor, parentConstructor){
var TempConstructor = function(){};
TempConstructor.prototype = parentConstructor.prototype; // Inherit parent prototype chain
childConstructor.prototype = new TempConstructor(); // Create buffer object to prevent assignments directly to parent prototype reference.
childConstructor.prototype.constructor = childConstructor; // Reset the constructor property back the the child constructor
};
//////////////////////////////////////
/** @constructor */
function ParentClass(title) {
this.setTitle(title);
var randId_ = Math.random();
/** @return {number} */
this.getPrivlegedRandId = function()
{return randId_;};
};
/** @return {string} */
ParentClass.prototype.getTitle = function()
{return this.title_;};
/** @param {string} value */
ParentClass.prototype.setTitle = function(value)
{this.title_ = value;};
//////////////////////////////////////
/**
* @constructor
* @param {string} title
* @param {string} name
*/
ChildClass = function (name, title) {
ParentClass.call(this, title); // Call the parent class constructor with the required arguments
this.setName(name);
}
inherits(ChildClass, ParentClass); // Inherit the parent class prototype chain.
/** @return {string} */
ChildClass.prototype.getName = function()
{return this.name_;};
/** @param {string} value */
ChildClass.prototype.setName = function(value)
{this.name_ = value;};
对于那些好奇为什么它有效而不是简单地记住 inherits 函数的人。
当在实例级别找不到属性时,JavaScript 将尝试通过搜索实例构造函数原型(prototype)链来解析丢失的属性。如果在第一个原型(prototype)对象中没有找到该属性,它将搜索父原型(prototype)对象,依此类推,一直搜索到 Object.prototype。如果在 Object.prototype 中找不到它,则会抛出错误。
// Bad
var ChildConstructor = function(arg1, arg2, arg3){
var that = new ParentConstructor(this, arg1, arg2, arg3);
that.getArg1 = function(){return arg1};
return that;
}
任何使用 new ChildConstructor 创建的变量都将返回 ParentConstructor 的实例。
ChildConstructor.prototype 将不会被使用。
// Good
var ChildConstructor = function(arg1, arg2, arg3){
ParentConstructor.call(this, arg1, arg2, arg3);
}
现在构造函数和父构造函数被正确调用。但是,只有在构造函数中定义的方法才会存在。不会使用父原型(prototype)上的属性,因为它们尚未链接到子构造函数原型(prototype)。
// Bad
ChildConstructor.prototype = new ParentConstructor();
根据是否使用 ParentConstructor.call(this),父构造函数将只被调用一次或多次。
// Bad
ChildConstructor.prototype = ParentConstructor.prototype;
尽管这在技术上是可行的,但对 ChildConstructor.prototype 的任何赋值也将被赋值给 ParentConstructor.prototype,因为对象是通过引用传递的,而不是通过复制传递的。
// Almost there
var TempConstructor = function(){};
TempConstructor.prototype = ParentConstructor.prototype;
ChildConstructor.prototype = new TempConstructor();
这允许您将属性分配给 ChildConstructor.prototype,因为它是一个临时匿名函数的实例。
在 TempConstructor 的实例上找不到的属性随后将检查其属性的原型(prototype)链,因此您已成功继承父原型(prototype)。唯一的问题是 ChildConstructor.prototype.constructor 现在指向 TempConstructor。
// Good
var TempConstructor = function(){};
TempConstructor.prototype = ParentConstructor.prototype;
ChildConstructor.prototype = new TempConstructor();
ChildConstructor.prototype.constructor = ChildConstructor;
var ParentConstructor = function(){
};
var ChildConstructor = function(){
ParentConstructor.call(this)
};
var TempConstructor = function(){};
TempConstructor.prototype = ParentConstructor.prototype;
ChildConstructor.prototype = new TempConstructor();
ChildConstructor.prototype.constructor = ChildConstructor;
你已经成功继承了父类!让我们看看是否可以做得更好。
function inherits(childConstructor, parentConstructor){
var TempConstructor = function(){};
TempConstructor.prototype = parentConstructor.prototype; // Inherit parent prototype chain
childConstructor.prototype = new TempConstructor(); // Create buffer object to prevent assignments directly to parent prototype reference.
childConstructor.prototype.constructor = childConstructor; // Reset the constructor property back the the child constructor (currently set to TempConstructor )
};
var ParentConstructor = function(){
};
var ChildConstructor = function(){
ParentConstructor.call(this)
};
inherits(ChildConstructor, ParentConstructor);
关于Javascript 原型(prototype)继承——后代相互覆盖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14564155/
我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah
我在pry中定义了一个函数:to_s,但我无法调用它。这个方法去哪里了,怎么调用?pry(main)>defto_spry(main)*'hello'pry(main)*endpry(main)>to_s=>"main"我的ruby版本是2.1.2看了一些答案和搜索后,我认为我得到了正确的答案:这个方法用在什么地方?在irb或pry中定义方法时,会转到Object.instance_methods[1]pry(main)>defto_s[1]pry(main)*'hello'[1]pry(main)*end=>:to_s[2]pry(main)>defhello[2]pry(main)
在Ruby类中,我重写了三个方法,并且在每个方法中,我基本上做同样的事情:classExampleClassdefconfirmation_required?is_allowed&&superenddefpostpone_email_change?is_allowed&&superenddefreconfirmation_required?is_allowed&&superendend有更简洁的语法吗?如何缩短代码? 最佳答案 如何使用别名?classExampleClassdefconfirmation_required?is_a
我们的git存储库中目前有一个Gemfile。但是,有一个gem我只在我的环境中本地使用(我的团队不使用它)。为了使用它,我必须将它添加到我们的Gemfile中,但每次我checkout到我们的master/dev主分支时,由于与跟踪的gemfile冲突,我必须删除它。我想要的是类似Gemfile.local的东西,它将继承从Gemfile导入的gems,但也允许在那里导入新的gems以供使用只有我的机器。此文件将在.gitignore中被忽略。这可能吗? 最佳答案 设置BUNDLE_GEMFILE环境变量:BUNDLE_GEMFI
在我的系统中,我已经定义了STI。Dog继承自Animal,在animals表中有一个type列,其值为"Dog"。现在我想让SpecialDog继承自dog,只是为了在某些特殊情况下稍微修改一下行为。数据还是一样。我需要通过SpecialDog运行的所有查询,以返回数据库中类型为Dog的值。我的问题是因为我有一个type列,rails将WHERE"animals"."type"IN('SpecialDog')附加到我的查询中,所以我不能获取原始的Dog条目。所以我想要的是以某种方式覆盖rails在通过SpecialDog访问数据库时使用的值,使其表现得像Dog。有没有办法覆盖用于类型
假设您编写了一个类Sup,我决定将其扩展为SubSup。我不仅需要了解你发布的接口(interface),还需要了解你的私有(private)字段。见证这次失败:classSupdefinitialize@privateField="fromsup"enddefgetXreturn@privateFieldendendclassSub问题是,解决这个问题的正确方法是什么?看起来子类应该能够使用它想要的任何字段而不会弄乱父类(superclass)。编辑:equivalentexampleinJava返回"fromSup",这也是它应该产生的答案。 最佳答案
我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的
如thisquestion,当在其自己的赋值中使用未定义的局部变量时,它的计算结果为nil。x=x#=>nil但是当局部变量的名称与现有的方法名称冲突时,就比较棘手了。为什么下面的最后一个示例返回nil?{}.instance_eval{a=keys}#=>[]{}.instance_eval{keys=self.keys}#=>[]{}.instance_eval{keys=keys}#=>nil 最佳答案 在Ruby中,因为可以在没有显式接收器和括号的情况下调用方法,所以在局部变量引用和无接收器无参数方法调用之间存在语法歧义:f
有人知道如何将capybarapoltergeist的用户代理覆盖到移动用户代理以进行测试吗?我发现了一些有关为seleniumwebdriver配置它的信息:http://blog.plataformatec.com.br/2011/03/configuring-user-agents-with-capybara-selenium-webdriver/这在capybara闹鬼中怎么可能? 最佳答案 请参阅poltergeistgithub页面上的链接:https://github.com/teampoltergeist/polte
如果我一直输入geminstallrails使用不同版本的Rails会怎样?例如,我可以输入:geminstallrails--verson3.2.10或geminstallrails这给了我版本3.2.12。问题每次安装都会覆盖之前的吗?它会删除所有旧文件并添加我正在安装的新版本吗?或者如果我运行它两次,它会保留一些文件吗?我正在使用Ubuntu。 最佳答案 它将安装两个独立的gem。实际的可执行文件rails将调用最新版本。你可以覆盖它__例如,rails_3.2.10_将执行Rails3.2.10。bundler顺便说一下,如