翻阅到之前的学习笔记,加上本身如今的理解,谈一谈JS的原型链。程序员
tips:本文有不少胡言乱语,若是你已经掌握js原型链,不建议阅读本文,以避免被我误导。编程
function Person() {
}
let person = new Person();
复制代码
当初我很不理解,person的原型是什么? 不少教程就说:数组
person的原型是 person.__proto__bash
我又疑问,那Object的原型呢?编程语言
Object.__proto__函数
当初我真是特别崩溃。就好像,我问:老王的儿子是谁?有人回答:老王的儿子是老王.儿子
学习
我指望的回答是相似于小李,小张的答案,而不是老王的儿子是老王.儿子
这种间接的答案。ui
咱们知道其余编程语言中的面对对象,每每都是基于类的面对对象。this
就好像:有人类的概念,而后咱们能够建立一我的类的实例。spa
基于类的面对对象的代码可能长这样子:
class Human{
}
new p1 = new Human()
复制代码
而后中国人的概念继承自人类
class Chinese extend Human{
}
let c1 = new Chinese()
复制代码
JS和基于类的继承不一样,JS是基于原型的。
可是在原型继承中,就没有人类,中国人类的概念了,取而代之的是一我的,一个中国人的概念。
汉语中,咱们会说:李华是一我的。
一我的的概念和奇特。 你能够说小明是小明,小明是人类,可是很差说小明是“一我的” 就好像英文中,"a person" "the person" 的概念,当咱们跟说道小明的时候,咱们可能再说 "the person" 而不是 "a person",你找不到"a person" 由于你找到它的时候,他就是"the person"了。
JS中,除了四种基本类型,其余一切都是对象。在js中函数也被定义为对象。那是JS对象就要有原型,lihua
的原型是什么?你可能会这样作:
lihua.__proto__
,但其实否则,对象的原型是抽象的概念,他不存在于实体(js解释器的内存中)。
lihua
是什么? lihua
是 一我的
,一我的
具备的特征李华都应该有。地球上有许多人,可是并不存在一我的
这样的实体。
有人可能会说:"我不是在控制台打印了lihua.__proto__
吗,那么在js解释器的内存中,lihua
的 __proto__
指向的内存不就是一我的
吗?"
其实这是一种误解,lihua
并无一个叫__proto__
的属性。
lihua
的原型的特征是什么,可是不能说
lihua
的原型在某块JS内存区。
在我我的理解中,用一个
的概念更容易理解JS的原型链.Object.prototype
能够理解为一个对象。Function.prototype
能够理解为一个函数,而后一个函数的原型就是一个对象,因此 Function.prototype.__proto__ === Object.prototype
下面是我画的原型链的图
obj
就是Object.prototype
、一个对象
;fun
就是Function.prototype
、一个函数
;以此类推。
咱们来捋一捋原型链。lihua
原型是一我的
,一我的
的原型是一个对象
。 Array
是一个函数
,因此他的原型是一个函数
,同时他又是Functin
的实例。一个Array的实例又是一个数组
,一个数组
的原型又是一个对象
。
用一个
的概念来理解原型,是否是容易不少?
咱们知道,除了经过构造函数,咱们还能够经过Object.create()来建立一个对象。
let a = {}
let b = Object.create(a)
复制代码
这段代码的意思就是建立一个对象b,并将b的原型指定为a。
这是有人可能会说:我这不是找到b的原型了吗?
b.__proto__ === a //true
其实我是这样想的:
let obj = {
name:"lihua"
}
let str = JSON.stringfiy(obj)
复制代码
若是把obj,str理解为JSON数据,他们表达的信息没有任何区别。
上述代码中,a既是JS解释器内存中的对象,又能表达b的原型有怎样的特征。 语法上b.__proto__ === a //true
,可是逻辑上b的原型是抽象的概念,a只是b的原型的一种表达。
好比下面三段代码
function hi(){
console.log("hi")
}
let h1 = new hi()
let lihua = {
name:"lihua"
}
let l1 = Object.create(lihua)
let aperson = {
eat:()=>{
console.log(this.name + " is eatting")
}
}
let lihuai = Object.create(aperson)
复制代码
第一段代码和第二段代码没有任何语法错误,可是逻辑上没人会这么写,由于h1
,l1
没有任何逻辑上的意义。
第三段代码和第二段没有什么语法上的区别,可是他有逻辑意义。咱们建立了一个对象lihua
,lihua
的原型是一我的,而一我的有eat
这个固有特征,你们都知道这是什么意义。等价于下面的代码:
function Person(){}
Person.prototype.eat = ()=>{
console.log(this.name + " is eatting")
}
复制代码
说了半天,就是想表达:不要单纯从语法上理解JS的原型链,还要考虑其中的逻辑意义。对象和对象的原型之间的关系就想李华和一我的之间的关系。