本篇内容介绍了“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原型继承机制原理”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注亿速云网站,小编将为大家输出更多高质量的实用文章!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。