您好,欢迎访问一九零五行业门户网

js原型和原型链是什么

js原型和原型链是:1、原型,所有的函数默认都有一个“prototype”这样公有且不可枚举的属性,它会指向另一个对象,这个对象就是原型。2、原型链,当访问对象的属性或方法时,首先对象会从自身去找,找不到就会往原型中去找,也就是它构造函数的“prototype”中,如果原型中找不到,即构造函数中也没有该属性,就会往原型后面的原型上去找,这样就形成了链式的结构,称为原型链。
本教程操作系统:windows10系统、javascript  ecmascript 2021版本、dell g3电脑。
一、原型
原型:所有的函数默认都有一个“prototype”这样公有且不可枚举的属性,它会指向另一个对象,这个对象就是原型。每当定义一个对象(函数也是对象)时,就会生成一个__proto__属性,被称为隐式原型;这个__proto__属性指向的是这个对象的构造函数的prototype,被称为显式原型。每一个对象都会从原型中“继承”属性。
首先看一个例子,创建一个student类,并创建类的实例对象student:
class student{ constructor(name, score) { this.name = name; this.score = score; } introduce() { console.log(`我是${this.name},考了${this.score}分。`) }}const student = new student('张三', 99)console.log('student', student); // student student { name: '张三', score: 99}student.introduce(); // 我是张三,考了99分。
控制台能访问到属性和方法。
但是直接在控制台输入student,会发现只有name和score属性,没有introduce方法,但是有一个[[prototype]]属性,用两个中括号括起来。
把[[prototype]]展开,会发现introduce方法在[[prototype]]中。
[[prototype]]属性被称为student对象的隐式原型。当我们要去找一个对象的属性或者方法时,如果在当前对象上找不到,就会去当前对象的隐式原型[[prototype]]属性上去找。
可通过.__proto__属性访问原型,注意__proto__两边分别有两条下划线。
而student()构造函数也有一个prototype属性,student()构造函数的prototype属性实际上就等于student对象的__proto__属性。
下面用一张图来说明:
因此,构造函数的prototype属性就等于实例对象的__proto__属性,构造函数的prototype属性被称为显式原型,实例对象的__proto__属性被称为隐式原型。
二、原型链
原型链:当访问一个对象的属性或方法时,首先对象会从自身去找,如果找不到,就会往原型中去找,即__proto__,也就是它构造函数的prototype中;如果原型中找不到,即构造函数中也没有该属性,因为构造函数也是对象,也有__proto__,就会往原型上去找,这样就形成了链式的结构,称为原型链,本质描述的是对象的一种继承关系。
再来看一个例子,创建一个person类,再创建一个teacher类继承自person类,并创建实例对象teacher:
class person { constructor(name) { this.name = name; } drink(){ console.log('喝水'); }}class teacher extends person { constructor(name, subject) { super(name); this.subject = subject; } teach() { console.log(`我是${this.name}, 教${this.subject}。`) }}const teacher = new teacher('哈默', '前端开发')console.log('teacher', teacher);teacher.teach();teacher.drink();
控制台输出如下,teacher可以执行teach()和drink()方法。
展开teacher对象,发现找不到这两个方法,于是去找对象的原型,即__proto__属性,找到teach()方法,再展开下一层__proto__属性,找到drink()方法。
下面用一张图说明:
可以看到,teacher实例对象本身是没有teach()方法的,这时就会去teacher对象的__proto__隐式原型指向的teacher.prototype显式原型上去找,此时找到了teach()方法并执行;同时,teacher.prototype上仍然没有找到drink()方法,而teacher.prototype也是一个对象,有自己的__proto__隐式原型,那么就去teacher.prototype.__proto__上去找,teacher.prototype.__proto__会指向person()构造函数的显式原型person.prototype,此时找到了drink()方法并执行,这就是原型链。
注:
(1)通过__proto__形成原型链而非protrotype。
(2)__proto__属性是对象所独有的。
(3)prototype属性是函数所独有的。但是由于js中函数也是一种对象,所以函数也拥有__proto__属性。
三、判断对象自身是否有某属性或方法
hasownproperty()方法会返回一个布尔值,用于判断对象自身是否有某属性或方法。返回true,代表是该对象自身的属性或方法;返回false,代表是该对象原型上的属性或方法。
由于person类继承自object类,那么执行teacher.hasownproperty()方法时,实际会找到object.prototype中的hasownproperty()方法并执行。
因此,所有继承了object的对象都会继承到hasownproperty方法。
同时可以看到,object.prototype.__proto__ 的值为 null ,即 object.prototype 没有原型,所以可以想象在原型链中,当找到顶层原型还没有属性时,那就是没有这个属性,返回返回undefined。
instanceof 运算符:用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。
看一个例子,使用typeof判断array的数据类型时,返回的是object,因此无法使用typeof判断array的类型。
const object = {};const array = [];// 使用typeof判断数据类型,array返回的是object console.log(typeof object); // objectconsole.log(typeof array); // object
下面使用instanceof运算符判断array的数据类型:
// 使用instanceof判断数据类型const flagobject = object instanceof array;const flagarray = array instanceof array;console.log(flagobject); // falseconsole.log(flagarray); // true
object instanceof array返回false,表示array.prototype不在object的原型链上;array instanceof array返回true,表示array.prototype在array的原型链上,由此可以区分object和array的数据类型。
也可通过控制台查看object和array的原型。
注:[] instanceof object 为 true
以上就是js原型和原型链是什么的详细内容。
其它类似信息

推荐信息