在JavaScript / ActionScript中重新定义Math.constructor是否有任何实际用途?

时间:2012-04-26 18:32:51

标签: javascript actionscript constructor ecmascript-5 jscript

Math对象没有prototype属性,但有一个构造函数属性。有没有重新定义构造函数有用的情况?

8 个答案:

答案 0 :(得分:6)

Math对象(确切地说:ECMAScript全局对象的Math属性的初始值引用的对象)有{{1} } property,参见ECMAScript Language Specification, 5.1 Edition,第15.8节和第34节;数学对象"。因此,

constructor

返回Math.hasOwnProperty("constructor") (符合ECMAScript Ed.3及更高版本的实现)。

false对象通过原型链从原型链继承一个Math属性,这是标准的内置对象原型 对象(15.2.4)" (同上),与constructor属性最初引用的相同。后一个对象提供了几个有用的属性,例如Object.prototype(见上文)。因此,有意义的是Object.prototype.hasOwnProperty对象的原型链不是空的。

Math对象也继承Math仅仅是ECMAScript实现中无条件继承的副作用(除了第4版提案的实现,也许还有将来的版本)属性没有合适的可见性修饰符来防止这种情况(如几种基于类的语言中的Object.prototype.constructor)。当然,继承自同一原型的private实例的构造函数是全局对象的Object属性的初始值所引用的对象。所以Object必须反映这一点。因此,评估结果

Object.prototype.constructor

Math.constructor === Object

答案 1 :(得分:5)

所有对象都有constructor属性,表示创建对象的构造函数。

即使({}).constructor返回Object()

答案 2 :(得分:3)

实际上,Math没有拥有“构造函数”属性。它继承了Object.prototype中的“constructor”,就像它继承了“toString”,“hasOwnProperty”以及Object.prototype的所有其他属性一样。

对于数学,“构造”可能没什么用处。它就是JavaScript继承如何工作的结果。

答案 3 :(得分:2)

MDN说:

  

与其他全局对象不同,Math不是构造函数。 Math的所有属性和方法都是静态

在其他语言中,当一个类是静态的时,您可以直接使用其属性和方法,而无需创建该类的实例(对象)。如果使用Math构造函数,则不存在支持该对象的本机类型,与基本类型不同:Number,String,Boolean。它们可以用包装器转换为对象。

此外,扩展根对象是一种不好的做法。如果将来在环境中实现了新功能,并且代码没有对此进行故障安全检查,它将覆盖原生功能。

我个人认为你不是构造函数,也不是原型 - 你可以定义自己的数学函数。 Math对象仅用于提供标准函数,并为程序员提供不定义PiE的杠杆作用。用户定义的数学函数可能比内置函数慢几倍。

答案 4 :(得分:2)

来自Math

