详解JavaScript原型与原型链
正如一些面向对象语言中所实现的那样,在JavaScript中我们有时也需要创建一个拥有公共函数与属性的类作为父类来减少代码重复、实现类型检查与实现更加清晰地代码结构。在JavaScript中,继承是通过原型链实现的。了解JavaScript的继承与原型链之前需要了解JavaScript中对象创建的方式。
在JavaScript中创建对象
JavaScript中对象创建的方式有两种工厂方法(Factory Functions)、构造器方法(Constructor Functions) 。
工厂方法
工厂方法在编程领域是一个非类或构造器的返回对象的方法。在JavaScript中,任何返回不使用new关键词创建对象的方法都是工厂方法。
function person(firstName, lastName, age) { const person = {}; person.firstName = firstName; person.lastName = lastName; person.age = age; return person; }
构造器方法
构造器方法和工厂方法的区别仅在用例和命名规范上。命名规范上一个构造器方法的名字开头字母需要大写,我们需要通过new关键词来调用构造器方法生成实例。这个实例之后便可以通过instanceof关键词来检查。
function Person(firstName, lastName, age) { this.firstName = firstName; this.lastName = lastName; this.age = age; }
new的行为
当在工厂方法和构造器方法上使用new关键词创建时,工厂方法创建出的对象的__proto__属性指向Object.prototype,构造器方法创建出的对象的__proto__属性指向本身的Xxx.prototype。
const mike = new person('mike', 'grand', 23); mike.__proto__ // Object.prototype
const jack = new Person('jack', 'grand', 23); jack.__proto__ // Person.protytype这里的prototype指向Person的Prototype Object jack.__proto__.__proto__ // Object.prototype
new关键词在后台为构造器方法执行了以下几步
- 在构造器方法内创建一个新对象并将其赋值到this上
- 设置对象的[[Prototype]]和__proto__为原型的构造函数,这一步也让新对象的构造函数在构造新对象时被添加到原型链上
- 如果这个方法内没有返回object、function或array类型的结果,就返回this
- 如果这个方法内没有返回任何值则返回this
狼蚁网站SEO优化是一个展示new关键词在JavaScript引擎当中执行效果的伪代码,注释当中的是用来示范new关键词添加语句的伪代码
function Person(firstName, lastName, age) { // this = {}; // this.__proto__ = Person.prototype; this.firstName = firstName; this.lastName = lastName; this.age = age; // return this; }
在构造器方法上没有返回值所以后台创建的this将被返回,而工厂方法内由于返回了对象所以后台不再添加return this自然返回的内容将不一致。
如果没有在构造器方法前使用new关键词,而将构造器方法直接调用执行,其仅作为一个方法来被执行而非构造器。
const bob = Person('bob', 'grand', 23); bob // undefined. 因为这里Person当作方法直接调用了且没有返回值 window.firstName // bob. 函数内的this将指向全局作用域,导致意外操作
继承与原型链
原型
原型(Prototype)可以认为是一个JavaScript方法的属性,每次在JavaScript代码中创建方法时,JavaScript引擎会将一个名为prototype的属性添加上去,这个prototype属性是一个对象(原型对象),这个对象默认有一个constructor属性指向原方法对象。任何添加到prototype的属性和方法都在这个对象里面,所有该类实例共享这个原型对象,实例对象的__proto__属性指向这个对象,方法的prototype属性指向这个对象。
在ECMAScript的标准里object.[[Prototype]]是访问原型的方法,但在ECMAScript 2015中用Object.getPrototypeOf()和Object.setPrototypeOf()来替代。等价的__proto__是多数浏览器使用的事实上的非标准的实现。
function Person(firstName, lastName, age) { this.firstName = firstName; this.lastName = lastName; this.age = age; } Person.prototype === Person.prototype.constructor.prototype // 指向Person的原型对象 Person.prototype.constructor === Person // 指向Person方法对象 let bob = new Person("Bob", "Ross", 21); Person.prototype === bob.__proto__; // true let alex = new Person("Alex", "Wang", 21); Person.prototype === alex.__proto__; // true alex.__proto__ === bob.__proto__; // true
原型链
我们需要了解对象查找机制。当我们使用一个对象的属性时,JavaScript引擎会查找本对象里是否有对应属性,如果没有则去对象的原型里查找属性,如果没有则去对象的原型对象的原型对象里查找属性,直至查询到对象的__proto__为null的时候停止。
const obj = {}; console.log(obj); // [object Object] obj的toString()方法从Object的原型中查找到并使用 function Person(firstName, lastName, age) { this.firstName = firstName; this.lastName = lastName; this.age = age; // 在Person.prototype上定义了toString覆写了Object.prototype上的toString Person.prototype.toString = function() { return `${this.firstName} It Is`; } } let bob = new Person("Bob", "Ross", 21); let alex = new Person("Alex", "Wang", 21); console.log(bob); // Bob It Is console.log(alex); // Alex It Is
以上就是详解JavaScript原型与原型链的详细内容,更多关于JavaScript原型与原型链的资料请关注狼蚁SEO其它相关文章!
编程语言
- 如何快速学会编程 如何快速学会ug编程
- 免费学编程的app 推荐12个免费学编程的好网站
- 电脑怎么编程:电脑怎么编程网咯游戏菜单图标
- 如何写代码新手教学 如何写代码新手教学手机
- 基础编程入门教程视频 基础编程入门教程视频华
- 编程演示:编程演示浦丰投针过程
- 乐高编程加盟 乐高积木编程加盟
- 跟我学plc编程 plc编程自学入门视频教程
- ug编程成航林总 ug编程实战视频
- 孩子学编程的好处和坏处
- 初学者学编程该从哪里开始 新手学编程从哪里入
- 慢走丝编程 慢走丝编程难学吗
- 国内十强少儿编程机构 中国少儿编程机构十强有
- 成人计算机速成培训班 成人计算机速成培训班办
- 孩子学编程网上课程哪家好 儿童学编程比较好的
- 代码编程教学入门软件 代码编程教程