原型与原型链的基础定义理解
关于原型与原型链下面这些基础 JavaScript 知识一定要 “死记硬背” 的。只有 “死记“,才能 “用活”。
- 对象是某个特定引用类型的实例,可以理解为对象要通过构造函数实例化实现的,而构造函数本身又是一个对象,构造函数本身又需要通过构造函数实例化实现。
- JavaScript 提供了很多原生引用类型:
Object、Array、Function、String、Number、Boolean、Date、RegExp,Map、WeakMap、Set、Symbol、BigInt
同时它们也都是原生构造函数 - 每个函数都是
Function
类型的实例,因此函数也是对象,所以同时拥有proto
和prototype
属性 - 对象都拥有隐式原型(
proto
属性)指向它的构造函数的原型对象(prototype
属性) - 每个构造函数都有一个
prototype
属性,叫原型对象(注意:原型对象,本质是对象),也叫显式原型 - 原型对象上有一个
constructor
属性指向构造函数本身 - 通过 new 实例化出来的对象没有
prototype
属性 - 对象都具有
proto
属性 - 宇宙的尽头:
Object.prototype.proto === null
- 对象的
constructor
属性用于返回创建该对象的函数
注意:并不是所以的prototype属性都是对象 Function.prototype是一个函数 它的proto属性又指向Object.prototype
typeof Function.prototype // 'function'
上面的规则 1、2、3 结合一起理解。
我们知道对象是可以这样实现的 const obj = new Object()
那么 obj 就是引用类型 Object
的实例,也就是说 obj instanceof Object 为 true
,而 Object 又是原生构造函数,即 typeof Object === "function"
,每个函数都是 Function 类型的实例,也就是 Object 也是 Function 的实例,即 Object instanceof Function 为 true
通过原型与原型链进行理解。
const obj = new Object()
,那么根据上面的规则 4 和 5 可以得知,obj.__proto__ === Object.prototype
根据规则 2、3、4 可以知道 Object 本身是引用类型也就是对象,根据规则 8,Object 拥有隐式原型 proto__ 同时 Object 也是一个函数,而函数都是 Function 的实例,也就是 Object 是 Function 的实例,因为对象的隐式原型(__proto 属性)指向它的构造函数的原型对象(prototype 属性) 所以:Object.__proto__ === Function.prototype
,根据上面的规则 5,Function.prototype
本质是对象,根据规则 8,Function.prototype 拥有隐式原型 __proto__
,而对象是通过原生构造函数 Object 实现的,所以 Function.prototype.__proto__ === Object.prototype
,最后根据规则 9,Object.prototype.__proto__ === null
。
至此,这整一个链路的过程也就是原型与原型链的原理解析过程,本质就是通过属性 __proto__
进行链接每一个节点对象。
每个函数都是Function的实例
上面的规则 3:每个函数都是 Function
类型的实例,因此函数也是对象。
function fn(){}
fn.__proto__ === Function.prototype //true
Object.__proto__ === Function.prototype //true
String.__proto__ === Function.prototype //true
Number.__proto__ === Function.prototype //true
Array.__proto__ === Function.prototype //true
Function 自己也是 Function 的实例,首先通过上文我们已经可以得知:
typeof Function === 'function' // true
Function instanceof Function === true // true
Function.__proto__ === Function.prototype //true
constructor
根据规则10可以知道,对象的constructor
属性用于返回创建该对象的函数;
let obj = new Object()
obj.constructor === Object //true
let Star = function(){}
let s = new Star()
s.constructor === Star //true
// 根据规则3可以知道,每个函数都是 Function 类型的实例,因此函数也是对象,所以同时拥有 __proto__和prototype属性
Array.constructor === Function //true
Object.constructor === Function //true
Number.constructor === Function //true
String.constructor === Function //true
原型
prototype
一般称为显式原型,proto__`一般称为隐式原型。每一个函数在创建之后,在默认情况下,会拥有一个名为 `prototype` 的属性,这个属性表示函数的原型对象。除此之外,每个 JavaScript 对象都有一个隐藏的原型属性——`__proto
- 原型对象的作用就是用来存放实例对象的公有属性和公有方法。在使用构找函数实例化的时候,会重复创建一次相同的属性和方法,属于代码的冗余。所以把共用属性和方法放在原型对象里共享
function Fn() {}
const obj = new Fn()
// 对象 obj 的隐式原型指向构造函数 Fn 的原型对象
obj.__proto__ === Fn.prototype //true
原型链
1.当访问一个对象的属性(包括方法)时,首先查找这个对象自身有没有该属性。
2.如果没有就查找它的原型(也就是__proto__
指向的prototype
原型对象) .
3.如果还没有就查找原型对象的原型( Object的原型对象) .
4.依此类推一-直找到Object为止( null) .
5.__proto__
对象原型的意义就在于为对象成员查找机制提供-个向,或者说一条路线
原型链查找规则:首先看自身对象上是否有这个属性,如果有就直接返回;如果没有就会沿着__proto__
这个隐式原型往上查找,也就是去构造函数的原型对象prototype身上查找
function Star(uname,age){
this.uname = uname
this.age = age
}
Star.prototype.sing1 = function(){
console.log('sing1')
}
Object.prototype.sing2 = function(){
console.log('sing2')
}
let ldh = new Star('ldh',18)
ldh.sing1() //sing1
ldh.sing2() //sing2
部分内容转载https://juejin.cn/post/7129157532970385421 标签:Function,__,proto,Object,理解,原型,prototype From: https://www.cnblogs.com/Lucky-daisy/p/16818646.html