正如您自己所说:您有一个函数object。函数是 JS 中的对象,就像对象字面量、数组或其他任何东西一样:可以随意为函数分配属性和方法:
var someAnonFunction = function(foo)
{
console.log(this);
console.log(this === someAnonFunction);//will be false most of the time
};
someAnonFunction.x = 123;//assign property
someAnonFunction.y = 312;
someAnonFunction.divide = function()
{
console.log(this === someAnonFunction);//will be true most of the time
return this.x/this.y;//divide properties x & y
};
someAnonFunction.divide();
在这种情况下,被引用的函数对象someAnonFunction
被分配了对匿名函数的引用,被称为divide
(好吧,对匿名函数的引用无论如何都被称为除法)。所以这里根本没有原型参与。请注意,正如您自己所说:所有对象都可以追溯到Object.prototype
,试试这个:
console.log(someAnonFunction.toString === Function.prototype.toString);//functions are stringified differently than object literals
console.log(someAnonFunction.hasOwnProperty === Object.prototype.hasOwnProperty);//true
或者,也许这更清楚:如何将方法/属性调用解析为 JS 中的值的简单方案:
[ F.divide ]<=========================================================\ \
F[divide] ===> JS checks instance for property divide | |
/\ || | |
|| || --> property found @instance, return value-------------------------------| |
|| || | |
|| ===========> Function.prototype.divide could not be found, check prototype | |
|| || | |
|| ||--> property found @Function.prototype, return-----------------------| |
|| || | |
|| ==========> Object.prototype.divide: not found check prototype? | |
|| || | |
|| ||--> property found @Object.prototype, return---------------------|_|
|| || |=|
|| =======>prototype is null, return "undefined.divide"~~~~~~~~~~~~~~~|X|
|| \ /
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~< TypeError can't read property 'x' of undefined
因此,如果您希望上面的代码使用原型工作,您将不得不增加各种原型(在本例中为Function.prototype
)。确实不建议这样做,实际上更改“本机”原型通常是不受欢迎的。仍然:
Function.prototype.divide = function (a, b)
{
a = +(a || 0);//coerce to number, use default value
b = +(b || 1) || 1;//division by zeroe is not allowed, default to 1
return a/b;
};
function someFunction ()
{
return 'someString';
};
var another = function(a, b)
{
return a + b;
};
someFunction.divide(12, 6);//will return 2
another.divide(12, 4);//3
someFunction
在这两种情况下,将扫描由名称 (或)引用的函数对象以查找未找到another
的名为 的属性。divide
然后,它会扫描Function.prototype
找到此类属性的 .
如果不是这样,JS 也会检查Object.prototype
,如果失败,它最终会抛出一个错误。
不久前,我在这个主题上发布了相当长的答案:
是什么让 my.class.js 如此之快?(处理原型链)
javascript 中的对象和函数(函数 <=> 对象 <=> 构造函数的回顾) JavaScript
中这三种“类”定义模式之间有什么区别?(还有更多信息)
Javascript - 动态更改函数的内容(模糊地涉及匿名函数,分配给变量和属性并更改它们的上下文)