关于JS中的原型

任何函数都有prototype;

任何对象都有__proto__;

函数原型也是对象,它除了__proto__,还有一个特殊的constructor。这可能是原型对象和实例对象的区别所在。如果重写了原型,那么constructor就不存在了。但是,原型链上的某一个原型对象总会有constructor

construcor不咋重要,最重要的是__proto__,只要是对象,就有proto

1.每个函数都会创建一个prototype属性,这个属性指向一个对象,包含应该由特定引用类型的实例共享的属性和方法。
(只要三个函数,就比如会附带出现一块对象储存区,链接名为prototype,一定要记住这一点。也就是说,函数,除了arguments等独特的属性,还有一个prototype。对象通过constructor属性指向函数,这样就形成了闭环。函数的prototype->对象,对象contructor->函数。每一个函数都有prototype,每一个对象都有contructor。函数和对象是共生关系,没有无对象的函数,也有离开函数的对象。)

2.对象来源于构造函数。通过new实现。一个函数new以后,就会产生一个实例,实际上也是对象。函数的prototype属性也会传给实例,在实例里面,这个属性叫[[Prototype]],它也指向函数的原型。也就说,所有的函数都有prototype,所有的对象都有contructor和[[Prototype]],这个[[Prototype]]可以通过别名__proto__访问。

3.经过new生成的对象叫实例,这个对象也有contructor和__proto__,contructor指向构造函数,__proto__指向构造函数的原型对象。

4.原型对象也是对象。它也有constructor和__proto__。原型对象的contructor回指向构造函数,但是原型对象的__proto__指向哪里呢?跟实例一样,谁造就它,它就指向谁的原型。一般情况下,对象的生产者都是Object构造函数,因此,自定义函数的原型都指向Object的原型对象。那么Object的原型对象的__proto__又指向谁呢?到根上了,没地方可指向,就给它赋值null.

 5.还有一点必须理解。实例与构造函数之间没有直接联系,实例直接联系的是构造函数的原型对象。举个例子,构造函数把实例生出来后就不管他了,而是交给奶妈原型对象去抚养了。

6.凡是都有例外,在js里, 有一个创建对象的方法Object.create(null),会创建一个新对象,真正的无父无母独立遗世,创建出的对象没有__proto__,空空如也。

7.Object.getOwnPropertyNames(),用这个方法可以查看对象的属性和方法,不管是实例还是原型,不管是可枚举还是不可枚举,都可以列出来,是一个很有用的方法。比如,Object.getOwnPropertyNames(Function.prototype),可以调出所有原生构造函数Function的原型对象中定义的属性和方法,以数组形式返回: ['length', 'name', 'arguments', 'caller', 'constructor', 'apply', 'bind', 'call', 'toString'],其中toString属于对Object原型方法的重写。再比如,Object.getOwnPropertyNames(Array.prototype),可以调出所有原生构造函数Array的原型对象中定义的属性和方法:

['length', 'constructor', 'at', 'concat', 'copyWithin', 'fill', 'find', 'findIndex', 'findLast', 'findLastIndex', 'lastIndexOf', 'pop', 'push', 'reverse', 'shift', 'unshift', 'slice', 'sort', 'splice', 'includes', 'indexOf', 'join', 'keys', 'entries', 'values', 'forEach', 'filter', 'flat', 'flatMap', 'map', 'every', 'some', 'reduce', 'reduceRight', 'toReversed', 'toSorted', 'toSpliced', 'with', 'toLocaleString', 'toString']
 
所有数组独有的方法都在里面了,其中也包括toString等重写的方法。
很有意思!
我们也可以给里面添加一些自定义的方法,但是呢,一般不这么弄,因为这样会“污染”原生命名空间,一般都是在自定义的作用域这么干
8.与Object.getOwnPropertyNames()方法相对应,还有一个类似的方法专门操作符号属性:Object.getOwnPropertySymbols()。比如,用它调出数组的符号属性Object.getOwnPropertySymbols(Array.prototype);会出现如下结果:
 [Symbol(Symbol.iterator), Symbol(Symbol.unscopables)],其中[Symbol.itetator]是内置迭代器,表面数组是可迭代的。
posted @ 2024-11-08 08:47  充实地生活着  阅读(2)  评论(0编辑  收藏  举报