Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
242 views
in Technique[技术] by (71.8m points)

javascript - Function.prototype is a function

I'm digging into the Javascript prototype chain.
In order to document my findings, I've drawn the following scheme:

enter image description here

Although most of the concepts are clear, I'm left with just two related questions. Rather than splitting them up, I guessed that centralising them in this question might be better:

  1. Is there a reason for Function.prototype to be of type function, instead of object?
    typeof Function.prototype; //"function"
  2. Is Function.prototype a 'unique function' in JS since it doesn't have a prototype property of its own like other functions do? (is there a generally accepted 'name' to refer to it?)
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The reason is that the ES5 spec says so:

The Function prototype object is itself a Function object (its [[Class]] is "Function") that, when invoked, accepts any arguments and returns undefined.

Note it's common in ES5 to make the prototype of some class a member of that class:

I think it was standardized as such because the prototype of a class has the intrinsic properties of that class, as the instances of that class. And if it looks like a duck it should behave as a duck. So calling the methods of the prototype on the prototype itself instead of on an instance should work too.

However, ES6 didn't like this. So it changed the behavior for those:

  • Boolean.prototype is an ordinary object with no [[BooleanData]] internal slot.
  • Error.prototype is an ordinary object with no [[ErrorData]] internal slot.
  • Number.prototype is an ordinary object with no [[NumberData]] internal slot.
  • Date.prototype is an ordinary object with no [[DateValue]] internal slot.
  • String.prototype is an ordinary object with no [[StringData]] internal slot.
  • RegExp.prototype is an ordinary object with no [[RegExpMatcher]] nor any of the other internal slots of RegExp instance objects.

And also for new "classes" (ES6 objects no longer have a [[Class]]):

  • Symbol.prototype is an ordinary object with no [[SymbolData]] internal slot.
  • TypedArray.prototype is an ordinary object with no [[ViewedArrayBuffer]] nor any other of the internal slots that are specific to TypedArray instance objects.
  • Map.prototype is an ordinary object with no [[MapData]] internal slot.
  • Set.prototype is an ordinary object with no [[SetData]] internal slot.
  • WeakMap.prototype is an ordinary object with no [[WeakMapData]] internal slot.
  • WeakSet.prototype is an ordinary object with no [[WeakSetData]] internal slot.
  • ArrayBuffer.prototype is an ordinary object with no [[ArrayBufferData]] nor [[ArrayBufferByteLength]] internal slots.
  • DataView.prototype is an ordinary object with no [[DataView]], [[ViewedArrayBuffer]], [[ByteLength]], nor [[ByteOffset]] internal slots.
  • GeneratorFunction.prototype is an ordinary object with no [[ECMAScriptCode]] nor any other of the internal slots listed in Table 27 or Table 56.
  • Promise.prototype is an ordinary object with no [[PromiseState]] nor any of the other internal slots of Promise instances.

However, the old behavior remains for those:

So now the reason is backwards compatibility:

The Function prototype object is specified to be a function object to ensure compatibility with ECMAScript code that was created prior to the ECMAScript 2015 specification.

Note this doesn't make Function.prototype a special function. Only constructors have the prototype property:

Function instances that can be used as a constructor have a prototype property.

There are multiple examples of non-constructor functions apart from Function.prototype, such as

  • Methods in Math object:

    typeof Math.pow; // "function
    'prototype' in Math.pow; // false
    
  • Some host objects:

    typeof document.createElement('object'); // "function
    'prototype' in document.createElement('object'); // false
    
  • In ES6, arrow functions:

    typeof (x => x * x); // "function
    'prototype' in (x => x * x); // false
    

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...