帮助, 我有这个班级
var jMath = {
pi2: Math.PI,
foo: function() {
return this.pi2;
}
}
我想让pi2保持不变,我希望jMath继承Math对象。我该怎么做?
答案 0 :(得分:3)
哦,很有趣,抓一切,这是正确的版本:
function JMath() {
this.foo = function() {
return this.PI;
}
}
JMath.prototype = Math;
var jMath = new JMath();
alert(jMath.foo());
(这与其他答案相符)
(我最初尝试使用“JMath.prototype = new Math()”设置原型,这是我在其他地方看到的,但上面的工作)
这是将其作为单身人士的一种方式
// Execute an inline anon function to keep
// symbols out of global scope
var jMath = (function()
{
// Define the JMath "class"
function JMath() {
this.foo = function() {
return this.PI;
}
}
JMath.prototype = Math;
// return singleton
return new JMath();
})();
// test it
alert( jMath.PI );
// prove that JMath no longer exists
alert( JMath );
答案 1 :(得分:3)
考虑使用prototype
:
function JMath() {};
JMath.prototype = {
pi2: Math.PI,
foo: function() {
return this.pi2;
}
}
var j = new JMath();
j.pi2=44; j.foo(); // returns 44
delete j.pi2; j.foo(); // now returns Math.PI
这和@ altCognito的答案之间的区别在于,这里对象的字段是共享的,并且都指向相同的东西。如果不使用原型,则在构造函数中创建新的和未链接的实例。您可以基于每个实例覆盖原型的值,如果您覆盖它,然后决定不喜欢覆盖值并想要恢复原始值,请使用delete
删除仅仅“阴影”的覆盖“原型的价值。
编辑:如果你想继承Math对象本身的所有方法和字段,但是在不影响Math对象的情况下覆盖一些东西,可以这样做(根据自己的喜好更改名称“Constructor1”):
function Constructor1() {};
Constructor1.prototype = Math;
function JMath() {};
JMath.prototype = new Constructor1();
JMath.prototype.pi2 = JMath.prototype.PI;
JMath.prototype.foo = function() { return this.pi2; }
var j = new JMath();
j.cos(j.foo()); // returns -1
编辑3:对Constructor1函数的解释:这将创建以下原型链:
j -> JMath.prototype -> Math
j是JMath的一个实例。 JMath的原型是Constructor1的一个实例。 Constructor1的原型是Math。 JMath.prototype是被覆盖的东西“活着”的地方。如果你只实现了几个JMath实例,你可以让被覆盖的东西是由构造函数JMath设置的实例变量,并直接指向Math,就像@ altCognito的答案那样。 (j是JMath的一个实例,JMath的原型是Math)
在构造函数中增加一个对象有两个缺点。 (实际上不一定是缺点)一个是在构造函数中声明实例字段/方法为每个实例创建单独的值。如果您创建了大量JMath实例,则每个实例的JMath.foo函数将是一个占用额外内存的单独对象。如果JMath.foo函数来自其原型,则所有实例共享一个对象。
此外,您可以在事实之后更改JMath.prototype.foo,并且实例将相应地更新。如果在构造函数中将foo函数作为每个实例的方法创建,那么一旦创建了JMath对象,它们就是独立的,更改foo函数的唯一方法就是更改每个函数。
编辑2:就只读属性而言,你无法在Javascript本身内实现它们,你需要在表面下捣乱。但是,您可以声明所谓的“getters”,它有效地充当常量:
JMath.prototype.__defineGetter__("pi2", function() { return Math.PI; });
JMath.prototype.__defineSetter__("pi2", function(){}); // NOP
var j = new JMath();
j.pi2 = 77; // gee, that's nice
// (if the setter is not defined, you'll get an exception)
j.pi2; // evaluates as Math.PI by calling the getter function
警告:定义getter / setters apparently is not something that IE doesn't implement nicely的语法。
答案 2 :(得分:1)
用户定义的对象属性不能是常量。 Math(以及一些其他对象)是一种特殊的内置函数 - 它具有只读属性和函数。但它不是构造函数 - 它只是一个静态对象(Math.constructor === Object)。
因为JavaScript具有原型继承,而不是经典,所以不能继承自Math。 (Read more here)
然而,您可以做的是定义原型。当在本地找不到属性时,JS解析器在当前对象的原型上查找该属性。 altCognito目前的解决方案非常清楚。
我很好奇你正在努力实现的目标。也许这样的事情就是你想要的?
var jMath = function()
{
const pi2 = Math.PI;
this.getPi2 = function()
{
return pi2;
}
}
var j = new jMath;
alert( j.getPi2() );