加入收藏 | 设为首页 | 会员中心 | 我要投稿 温州站长网 (https://www.0577zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 编程要点 > 语言 > 正文

JavaScript原型与原型链是什么意思?

发布时间:2022-01-06 07:36:43 所属栏目:语言 来源:互联网
导读:这篇文章主要给大家介绍关于JavaScript原型与原型链的内容,一些朋友可能对JavaScript原型和JavaScript原型链是什么不是很了解,对此本文有很详细的介绍,需要的朋友了解看看,那么接下来就跟随小编来学习一下吧。 正如一些面向对象语言中所实现的那样,在
   这篇文章主要给大家介绍关于JavaScript原型与原型链的内容,一些朋友可能对JavaScript原型和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
    下面是一个展示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

(编辑:温州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读