原型与原型链
- 1. 原型(prototype)
-
-
- 1.1 每个函数都有一个prototype属性,且默认指向一个空的Object对象
- 1.2 原型对象中有一个属性constructor,它指向函数对象
- 1.3 给原型对象添加属性
-
- 2. 显式原型与隐式原型
- 3.原型链
-
-
- 3.1 原型链图解
-
- 图解一:以Fn与Obecjt为例
- 图解二:以两种创建对象的方式为例
- 图解三:以function Foo(){}为例
- 3.2 原型链补充( 重要 )
- 3.3原型链的属性问题
-
- 4. 探索instanceof底层原理
-
- 4.1 案例一
1. 原型(prototype)
原型 - 锐客网 >
// 输出Date原型中的属性及方法以及Date原型的类型
console.log(Date.prototype, typeof Date.prototype)// 定义一个函数Fn
function Fn(){}
// 输出Fn原型中的属性及方法以及Fn原型的类型
console.log(Fn.prototype, typeof Fn.prototype)
// 查看原型中对象的constructor属性是否指向原对象
console.log(Date.prototype.constructor === Date)
console.log(Fn.prototype.constructor === Fn)// 给原型对象添加属性
Fn.prototype.test = function(){
console.log("test....")
}
// 声明一个实例对象
var f1 = new Fn();
// 调用原型中的方法
f1.test()
1.1 每个函数都有一个prototype属性,且默认指向一个空的Object对象
console.log(Date.prototype, typeof Date.prototype)
输出Date原型中的属性及方法以及Date原型的类型
文章图片
function fn(){}
console.log(fn.prototype, typeof fn.prototype)
自定义fn函数,输出fn函数的原型,默认为空对象(并没有多余的属性和方法),原型类型为Object
文章图片
1.2 原型对象中有一个属性constructor,它指向函数对象
console.log(Date.prototype.constructor === Date) // true
console.log(fn.prototype.constructor === fn)// true
定义一个Type函数 function Type(){ }
其内部有prototype属性,此属性指向一个对象,对象中有constructor属性,指向原来的Type函数
文章图片
1.3 给原型对象添加属性
function Fn(){}
// 给原型对象添加属性(一般是方法)可供实例对象使用
Fn.prototype.test = function(){
console.log("test....")
}
// 声明一个实例对象
var f1 = new Fn();
// 调用原型中的方法
f1.test()
2. 显式原型与隐式原型
显式原型与隐式原型 - 锐客网 >
// 创建一个构造函数
function Fun(){
// 内部隐含语句:this.prototype = {}
}// 1.每个函数function都有一个prototype属性,即显式原型属性,默认指向空的Obejct对象
console.log(Fun.prototype);
// 2.每个实例对象都有一个__proto__ , 可称为隐式原型属性,
// 默认指向和函数相同指向的那个空的Obejct对象
var fun = new Fun();
// 内部隐含语句 this.__ptoto__ = Fun.prototype
console.log(fun.__proto__);
// 3.对象的隐式原型的值为其对应构造函数的显式原型的值
console.log(Fun.prototype === fun.__proto__);
// true
文章图片
文章图片
3.原型链
原型链 - 锐客网 >
console.log(Object.prototype)
function Fn(){
this.test1 = function(){
console.log('test1....');
}
}Fn.prototype.test2 = function(){
console.log("test2.....");
}var f1 = new Fn();
f1.test1();
f1.test2();
f1.test3();
3.1 原型链图解
图解一:以Fn与Obecjt为例
- 在开始时,浏览器会在内存中创建Obejct函数对象,假设为0x456,函数对象存在prototype属性,Object的prototype属性会指向其原型对象,假设其原型对象地址值为0x345。
- 开发人员创建Fn函数时,会在栈中存储Fn的变量,其保存Fn函数对象的地址,假设为0x123,同时其函数对象内部的prototype属性会指向一个空的Object对象,假设为0x234。
- Fn.prototype.test2表示在Fn内部的prototype指向的空对象中会创建一个test2函数对象
- 当执行var fn = new Fn()时会在栈中生成一个fn变量,保存Fn实例对象的地址,假设为0x567
文章图片
- 当使用var o1 = new Object()方式创建一个对象时,o1为实例对象,按照原则,实例对象内部有__proto__属性,其指向创建自己的函数对象的原型对象,即为Object()的原型对象,原型对象中存在constructor属性,指向函数对象本身,因此在函数对象和其原型对象之间会形成一个环,即表现为互相引用,互相指向。
- 使用var o2 = {}方式创建对象与上述方式相同
文章图片
- 执行function Foo(){}时,会在内存中生成Foo函数对象以及其指向的原型对象,函数对象中存在prototype属性,其保存的地址值指向其原型对象(即为下图中线1所表示),原型对象中存在constructor属性,其保存的地址值指向其对应得函数对象(即为下图中线2所表示)。
- 因为开发人员定义的任何函数都是通过new Function()创建的,例如创建方式为var Foo = new Functon(),因此创建得到的函数也属于Function的实例对象,因此创建的函数也具备__proto__属性,其指向创建自己函数对象的原型对象(即为下图中线3所表示)。
- 由下图可知Function本身具备__proto__属性,此属性为实例对象所具备的,因此可知Function也为某个函数的实例对象,通过下图中的线4可知,Function的__proto__指向自身的prototype,因此可知,Function是通过自身创建的,即为Function = new Function()。从Function()作为函数对象的角度来看,函数对象具备prototype,其指向自身的原型对象,即为下图中线5所表示,而原型对象也会又constructor属性,指向自身的函数对象,即下图中线6所表示的。
- Object()也是一个函数对象,因此它也是通过Function()所创建的,因此Object()函数对象也是实例对象,其内部也存在__proto__指向创建自身的函数对象的原型,即为Function()函数对象的原型,即下图中线9所表示的。
文章图片
原型链补充 - 锐客网
>
function Fn(){}
// 1.函数的显式原型指向的对象默认是空Object对象,但对于Object函数来说并不满足此条件
console.log(Fn.prototype instanceof Object)// true
console.log(Object.prototype instanceof Object)// false
// Function函数对象的原型也是Object的实例对象
console.log(Function.prototype instanceof Object)// false// 2.所有的函数都是Function的实例,包括function自身
console.log(Function.__proto__ === Function.prototype)// true// 3.Object的原型对象是原型链的尽头
console.log(Object.prototype.__proto__)// null
3.3原型链的属性问题
原型链_属性问题 - 锐客网 ="text/javascript">
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.setName = function (name) {
this.name = name;
}
Person.prototype.sex = '男';
var p1 = new Person('Tom', 12)
p1.setName('Jack')
console.log(p1.name, p1.age, p1.sex)
p1.sex = '女'
console.log(p1.name, p1.age, p1.sex)var p2 = new Person('Bob', 23)
console.log(p2.name, p2.age, p2.sex)
文章图片
4. 探索instanceof底层原理 4.1 案例一
05_探索instanceof - 锐客网 ="text/javascript">
//案例1
function Foo() {}
var f1 = new Foo();
console.log(f1 instanceof Foo);
console.log(f1 instanceof Object);
//案例2
console.log(Object instanceof Function)
console.log(Object instanceof Object)
console.log(Function instanceof Object)
console.log(Function instanceof Function)
function Foo() {}
console.log(Object instanceofFoo);
1. 判断f1是否是Foo的实例,对于f1来说,沿着__proto__向上第一个节点为Foo.prototype, Foo查看prototype的指向,因此两条线路相交于Foo.prototype,则是Foo的实例
2. 判断f1是否是Object的实例, 对于f1来说,沿着__proto__向上第一个节点为Foo.prototype, Object的prototype指向Object.prototype, 各向上走一步并没有相交,f1可沿着__proto__继续向上走,第二个节点指向Object.prototype , 两则在此处相交,因此是Object的实例。
【#|Javascript之原型与原型链】
文章图片
推荐阅读
- #|弹性盒基础
- Vue知识|什么是.vue文件,它的作用是什么
- JavaScript简介-JavaScript入门基础(001)
- 对象-JavaScript入门基础(016)
- 在Javascript中调用嵌套的div类。修改后的代码在WordPress中不起作用
- 将Bootstrap 4 JS文件添加到WordPress主题时出错-内存耗尽
- 在js,wordpress中移动CSS类时,使用insertafter复制CSS类
- 前端|生鲜 B2B 技术平台的前端团队该如何搭建(B2B 技术共享第七篇)
- 在elementor小部件中显示wordpress短代码()