JavaScript 原型概念的介绍

发布时间:2021-06-21 13:35:14 作者:chen
来源:亿速云 阅读:164

本篇内容主要讲解“JavaScript 原型概念的介绍”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“JavaScript 原型概念的介绍”吧!

原型是JavaScript中一个比较难理解的概念,原型相关的属性也比较多,对象有”[[prototype]]”属性,函数对象有”prototype”属性,原型对象有”constructor”属性。

为了弄清原型,以及原型相关的这些属性关系,就有了这篇文章。

相信通过这篇文章一定能够清楚的认识到原型,现在就开始原型之旅吧。

认识原型

开始原型的介绍之前,首先来认识一下什么是原型?

在JavaScript中,原型也是一个对象,通过原型可以实现对象的属性继承,JavaScript的对象中都包含了一个” [[Prototype]]”内部属性,这个属性所对应的就是该对象的原型。

“[[Prototype]]”作为对象的内部属性,是不能被直接访问的。所以为了方便查看一个对象的原型,Firefox和Chrome中提供了”__proto__”这个非标准(不是所有浏览器都支持)的访问器(ECMA引入了标准对象原型访问器”Object.getPrototype(object)”)。

实例分析

下面通过一个例子来看看原型相关概念:

function Person(name, age){     this.name = name;     this.age = age;      this.getInfo = function(){         console.log(this.name + " is " + this.age + " years old");     }; }  var will = new Person("Will", 28);

在上面的代码中,通过了Person这个构造函数创建了一个will对象。下面就通过will这个对象一步步展开了解原型。

Step 1: 查看对象will的原型

通过下面代码,可以查看对象will的原型:

console.log(will.__proto__); console.log(will.constructor);

结果分析:

JavaScript 原型概念的介绍

Step 2: 查看对象will的原型(will.__proto__)的原型

既然will的原型”Person {}”也是一个对象,那么我们就同样可以来查看”will的原型(will.__proto__)的原型”。

运行下面的代码:

console.log(will.__proto__ === Person.prototype); console.log(Person.prototype.__proto__); console.log(Person.prototype.constructor); console.log(Person.prototype.constructor === Person);

结果分析:

通过上面可以看到,“Person.prototype”对象和Person函数对象通过”constructor”和”prototype”属性实现了相互引用(后面会有图展示这个相互引用的关系)

JavaScript 原型概念的介绍

Step 3: 查看对象Object的原型

通过前一部分可以看到,will的原型的原型是”Object {}”对象。实际上在JavaScript中,所有对象的原型都将追溯到”Object {}”对象。

下面通过一段代码看看”Object {}”对象:

console.log(Person.prototype.__proto__ === Object.prototype); console.log(typeof Object); console.log(Object); console.log(Object.prototype); console.log(Object.prototype.__proto__); console.log(Object.prototype.constructor);

通过下面的代码可以看到:

JavaScript 原型概念的介绍

Step 4: 查看对象Function的原型

在上面的例子中,Person是一个构造函数,在JavaScript中函数也是对象,所以,我们也可以通过”__proto__”属性来查找Person函数对象的原型。

console.log(Person.__proto__ === Function.prototype); console.log(Person.constructor === Function) console.log(typeof Function); console.log(Function); console.log(Function.prototype); console.log(Function.prototype.__proto__); console.log(Function.prototype.constructor);

结果分析 :

JavaScript 原型概念的介绍

对比prototype和__proto__

对于”prototype”和”__proto__”这两个属性有的时候可能会弄混,”Person.prototype”和”Person.__proto__”是完全不同的。

在这里对”prototype”和”__proto__”进行简单的介绍:

图解实例

通过上面结合实例的分析,相信你一定了解了原型中的很多内容。

但是现在肯定对上面例子中的关系感觉很凌乱,一会儿原型,一会儿原型的原型,还有Function,Object,constructor,prototype等等关系。

现在就对上面的例子中分析得到的结果/关系进行图解,相信这张图可以让你豁然开朗。

JavaScript 原型概念的介绍

对于上图的总结如下:

通过原型改进例子

在上面例子中,”getInfo”方法是构造函数Person的一个成员,当通过Person构造两个实例的时候,每个实例都会包含一个”getInfo”方法。

var will = new Person("Will", 28);
var wilber = new Person("Wilber", 27);

JavaScript 原型概念的介绍

前面了解到,原型就是为了方便实现属性的继承,所以可以将”getInfo”方法当作Person原型(Person.__proto__)的一个属性,这样所有的实例都可以通过原型继承的方式来使用”getInfo”这个方法了。

