时间:2021-05-25
正如一些面向对象语言中所实现的那样,在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.prototypeconst jack = new Person('jack', 'grand', 23);jack.__proto__ // Person.protytype这里的prototype指向Person的Prototype Objectjack.__proto__.__proto__ // Object.prototypenew关键词在后台为构造器方法执行了以下几步
下面是一个展示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__; // truelet alex = new Person("Alex", "Wang", 21);Person.prototype === alex.__proto__; // truealex.__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 Isconsole.log(alex); // Alex It Is以上就是详解JavaScript原型与原型链的详细内容,更多关于JavaScript原型与原型链的资料请关注其它相关文章!
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
本文实例讲述了JavaScript原型与原型链用法。分享给大家供大家参考,具体如下:一句话说明什么是原型:原型就是一个JavaScript对象,原型能存储我们的
整理《javascript高级程序设计》中继承的方法以及优缺点。1.原型链ECMAScript中描述了原型链的概念,并将原型链作为实现继承的主要方法。原型链继承
之前我对Javascript的原型链中,原型继承与标识符查找有些迷惑,如,如下的代码:复制代码代码如下:functionFoo(){};varfoo=newFo
JavaScript中this指向问题记得初学JavaScript时,其中this的指向问题曾让我头疼不已,我还曾私自将其与闭包、原型(原型链)并称JS武林中的
本文实例讲述了javascript原型与原型链的理解。分享给大家供大家参考,具体如下:javascript中一切皆对象,但是由于没有Class类的概念,所以就无