Object对象“继承”(意为Math.__proto__ === Object.prototype

Math对象对于任何JavaScript程序员来说都不是“特殊”,而是简单Object附加了方法,其实现和构造是自动和隐藏的。

Object.prototype定义了.constructor字段(实际上任何函数都将自己分配给自己的原型构造函数,请参阅 ex1

ex1(稍微绕道而行)

function xxx() { }
// then:
xxx.prototype.constructor === xxx; // true
// since xxx is a function:
xxx.constructor === Function.prototype.constructor; // true
// and as such:
xxx.constructor === Function; // true

因此,当您使用Math.constructor时,它只是查找Math对象的原型链,就像这样(......很好):

  1. Math - > Math.hasOwnProperty('constructor') === false

  2. NOT FOUND MOVE NEXT

  3. Math.__proto__ - > Math.__proto__.hasOwnProperty('constructor') === true

  4. 找到,回复: Math.__proto__.constructor

  5. 基本上如此:

    Math.constructor === Object.prototype.constructor; // true
    // and as such:
    Math.constructor === Object; // true
    // and as stated at the top:
    Math.__proto__ === Object.prototype; // true
    

    希望这有助于确认

答案 5 :(得分:0)

在我看来,JavaScript中的Math对象试图模拟其他流行编程语言(例如Java)中的静态Math行为。由于这只能用JavaScript模拟,并且默认情况下所有对象都有原型和构造函数属性,我的猜测是开发人员忘记将构造函数属性设置为undefined,通过显式执行类似{{1}的内容}

答案 6 :(得分:0)

在您需要生成转换表而不会污染全局范围的情况下,这将非常有用。例如:

Math.constructor = function() {
  var i = 0, unicode = {}, zero_padding = "0000", max = 9999;
  //Loop through code points
  while (i < max) {
    //Convert decimal to hex value, find the character, then pad zeroes to the codepoint
    Math.constructor[String.fromCharCode(parseInt(i, 16))] = ("u" + zero_padding + i).substr(-4);
    i = i + 1;
    }    
  }

调用构造函数来填充它:

Math.constructor();

Math.constructor["a"]

另一种用途是扩展属性和方法以定义图形库的基元:

root(arg,index)     "index-th" root of argument. Example: root(x,6) sixth root of x, root[tan(x),4] fourth root of the tangent of x.
sqrt()  Square root of argument (number or expression inside the parentheses). Equivalent to root(argument,2)
cbrt()  Cube root of argument. Equivalent to root(argument,3)
logn(arg,base)  Logarithm base-base of arg.
ln()    Natural logarithm of argument (base-E logarithm of argument where E is Euler's constant)
lg()    Logarithm base-10 of argument, equivalent to logn(argument,10).
lb()    Logarithm base-2 of argument.
exp()   Exponential Function E to the power of argument, equivalent to E^argument
sin()   Sine of argument
cos()   Cosine
tan()   Tangent
cot()   Cotangent
sec()   Secant of argument, equiv. to 1/cos(arg).
csc()   Cosecant, equiv. to 1/sin(arg).
asin()  Arc sine
acos()  Arc cosine
atan()  Arc tangent
acot()  Arc cotangent
asec()  Arc secant, inverse secant.
acsc()  Arc cosecant, inverse cosecant.
sinh()  Hyperbolic sine, Sinus hyperbolicus
cosh()  Hyperbolic cosine, Cosinus hyperbolicus
tanh()  Hyperbolic tangent, Tangens hyperbolicus
coth()  Hyperbolic cotangent, Cotangens hyperbolicus
sech()  Hyperbolic secant, Secans hyperbolicus.
csch()  Hyperbolic cosecant, Cosecans hyperbolicus.
asinh()     Area sine, Area sinus hyperbolicus, inverse sinh().
acosh()     Area cosine, Area cosinus hyperbolicus, inverse cosh().
atanh()     Area tangent, Area tangens hyperbolicus, inverse tanh().
acoth()     Area cotangent, Area cotangens hyperbolicus, inverse cotanh().
asech()     Area- secant, Area secans hyperbolicus, inverse sech().
acsch()     Area- cosecant, Area cosecans hyperbolicus, inverse csch().
gaussd(x,mean,sigma)    Gaussian distribution ("Bell Curve"). gaussd(x,0,1), by the way, is the special case "Normal distribution density with mean-value=0, standard-deviation=1".
min(arg1,arg2)  Returns the lesser of the two arguments
max(arg1,arg2)  Returns the greater of the two arguments
round()     Rounds argument up or down to the closest integer
floor()     Rounds arg down.
ceil()  Rounds arg up.
abs() or | |    Absolute value of argument. Example: 2abs(sin[x]) or alternatively 2|sin(x)| .
sgn()   Sign Function. 
rand    Random number between 0 und 1. Example:
pi*rand*sin(x) or even Pirandsin(x) .
E   Euler's constant 2.718281828459045...
LN2     Natural logarithm of 2, is 0.6931471805599453...
LN10    Natural logarithm of 10, is 2.302585092994046...
LOG2E   Base-2 logarithm of E (E: see above), is 1.4426950408889633...
LOG10E  Base-10 logarithmus of E, is 0.4342944819032518...
PHI     Golden Ratio 1.61803398874989...
PI  3.141592653589793...
SQRT1_2     Square root of 1/2, is 0.7071067811865476...
SQRT2   Square root of 2, is 1.4142135623730951... 

<强>参考

答案 7 :(得分:-1)

   <script type="text/javascript">
    Math.prototype=Math;
    Math.prototype.rand=function(min,max){
        return Math.floor((Math.random() * (max-min+1))+min)
    }

    var o=[];
    for(var i=0;i<100;i++)o.push(Math.rand(-1,1));
    alert(o.join(", "))
    </script>

粗略的你也可以这样做:

Math.rand=function(min,max){
    return Math.floor((Math.random() * (max-min+1))+min)
}

Math没有像Array和String这样的原型,因为它不是一个函数,而是一个对象。由于您可以使用新的String()和新Array(),因此您还可以使用String.prototypeArray.prototype

Object, Function, Number, Date, RegExp and even Boolean也是如此。但是,任何已定义的函数都将被赋予一个prototype属性,并将继承Function和它必须继承的链中的其他任何东西。

如果你想像一个函数一样对待Math,你所要做的就是用一个函数覆盖变量。那样Math.constructor在调用时不会返回Object,因为它实际上会链接到创建它的用户定义函数。

您可以先创建本机对象的副本,然后将其丢弃到覆盖函数的原型属性之一,或使用封装,这样只有新的Math函数才能访问本机方法。不确定在这个问题上还能说些什么。

开场问题毫无意义。 Math.constructor将返回Object,并且与直接调用Object相同。唯一的区别是你改变了构造函数。

为什么要改变构造函数呢?

Math对象完全没问题。如果我们期望它从某个地方继承某些东西,那么我们期望“this”指向什么呢?如果你能够得到这个问题的答案,那么你将拥有一些可以编码的目的。