JS 原型与原型链

面向对象的语言有三个基本特征:封装、继承、多态。 ————这是我以前学Java的时候印象最深的一句话。

现在流行的高级语言越来越多,那到底什么是面向对象?

面向对象是相对与面向过程来说的(C语言就是一门面向过程编程的语言)。面向对象编程的思想中,有两个类和对象两个概念。

我们知道ECMAScript中没有类的概念,所以,JavaScript有别于传统的基于类的面向对象语言,JavaScript的面向对象和Java等高级语言的面向对象不同点在于,它没有抽象、继承、重载等面向对象语言的功能,而是形成了一种基于原型的面向对象

原型是什么

在JavaScript中,每一个函数都有原型。

JS中一切皆是对象,原型实质上也是一个对象。JS中所说的原型,全称叫做原型对象。当定义一个函数时,JavaScript就会在计算机内存上生成一个对应的原型对象。这个函数会有一个默认的prototype属性,prototype的值指向的就是内存上对应的原型对象

function Fn(){};
Fn.prototype.name = '李四';
Fn.prototype.sayHello = function (){
    alert('你好!');
}
console.log(Fn.prototype);

通过函数Fn的prototype属性,可以给函数对应的原型对象添加属性和方法。
在这里插入图片描述

除了通过prototype添加的name属性和sayHello方法之外,上面的图片中显示在原型上还有一个constructor属性,constructor的值指向的是当前原型对象对应的函数Fn。这就形成了一个简单的链式循环。

console.log(Fn === Fn.prototype.constructor); // true

在这里插入图片描述
JavaScript中,可以通过构造函数和new关键字来创建对象,通过这种方式创建出来的对象都具有相同的属性和行为,比如:

function Fn(){};
Fn.prototype.name = '张三';
Fn.prototype.sayHello = function (){
    return '你好,我是' + this.name + '!';
}

var fn = new Fn();
var fn2 = new Fn();
console.log(fn.name); // 张三
console.log(fn.name === fn2.name); // true
console.log(fn.sayHello === fn2.sayHello); // true

上面代码中,fn和fn2两个实例对象都是通过构造函数Fn实例化出来的,在这两个实例对象中,每个对象都有__proto__属性,指向了创建该对象的构造函数Fn的原型,所以它们共享相同的属性和方法。
其实这个属性指向了[[prototype]],但是[[prototype]]是内部属性,我们并不能访问到,一般我们使用_proto_来访问

通过下面这个图可以看到,fn和fn2的隐式原型__proto__对应的值都是其构造函数Fn的原型,所用fn.sayHello === fn2.sayHello结果为true,因为这两个方法指向的是同一个对象。

console.log(fn.__proto__ === Fn.prototype); // true
console.log(fn2.__proto__ === Fn.prototype); // true
console.log(fn.__proto__ === fn2.__proto__); // true

在这里插入图片描述

原型链

在JavaScript中,一切皆是对象,对象之间往往会通过__proto__链接在一起,这种现象被称为原型链。

JavaScript中,每个对象都有一个属性:__proto__,这个属性指向该对象的原型A,同样的道理,这个原型对象A也会有一个__proto__(原型对象也是一个对象),原型对象A的__proto__属性会指向它的原型对象B,原型对象B的__proto__属性又会指向它的原型对象C,在JavaScript中,这种现象叫做原型链。

每个对象,都会从原型中继承属性,所以,JS通过这种原理实现了基于原型的继承。

下图是一个完整的原型链示意图。(箭头颜色没啥特殊含义,只是为了表示指向,Enmmm~~~,原谅我这个手残吧。)
在这里插入图片描述

在原型链中,有两个特殊的对象,ObjectFunction
通过上面的示意图可以看到,所有的构造函数的__proto__都指向Function对象的原型(即Function.prototype),就连Function对象本身的__proto__属性也指向Function.prototype。

所有原型对象的__proto__属性都指向Object对象的原型(Object.prototype)。

Object.prototype.proto = null。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值