如你所说: 你有一个函数对象。在JS中,函数就像Object字面量、数组或其他任何东西一样都是对象:函数可以随意分配属性和方法:
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
(不过,引用匿名函数的引用被命名为
divide
)。所以这里根本没有涉及原型。请注意,正如你自己所说:所有对象都可以追溯到
Object.prototype
,只需尝试此操作即可:
console.log(someAnonFunction.toString === Function.prototype.toString)
console.log(someAnonFunction.hasOwnProperty === Object.prototype.hasOwnProperty)
或许这样更加清晰: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);
b = +(b || 1) || 1;
return a/b;
};
function someFunction ()
{
return 'someString';
};
var another = function(a, b)
{
return a + b;
};
someFunction.divide(12, 6);
another.divide(12, 4);
在这两种情况下,函数对象,由名称(
someFunction
或
another
)引用,将被扫描以查找名为
divide
的属性,但未找到。然后它将扫描
Function.prototype
,在那里找到了这样的属性。
如果不是这样,JS还会检查
Object.prototype
,如果失败,最终会抛出错误。
我之前在SO上发布过关于这个主题的相当详细的答案:
什么使得my.class.js如此快速?(处理原型链)
JavaScript中的对象和函数(函数、对象和构造函数的回顾)
这三种JavaScript中"class"定义的模式有何不同?(更多信息,但仍需澄清)
JavaScript - 动态更改函数的内容(略带匿名函数,分配给变量和属性并更改其上下文)
var addNum = function(num1, num2) { this.divide = function(){} return num1 + num2; }
我认为是的。 - Weishi Z