函数和 Function.prototype 之间的区别
Difference between Function and Function.prototype
根据this,函数依次继承自Function
和Function
自Function.prototype
:
The global Function
object has no methods or properties of its own, however, since it is a function itself it does inherit some methods and properties through the prototype chain from Function.prototype
.
那Function.prototype
有什么意义呢?为什么不把它的属性移到 Function
而让 Function.prototype
变成 undefined
?函数将从 Function
派生。
Object
等也是如此
原型上的函数只创建一次并在每个实例之间共享。在构造函数中创建的函数被创建为每个使用构造函数创建的新对象的新对象。
作为一般规则,函数应该在原型上,因为它们通常不会针对同一类型的不同对象进行修改,这有一点 memory/performance 好处。其他属性如对象和数组应该在构造函数中定义,除非你想创建一个共享的、静态的属性,在这种情况下你应该使用原型。
与普通对象或数组的区别比与函数的区别更容易看出
function Foo(){
this.bar = [];
}
var fooObj1 = new Foo();
var fooObj2 = new Foo();
fooObj1.bar.push("x");
alert(fooObj2.bar) //[]
as opposed to:
function Foo(){
}
Foo.prototype.bar = []
var fooObj1 = new Foo();
var fooObj2 = new Foo();
fooObj1.bar.push("x");
alert(fooObj2.bar) //["x"]
functions inherit from Function
你引用的 MDN 不严谨。它实际上说的是:
function objects inherit from Function.prototype
注意在MDN页面上,上面句子中的第一个单词"function"是大写的,但只是因为它在句子的开头,并不是因为它指的是JS对象Function
。它指的是声明为 function() { }
.
的常规旧函数
请记住,MDN 是由凡人编写的。我宁愿他们不使用 "inherit" 和 "inheritance",更不用说 "derived"。 JS没有严格意义上的继承这个概念。如果你使用这个术语,你最终会把自己弄糊涂。 JS 拥有的是与对象关联的原型。当访问对象上的 属性 时,如果没有找到,则查询原型。如果在那里找不到,因为原型也是具有原型的对象,所以会查询原型的原型,依此类推。
所以上面这句话最好写成"function objects have as their prototype Function.prototype
".
JS Function
对象与 Function.prototype
没有直接关联,除了 Function.prototype
是 Function
的 属性,并且,因为 Function
对象本身就是一个函数,它本身就有 Function.prototype
作为它的原型。 Function
上可能存在或不存在的任何属性,或由您挂在其上的任何属性,都与原型链无关,也不是任何人 "inherited"。
当您执行 (function() { }).call()
时,首先会在函数对象本身上查找 call
property/method;如果它在那里不存在(通常不存在),则在声明函数时固有分配的原型上查找它,即 Function.prototype
。如果不在 Function.prototype
上,您还会将 call
或 apply
等方法放在哪里?除了 Function.prototype
之外,您还会将自动分配给函数的原型称为什么?
顺便说一句,请注意 Function.call
将正确解析为内部 call
函数。为什么?不是因为那是 call
所在的地方,也不是因为那是常规函数 "inherit" call
的地方,而是因为,因为正如我之前提到的,Function
本身就是一个函数, 因此有原型 Function.prototype
, call
可以在其原型链上找到.
What's the point of Function.prototype
then? Why not move its properties to Function
and let Function.prototype
be undefined? Functions would be derived from Function
instead.
X.prototype
是 X 上的 属性,用作使用 X 作为构造函数创建的对象的原型。因此,要将正确的原型分配给使用 Function
作为构造函数创建的对象(包括声明为 function x() { }
的函数),原型必须作为 prototype
属性 Function
.
如果你想扩展功能,你需要 Function.prototype
,考虑这个:
Function.prototype.moo = 5;
function x() { };
console.log(x.moo); // 5
您创建的每个函数现在都有 属性 moo
,对比:
Function.quack = 6;
function b() {};
console.log(b.quack); // undefined
如果您只是将 属性 打到 Function
上,则情况并非如此。每个函数都不会继承分配给 Function
的属性,这就是为什么你需要 Function.prototype
.
根据this,函数依次继承自Function
和Function
自Function.prototype
:
The global
Function
object has no methods or properties of its own, however, since it is a function itself it does inherit some methods and properties through the prototype chain fromFunction.prototype
.
那Function.prototype
有什么意义呢?为什么不把它的属性移到 Function
而让 Function.prototype
变成 undefined
?函数将从 Function
派生。
Object
等也是如此
原型上的函数只创建一次并在每个实例之间共享。在构造函数中创建的函数被创建为每个使用构造函数创建的新对象的新对象。
作为一般规则,函数应该在原型上,因为它们通常不会针对同一类型的不同对象进行修改,这有一点 memory/performance 好处。其他属性如对象和数组应该在构造函数中定义,除非你想创建一个共享的、静态的属性,在这种情况下你应该使用原型。
与普通对象或数组的区别比与函数的区别更容易看出
function Foo(){
this.bar = [];
}
var fooObj1 = new Foo();
var fooObj2 = new Foo();
fooObj1.bar.push("x");
alert(fooObj2.bar) //[]
as opposed to:
function Foo(){
}
Foo.prototype.bar = []
var fooObj1 = new Foo();
var fooObj2 = new Foo();
fooObj1.bar.push("x");
alert(fooObj2.bar) //["x"]
functions inherit from
Function
你引用的 MDN 不严谨。它实际上说的是:
function objects inherit from
Function.prototype
注意在MDN页面上,上面句子中的第一个单词"function"是大写的,但只是因为它在句子的开头,并不是因为它指的是JS对象Function
。它指的是声明为 function() { }
.
请记住,MDN 是由凡人编写的。我宁愿他们不使用 "inherit" 和 "inheritance",更不用说 "derived"。 JS没有严格意义上的继承这个概念。如果你使用这个术语,你最终会把自己弄糊涂。 JS 拥有的是与对象关联的原型。当访问对象上的 属性 时,如果没有找到,则查询原型。如果在那里找不到,因为原型也是具有原型的对象,所以会查询原型的原型,依此类推。
所以上面这句话最好写成"function objects have as their prototype Function.prototype
".
JS Function
对象与 Function.prototype
没有直接关联,除了 Function.prototype
是 Function
的 属性,并且,因为 Function
对象本身就是一个函数,它本身就有 Function.prototype
作为它的原型。 Function
上可能存在或不存在的任何属性,或由您挂在其上的任何属性,都与原型链无关,也不是任何人 "inherited"。
当您执行 (function() { }).call()
时,首先会在函数对象本身上查找 call
property/method;如果它在那里不存在(通常不存在),则在声明函数时固有分配的原型上查找它,即 Function.prototype
。如果不在 Function.prototype
上,您还会将 call
或 apply
等方法放在哪里?除了 Function.prototype
之外,您还会将自动分配给函数的原型称为什么?
顺便说一句,请注意 Function.call
将正确解析为内部 call
函数。为什么?不是因为那是 call
所在的地方,也不是因为那是常规函数 "inherit" call
的地方,而是因为,因为正如我之前提到的,Function
本身就是一个函数, 因此有原型 Function.prototype
, call
可以在其原型链上找到.
What's the point of
Function.prototype
then? Why not move its properties toFunction
and letFunction.prototype
be undefined? Functions would be derived fromFunction
instead.
X.prototype
是 X 上的 属性,用作使用 X 作为构造函数创建的对象的原型。因此,要将正确的原型分配给使用 Function
作为构造函数创建的对象(包括声明为 function x() { }
的函数),原型必须作为 prototype
属性 Function
.
如果你想扩展功能,你需要 Function.prototype
,考虑这个:
Function.prototype.moo = 5;
function x() { };
console.log(x.moo); // 5
您创建的每个函数现在都有 属性 moo
,对比:
Function.quack = 6;
function b() {};
console.log(b.quack); // undefined
如果您只是将 属性 打到 Function
上,则情况并非如此。每个函数都不会继承分配给 Function
的属性,这就是为什么你需要 Function.prototype
.