原型、原型链的认识
函数的定义:
构造函数与普通函数唯一的区别就是调用方式不同:任何函数只要使用new操作符调用就是构造函数,而不是用new操作符调用的函数就是普通函数。
原型:每个函数都会创建一个prototype属性,它指向一个对象(原型),包含特定引用类型的实例共享的属性和方法。通过构造函数创造的对象的原型就是该构造函数的prototype(原型)对象.
- 构造函数原型对象默认会获得一个constructor属性,这个constructor属性指向或者说引用其构造函数,除此之外,其余所有方法都继承Object。
- 每次调用构造函数创建新的实例对象时,这个新的实例对象内部的prototype属性(指针)都会赋值为(指向)创建它的构造函数的原型对象。
ps:在firefox、safari、和chrome浏览器会在每个对象中暴露出__proto__属性(可称为隐式原型),这个属性访问其所在对象的原型。
在一般情况下某个实例对象的__proto__可视为链接到该对象构造函数的原型对象。
例
1 function Person(name, age, job) { 2 this.name = name; 3 this.age = age; 4 this.job = job; 5 this.introduce = function () { 6 console.log(`我是${name},我${age}岁`); 7 }; 8 } 9 let person1 = new Person("徐凤年", "22", "世子殿下"); 10 let person2 = new Person("温华", "22", "游侠"); 11 person1.introduce();//我是徐凤年,我22岁 12 13 console.log(Person.prototype); 14 console.log(person1); 15 16 console.log(person1.prototype !== Person); //true 17 console.log(person1.__proto__ === Person.prototype); //true 18 console.log(Person.prototype.constructor === Person); //true 19 console.log(Person.prototype !== Person); //true 20 console.log(person1.prototype === person2.prototype); //true 21 console.log(Person.prototype.__proto__ == Object.prototype);//true
- 构造函数Person的prototype引用其原型对象,其原型对象是中存在constructor属性指向(引用)该构造函数本身,是循环引用。
- 构造函数、构造函数的原型对象prototype、以及构造函数实例化的对象是三个完全不同的对象。
- 通过构造函数创建的实例对象person1的隐式原型__proto__是指向其构造函数Person的原型prototype。
- 通过同一构造函数实例化出来的俩个对象的原型对象是同一个对象。
- 构造函数Person的原型对象prototype的隐式原型对象__proto__指向object的原型对象prototype。
- 正常的原型链都会终止于object.prototype.这个object.prototype.__proto__则为null
- 调用一个对象的属性或方法首先在对象实例上查找,若是有则返回实例的属性或方法(会覆盖原型上的同名属性方法),然后会往原型对象上找,以此类推,再往这个原型对象的原型对象上找,这就是原型链。js中继承功能就是通过原型这一功能实现,包括class继承。