小白学习"原型"从0到1全过程

163 阅读4分钟

前言

大家好,我是阳阳,小白一枚,这个专栏是我学习原型的全部过程啦,我把看课做的笔记,结合一点百度百科,最终写出了这几篇文章,如果这些对你有帮助,那是再好不过啦~如果哪里还有不足,欢迎评论区指正喔!!

定义

function Person(){
    this.name = '阳阳'
    this.age = 18
}

首先我们定义了一个构造函数。

let p = new Person()

然后创造一个实例对象

Person { name: '阳阳', age: 18 }

于是我们得到这样一个对象

如果我们往对象身上加上一个方法,如何实现?

我们可以直接在构造方法里面用this关键字添加一个say方法。

function Person(){
    this.name = '阳阳'
    this.age = 18
    this.say = function() {
        return 'Hello'
    }
}

这样当我们调用p.say()的时候能得到Hello

换一种方法

或许我们也可以在构造函数身上直接挂一个方法,

Person.say = function(){
    return 'Hello'
}

可是当我们调用p.say()的时候会报错

TypeError: p.say is not a function

打印这个实例对象的时候发现也没有say这个方法

Person { name: '阳阳', age: 18 }

那就说明我们往函数身上直接添加的属性和方法,是不能继承到实例对象当中的。

那我们在Person后面添加一个protoytpe,它是函数天生就具有的属性,我们称它为函数的原型

Person.prototype.say = function() { 
    return 'Hello'
}

当我们现在调用p.say()的时候就可以成功拿到Hello

但是打印p的时候依旧看不到say()这个方法。我们称之为隐式继承

如果我们再创建一个对象p2

let p = new Person()

判断一下继承的父属性是否是一致,如果一致则认为他们继承的是同一个祖先。

console.log(p.say == p2.say)

ture

毋庸置疑,打印结果为ture

所以最后我们就能得到原型的定义

  • 原型(prototype)是函数天生就具有的属性,它定义了构造函数制造出的对象的公共祖先。
  • 通过该构造函数产生的对象,可以隐式继承到原型上的属性和方法。

意义

原型有何意义呢?举个栗子:

Car.prototype.name = 'BMW'
Car.prototype.lang = 4900
Car.prototype.height = 1400

function Car(owner, color){
    this.owner = owner
    this.color = color
}

var car = new Car('掘友', 'pink');

我们在买车子的时候通常会有选配的环节,但是有一些属性又是定死了的,比如车标,车长和车高,那么可以自定义的有车主的名字和颜色等等,这里简单举这样一个例子,那么定死的属性是不是可以放到构造函数的原型上去,这意味着所有通过 Car 构造函数创建的对象实例都可以共享这三个属性。

所以最后我们就能得到原型的意义

通过原型,我们可以将属性和方法定义在一个对象上,使得所有通过构造函数创建的实例都能够共享这些属性和方法,可以简化我们代码的执行。

原型的增删改

Car.prototype.name = 'BMW'
Car.prototype.lang = 4900
Car.prototype.height = 1400

function Car(owner, color){
    this.owner = owner
    this.color = color
}

var car1 = new Car('掘友', 'pink');
var car2 = new Car('掘金管理', 'green');

console.log(car1);
console.log(car2);

我们打印得到两个实例对象:

Car { owner: '掘友', color: 'pink' }

Car { owner: '掘金管理', color: 'green' }

如果突然有一天,掘友想换个车漆,那么应该怎么办?

我们直接在实例对象的属性上修改:

car1.color='black'

修改后我们发现,实例对象只能修改自己的属性值。

Car { owner: '掘友', color: 'black' }

Car { owner: '掘金管理', color: 'green' }

那掘友又想换个车标,那怎么办?

我们还是直接在实例对象的属性上修改:

car1.name='红旗'

然后我们打印car1car2.name我们发现,car1身上多了一个name属性,而且car2name属性没变

Car { owner: '掘友', color: 'black', name: '红旗' }

BMW

所以我们发现实例对象是无法修改原型的属性和方法的

那如果我就是要修改所有的实例对象的车标呢?

那我们只能跑到厂家,叫厂家改吧。所以我们只能去原型上修改:

Car.prototype.name = '红旗'

然后我们打印两个实例对象的name

红旗

红旗

那如果我就是要删除这个车标呢?我掘友就要空标上路。那么也是同理:

delete Car.prototype.name

而相比于delete car1.name就只能删除实例对象car1自己的name属性,原型上的属性只能由原型自己修改。

所以我们就可以得出原型增删改的规律:

  • 实例对象是 可以读取 原型的属性和方法的
  • 实例对象是 无法修改 原型的属性和方法的
  • 实例对象是 无法删除 原型的属性和方法的

最后

至此,原型的定义、意义与增删改已经介绍完毕,在下面的章节,我们会对原型进行更深入讲解,我在下一章等你!

下一章:    敬请期待

技术小白记录学习过程,有错误或不解的地方还请评论区留言,如果这篇文章对你有所帮助请 “点赞 收藏+关注” ,感谢支持!!