本篇内容介绍了“JavaScript原型继承机制原理”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
文章目录
(1)案例一
JavaScript原型继承机制
JavaScript并非一个纯粹的面向的对象的语言,也没有一个实际意义上的继承机制。语言的设计者最初并未想实现继承机制,但是后来还是实现了一个类似的机制——原型继承机制。但实际上,这并非实际的继承,我们来一一揭开JavaScript的伪继承机制。
在JavaScript中,typeof是测试对象的类型,只会测试出对象属于哪种内置类型,无法测试自定义类型。也就是所有自定义类型都会返回object。
而obj instanceof sometype(obj 指对象,sometype指的是类型),是测试obj的原型链中是否有sometype类型。所以通过错误的改变prototype的值会使得instanceof得出的结构不合理。
<script>
var num = 10;
document.write("typeof num:"+typeof num+"<br/>");
var onum = Number(10);
document.write("typeof onum:"+typeof onum+"<br/>");
var str = "1010";
document.write("typeof str:"+typeof str+"<br/>");
var ostr = String("1010");
document.write("typeof ostr:"+typeof ostr+"<br/>");
var bol = true;
document.write("typeof bol:"+typeof bol+"<br/>");
var obol = true;
document.write("typeof obol:"+typeof obol+"<br/>");
var dat = new Date();
document.write("typeof dat:"+typeof dat+"<br/>");
var func = new Function('x','y',"return x+y;");
document.write("typeof func:"+typeof func+"<br/>");
var myconstructor = function Person(){};
document.write("typeof myconstructor:"+typeof myconstructor+"<br/>");
var myobj = new myconstructor();
document.write("typeof myobj:"+typeof myobj+"<br/>");
</script>
结果:
typeof num:number typeof onum:number typeof str:string typeof ostr:string typeof bol:boolean typeof obol:boolean typeof dat:object typeof func:function typeof myconstructor:function typeof myobj:object
这说明元构造器的类型为:function
内建的普通构造器类型为:function
自定义普通构造器类型为:function
所有内置对象类型为:内置类型
所有自定义普通对象:object
实际就是测试实例是否有继承基类的原型链,如obj instanceof Type,若obj的原型链中Type则返回true,否则返回false。
//案例一
var Person = function(){};
var obj = new Person();
document.write((obj instanceof Person) +"<br/>");
document.write((obj instanceof Object) +"<br/>");
document.write(obj.__proto__ +"<br/>");
document.write(Person.constructor+"<br/>");
document.write(obj.constructor+"<br/>");
document.write((obj.constructor === Person)+"<br/>");
结果:
true true [object Object] function Function() { [native code]} function (){} true
//案例二
var other = function(){};
Person.prototype = new other();
document.write((obj instanceof Person) +"<br/>");
document.write((obj instanceof Object) +"<br/>");
document.write((obj instanceof other) +"<br/>");
document.write(obj.__proto__ +"<br/>");
document.write(obj.constructor+"<br/>");
结果:
false true false [object Object] function (){}
//案例三
obj.__proto__ = new other();
document.write((obj instanceof Person) +"<br/>");
document.write((obj instanceof Object) +"<br/>");
document.write((obj instanceof other) +"<br/>");
document.write(obj.__proto__ +"<br/>");
结果:
false true true [object Object]
下面我们就来具体分析这三个案例:
var Person = function(){};
这句具体发生了什么呢?我们用下面的伪代码来解释一下:生成了一个函数对象Person
{
this.prototype = {constructor:this}; //{}表示一个Object构造的空对象
var prototype = Function.prototype; //内部{Prototype}属性,不能改变
this.__proto__ = prototype; //内部属性的外部访问方式,
this.constructor = this; // 默认的,也是合理的值
}
var obj = new Person();
这句发生了什么呢?我们也用伪代码来解释一下:生成普通对象obj
{
var prototype = Person.prototype;
this.__proto__ = prototype;
this.constructor = Person;
}
按此来说,在案例一中:
//function类型
Person.__proto__=== Function.prototype;
//object类型, 默认情况下每个构造器内部都有一个Object的实例对象,供所有子类共享,这就是所有对象都默认继承object的实例的原因
Person.prototype === obj.__proto__ ;
//验证每个自定义类型都默认继承自一个Object实例object
Person.prototype.__proto__ = Object.prototype;
//每个对象的构造器为构造它的函数对象
Person.constructor === Function;
Function.constructor === Function; //说明Function由自己构造,自举性
obj.constructor === Person;
//从中可以看出prototype告诉构造器,你构造的对象应该继承谁
//__proto__可以告诉我们该对象继承自谁。
其次我们可以看出:
//Function 的自举性
Function.prototype === Function.prototype;
Function.__proto__ === Function.prototype;
Function.constructor === Function;
//Object由Function构造
Object.prototype === Object.prototype;
Object.__proto__ === Function.prototype;
Object.constructor === Function;
Function.prototype.__proto__ === Object.prototype; //说明Object.prototype是万物之源
而obj对象呢,也有着这些特性,不过它是普通对象,没有公开属性prototype:
//普通对象特性
obj.__proto__ === Person.prototype;
obj.constructor === Person;
我们再来看看Object.prototype:
//元对象
Object.prototype === Object.prototype; //对象的祖宗,根
Object.prototype.__proto__ === null; //祖先没有祖先,单位了系统完备,其内部仍然有{Prototype}属性,置为null,合理。
Object.prototype.constructor === Object; //祖先按理说是没有构造器的,但为了说明祖先仍然属于Object的实例,就这么做。
接着我们再看看Function.prototype:
//元构造器
Function.prototype === Function.prototype; //由Function构造出来的对象的原型
Function.prototype.__proto__ === Object.prototype; //对象Function.prototype的原型为Object.prototype
Function.prototype.constructor === Function;
//对象Function.prototype是由构造器Function构造的,实际上并非如此,但是为了Function.prototype的类型是Function也就这么设计了。
在Js中有两个顶级上司,或者说顶级公民:Function.prototype 和Object.prototype。
1.一切都是对象
在Js中一切都是对象,而几乎所有对象都由构造器产生。不过有一个例外,所有对象的基础(元对象):Object.prototype,他不是由构造器产生,而是由Js引擎实现。它不同于java的Object——那是一个类,而Js中的Object.prototype仅仅是一个对象,它不能作为构造器。这来来讲就好比西方人类最初也只有两个人作为祖先——亚当和夏娃。但是在Js中只有一个没有构造功能的Object.prototype那么如何基于这个原型来构造子对象呢,这就需要下面讲到的元构造器——Function.prototype。
2.Object.prototype不是由构造器产生
3.Function.prototype由自己构造,但是却是继承自Object.prototype
4.继承只是继承对象,所谓对象A继承自B,说明对象A维护者对象B的引用
5.函数对象中的__proto__才是指明该函数对象作为对象时继承自谁,或者说维护了哪个对象的引用
6.函数对象中有个特别的特性prototype,这是普通对象所不具有的,这是函数对象作为构造器时的特性,它指明了该构造器作为”伪类“时的内部数据结构,他是一个引用类型。由该构造器构造出来的对象都维护着prototype所引用的对象的引用
“JavaScript原型继承机制原理”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注亿速云网站,小编将为大家输出更多高质量的实用文章!
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。
原文链接:https://www.xuebuyuan.com/3256670.html