JS的对象的原型

翻阅到以前的学习笔记,加上自己现在的理解,谈一谈JS的原型链。

tips:本文有很多胡言乱语,如果你已经掌握js原型链,不建议阅读本文,以免被我误导。

对象的原型究竟在哪里?

function Person() {

}
let person = new Person();
复制代码

当初我很不理解,person的原型是什么? 很多教程就说:

person的原型是 person.__proto__

我又疑问,那Object的原型呢?

Object.__proto__

当初我真是特别崩溃。就好像,我问:老王的儿子是谁?有人回答:老王的儿子是老王.儿子

我期望的回答是类似于小李,小张的答案,而不是老王的儿子是老王.儿子这种间接的答案。

对象继承

我们知道其他编程语言中的面对对象,往往都是基于类的面对对象。

就好像:有人类的概念,然后我们可以创建一个人类的实例。

基于类的面对对象的代码可能长这样子:

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的原型链,还要考虑其中的逻辑意义。对象和对象的原型之间的关系就想李华和一个人之间的关系。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值