JS的对象的原型

翻阅到之前的学习笔记,加上本身如今的理解,谈一谈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()

咱们知道,除了经过构造函数,咱们还能够经过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没有任何逻辑上的意义。

第三段代码和第二段没有什么语法上的区别,可是他有逻辑意义。咱们建立了一个对象lihualihua的原型是一我的,而一我的有eat这个固有特征,你们都知道这是什么意义。等价于下面的代码:

function Person(){}
Person.prototype.eat = ()=>{
    console.log(this.name + " is eatting")
}
复制代码

结语

说了半天,就是想表达:不要单纯从语法上理解JS的原型链,还要考虑其中的逻辑意义。对象和对象的原型之间的关系就想李华和一我的之间的关系。

相关文章
相关标签/搜索