Math对象没有prototype属性,但有一个构造函数属性。有没有重新定义构造函数有用的情况?
答案 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对象仅用于提供标准函数,并为程序员提供不定义Pi
或E
的杠杆作用。用户定义的数学函数可能比内置函数慢几倍。
答案 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
对象的原型链,就像这样(......很好):
Math
- > Math.hasOwnProperty('constructor')
的 === false
强>
NOT FOUND MOVE NEXT
Math.__proto__
- > Math.__proto__.hasOwnProperty('constructor')
的 === true
强>
找到,回复: Math.__proto__.constructor
基本上如此:
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.prototype
和Array.prototype
。
Object, Function, Number, Date, RegExp and even Boolean
也是如此。但是,任何已定义的函数都将被赋予一个prototype属性,并将继承Function和它必须继承的链中的其他任何东西。
如果你想像一个函数一样对待Math
,你所要做的就是用一个函数覆盖变量。那样Math.constructor
在调用时不会返回Object,因为它实际上会链接到创建它的用户定义函数。
您可以先创建本机对象的副本,然后将其丢弃到覆盖函数的原型属性之一,或使用封装,这样只有新的Math函数才能访问本机方法。不确定在这个问题上还能说些什么。
开场问题毫无意义。 Math.constructor将返回Object,并且与直接调用Object相同。唯一的区别是你改变了构造函数。
为什么要改变构造函数呢?
Math
对象完全没问题。如果我们期望它从某个地方继承某些东西,那么我们期望“this
”指向什么呢?如果你能够得到这个问题的答案,那么你将拥有一些可以编码的目的。