A similar question to this is why isArray is on Array and not on Array.prototype. That is, the isArray method is usually called using array.isarray (), not array.prototype.isarray ().

(Array.prototype) (array.prototype) (array.prototype) (array.prototype) (array.prototype)

function Person() {
    this.name = 'fan';
}
// The method is placed on the prototype object to achieve the effect of sharing methods and saving storage space
Person.prototype.sayHello = function () {
    console.log('hello');
};
Copy the code

Why can methods be placed on constructors

The constructor is an instance of the Function constructor. If it is an object, it can have its own properties and methods. Of course, you can put methods on the constructor, such as sayHello. You can place it on the Person constructor (also a Person object) as a member of Person. Each JavaScript Function is actually a Function instance.

The Function constructor is an object of its own, but it does not have its own properties and methods. It also has its own prototype objects, such as call, bind, and apply. You can access these methods through the prototype chain, because the JS Function is a Function instance object and points to function.prototype. A JS Function is a Function instance and has its own method defined in it:

What’s the difference between putting a method on a prototype object and a constructor

Because of the stereotype chain, any method placed on the stereotype object can be called directly through the instance. In layman’s terms, an instance can only access properties and methods on the stereotype chain, such as an array:

let arr = [1.2.3.4.5];
// You can call slice directly with arR
let arrCopy1 = arr.slice();
/ / Array can also be used. The prototype. Slice. Call call
let arrCopy2 = Array.prototype.slice.call(arr);
Copy the code

However, as long as this method is placed on a constructor, such as the from method, it cannot be called directly by the instance, and the instance cannot access it, as follows:

let arr = [1.2.3];
// Error call
let arrCopy = arr.from();    // TypeError: arr.from is not a function
// The correct call
let arrCopy = Array.from(arr);
Copy the code

And finally, why put the method in a different place

For example, array. isArray determines whether a variable is an Array. If you put it on array. prototype, you can only call isArray if the variable is already an Array, that is, if it is an Array, Calling arr.isarray () is true, and if it’s not an array, it can’t call isArray at all. Furthermore, variables can be a variety of values, such as the basic type number, string, undefined, or NULL. Null has no way to call any function. Therefore, the isArray method must be placed on the Array constructor, using array.isarray () every time it is called.

However, if you use call to force an instance to call a method directly on the prototype object, you can do this, but it is not recommended:

function Person() {}
Person.prototype.myIsArray = Array.isArray;

let person = new Person();
// The first argument is null, because call binds this to the first argument in the function. The array. isArray method determines whether the argument is an Array
console.log(person.myIsArray.call(null[1.2]));
// We can get the correct result to determine whether an object is an array
Copy the code

Array.isarray () lets you know whether the methods of other built-in objects are on the prototype object or on the constructor, for much the same reason.

In my opinion, the reason why the from method is used on the Array constructor is because not all data types can be converted to arrays, so there must be a type determination in the body of the function. For example, array. from(null) will report TypeError: Cannot convert undefined or NULL to object, which is obviously not appropriate on a prototype object (NULL Cannot call any methods, and the from method must handle inappropriate data types).

For Slice, it can slice arrays, it can slice strings, and it can turn array-like objects into arrays. Slice is not allowed for variables of other data types, so variables of other data types are not allowed to call slice at all.