所以对例子进行如下修改:

function Person(name, age){     this.name = name;     this.age = age; }  Person.prototype.getInfo = function(){     console.log(this.name + " is " + this.age + " years old"); };

修改后的结果为:

JavaScript 原型概念的介绍

原型链

因为每个对象和原型都有原型,对象的原型指向对象的父,而父的原型又指向父的父,这种原型层层连接起来的就构成了原型链。

在”理解JavaScript的作用域链“一文中,已经介绍了标识符和属性通过作用域链和原型链的查找。

这里就继续看一下基于原型链的属性查找。

属性查找

当查找一个对象的属性时,JavaScript 会向上遍历原型链,直到找到给定名称的属性为止,到查找到达原型链的顶部(也就是 “Object.prototype”), 如果仍然没有找到指定的属性,就会返回 undefined。

看一个例子:

function Person(name, age){     this.name = name;     this.age = age; }  Person.prototype.MaxNumber = 9999; Person.__proto__.MinNumber = -9999;  var will = new Person("Will", 28);  console.log(will.MaxNumber); // 9999 console.log(will.MinNumber); // undefined

在这个例子中分别给”Person.prototype “和” Person.__proto__”这两个原型对象添加了”MaxNumber “和”MinNumber”属性,这里就需要弄清”prototype”和”__proto__”的区别了。

“Person.prototype “对应的就是Person构造出来所有实例的原型,也就是说”Person.prototype “属于这些实例原型链的一部分,所以当这些实例进行属性查找时候,就会引用到”Person.prototype “中的属性。

属性隐藏

当通过原型链查找一个属性的时候,首先查找的是对象本身的属性,如果找不到才会继续按照原型链进行查找。

这样一来,如果想要覆盖原型链上的一些属性,我们就可以直接在对象中引入这些属性,达到属性隐藏的效果。

看一个简单的例子:

function Person(name, age){     this.name = name;     this.age = age; }  Person.prototype.getInfo = function(){     console.log(this.name + " is " + this.age + " years old"); };  var will = new Person("Will", 28); will.getInfo = function(){     console.log("getInfo method from will instead of prototype"); };  will.getInfo(); // getInfo method from will instead of prototype

对象创建方式影响原型链

会到本文开始的例子,will对象通过Person构造函数创建,所以will的原型(will.__proto__)就是”Person.prototype”。

同样,我们可以通过下面的方式创建一个对象:

var July = {     name: "July",     age: 28,     getInfo: function(){         console.log(this.name + " is " + this.age + " years old");     }, }  console.log(July.getInfo());

当使用这种方式创建一个对象的时候,原型链就变成下图了,July对象的原型是”Object.prototype”也就是说对象的构建方式会影响原型链的形式。

JavaScript 原型概念的介绍

hasOwnProperty

“hasOwnProperty”是”Object.prototype”的一个方法,该方法能判断一个对象是否包含自定义属性而不是原型链上的属性,因为”hasOwnProperty” 是 JavaScript 中***一个处理属性但是不查找原型链的函数。

相信你还记得文章最开始的例子中,通过will我们可以访问”constructor”这个属性,并得到will的构造函数Person。这里结合”hasOwnProperty”这个函数就可以看到,will对象并没有”constructor”这个属性。

从下面的输出可以看到,”constructor”是will的原型(will.__proto__)的属性,但是通过原型链的查找,will对象可以发现并使用”constructor”属性。

JavaScript 原型概念的介绍

“hasOwnProperty”还有一个重要的使用场景,就是用来遍历对象的属性。

function Person(name, age){     this.name = name;     this.age = age; }  Person.prototype.getInfo = function(){     console.log(this.name + " is " + this.age + " years old"); };  var will = new Person("Will", 28);  for(var attr in will){     console.log(attr); } // name // age // getInfo  for(var attr in will){     if(will.hasOwnProperty(attr)){         console.log(attr);     } } // name // age

总结

本文介绍了JavaScript中原型相关的概念,对于原型可以归纳出下面一些点:

还有要强调的是文章开始的例子,以及通过例子得到的一张”普通对象”,”函数对象”和”原型对象”之间的关系图,当你对原型的关系迷惑的时候,就想想这张图(或者重画一张当前对象的关系图),就可以理清这里面的复杂关系了。

到此,相信大家对“JavaScript 原型概念的介绍”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

推荐阅读:
  1. 何为JavaScript原型?读完你就明白了
  2. JavaScript面向对象是什么

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

javascript

上一篇:JS如何实现课堂随机点名和顺序点名

下一篇:Dojo1.6有什么新的特性

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》