日期:2021年9月15日
作者:Commas
签名:(ง •_•)ง 积跬步以致千里,积小流以成江海……
注释:如果您觉得有所帮助
,帮忙点个赞
,也可以关注我,我们一起成长;如果有不对的地方,还望各位大佬不吝赐教,谢谢^ - ^
1.01365 = 37.7834;0.99365 = 0.0255
1.02365 = 1377.4083;0.98365 = 0.0006
如果您想了解更多有关javascript
的知识,那么请点《javascript学习的奇妙之旅》
一、什么是原型
说明:原型实际上就是一个普通对象,由
JavaScript
自动创建并依附于每个实例对象身上。
//(1)构造函数
function F(){};
const FP = F.prototype; //显式原型
console.log(FP);
//控制台输出:
//{constructor: ƒ}
// constructor: ƒ F()
// [[Prototype]]: Object
//(2)实例对象
const f = new F();
//const f = new F.prototype.constructor();
fp = f.__proto__; //隐式原型
console.log(fp);
//控制台输出:
//{constructor: ƒ}
// constructor: ƒ F()
// [[Prototype]]: Object
//对比是否相等
console.log(FP===fp);
//控制台输出:true
我们可以看到F.prototype === f.__proto__
,函数被实例化以后,实例对象 f
通过 prototype
属性(即__proto__
)可以访问原型,从而实现继承机制。换句话说,JS中继承的本质是原型的继承。
知识加油站:
1、F.prototype
为显式原型;
2、f.__proto__
为隐式原型;
3、const f = new F();
与const f = new F.prototype.constructor();
等价;
我们也可以看看原始数据类型,它们的原型是什么?
- 对象的原型是
Object
// let obj = new Object;
let obj = {};
console.log(obj.__proto__ === Object.prototype);
//控制台输出:{} true
console.log(obj);
- 数组的原型是
Array
// let ary = new Array;
let ary = [];
console.log(ary.__proto__ === Array.prototype);
//控制台输出:[] true
console.log(ary);
- 其它数据类型(字符串、布尔值、正则表达式),如下所示:
// let str = new String;
let str = '';
console.log(str,str.__proto__ === String.prototype);
//控制台输出: true
// let bool = new Boolean();
let bool = false;
console.log(bool,bool.__proto__ === Boolean.prototype);
//控制台输出:false true
// let reg = new RegExp('a');
let reg = /a/i;
console.log(reg,reg.__proto__ === RegExp.prototype);
//控制台输出:/(?:)/ true
二、原型访问、设置与检测
- 原型访问
访问原型对象有 3 种方法,如下表所示:
序号 | 语法 | 说明 |
---|---|---|
1 | f.__proto__ | 引用原型,私有属性,属性访问器,可读可写,IE暂不支持 |
2 | f.constructor.prototype | 引用原型,构造函数 constructor 的属性 |
3 | Object.getPrototypeOf(f) | 返回值是参数 f 的原型对象 |
注释:f
表示实例对象,constructor
表示构造函数。
function F(){}; //构造函数
console.log(F);
//控制台输出: F(){}
const f = new F(); //实例对象
console.log(f);
//控制台输出:
//F {}
// [[Prototype]]: Object
// constructor: ƒ F()
// [[Prototype]]: Object
//(1)
let p1 = f.__proto__;
console.log(p1);
//控制台输出:
//{constructor: ƒ}
// constructor: ƒ F()
// [[Prototype]]: Object
//(2)
let p2 = f.constructor.prototype;
console.log(p2);
//控制台输出:
//{constructor: ƒ}
// constructor: ƒ F()
// [[Prototype]]: Object
//(3)
let p3 = Object.getPrototypeOf(f);
console.log(p3);
//控制台输出:
//{constructor: ƒ}
// constructor: ƒ F()
// [[Prototype]]: Object
console.log(p1===p2);
//控制台输出:true
console.log(p1===p3);
//控制台输出:true
console.log(p2===p3);
//控制台输出:true
- 原型设置
设置原型对象有 3 种方法,如下表所示:
序号 | 语法 | 说明 |
---|---|---|
1 | f.__proto__ = objPrototype | IE不支持 |
2 | Object.setPrototypeOf(f,objPrototype) | IE不支持 |
3 | Object.create(objPrototype) | IE支持 |
注释:f
表示实例对象,objPrototype
表示原型对象。
//原型对象
const objPrototype = {"name":"我是一个原型对象"}
//(1)
const f1 = {};
f1.__proto__ = objPrototype;
console.log(f1);
//(2)
const f2 = {};
Object.setPrototypeOf(f2,objPrototype);
console.log(f2);
//(3)
const f3 = Object.create(objPrototype);
console.log(f3);
- 原型检测
序号 | 语法 | 说明 |
---|---|---|
1 | objPrototype.isPrototypeOf(f) | 判断对象 objPrototype 是否为参数对象 f 的原型 |
2 | f instanceof F | 判断对象 f 是否是 F 的实例,变相检查 f 的原型链上是否存在 F 的原型 |
注释:f
表示实例对象,objPrototype
表示原型对象,F表示构造函数
function F(){}; //构造函数
const f = new F(); //实例对象
//检测原型
const objPrototype = f.__proto__;
console.log(objPrototype.isPrototypeOf(f));
//控制台输出:true
console.log(Object.isPrototypeOf(f));
//控制台输出:fasle
//检测实例
console.log(f instanceof F);
//控制台输出:true
console.log(f instanceof Object);
//控制台输出:true
console.log(f);
三、原型链
我们以数组为例,来探讨什么是原型链。
let ary = [];
console.log(ary.__proto__ === Array.prototype);
//控制台输出:true
let ary = [];
console.log(ary.__proto__.__proto__ === Object.prototype);
//控制台输出:true
console.log(Array.prototype.__proto__ === Object.prototype);
//控制台输出:true
我们不难发现, []
的原型等于 Arrary.prototype
,Array
的原型等于 Object.prototype
,这样就形成了一个链条,为了方便描述这种链式关系,我们将其称为原型链。为了更好体现出链式关系,我绘制了一张图,如下:
另外,我们也可以来看看构造函数与实例对象
function F(){}; //构造函数
const f = new F(); //实例对象
console.log(f);
console.log(f.__proto__ === F.prototype);
//控制台输出:true
console.log(f.__proto__.__proto__ === Object.prototype);
//控制台输出:true
因此,可以说JS中继承的本质是原型的继承;另外还可以窥探到,JS中一切皆对象的影子……
参考文章:
1、JS原型(prototype)和原型链完全攻略
2、图解JS原型与原型链实现原理
3、js的原型和原型链
版权声明:本文为博主原创文章,如需转载,请给出:
原文链接:https://blog.csdn.net/qq_35844043/article/details/120365569