原型和原型链
原型链
概述:
原型链是 JavaScript 实现继承的方式。
原型:
function Person() {
this.name = 'Tomy';
}
const man = new Person();
man.name; //"Tomy"
man.__proto__ === Person.prototype; //true
Person.prototype.constructor === Person; //true
如上段代码演示,
man是由构造函数Person所生成的实例。
实例man的隐式原型__proto__指向构造函数Person的显式原型prototype。
而原型prototype的constructor又指向本构造函数Person。
function Person() {
this.name = 'Tomy';
}
function Worker() {
this.salary = 1000;
}
const man = new Worker();
man.salary; //1000
man.name; //undefined
// 挂载原型
const people = new Person();
man.__proto__ = people;
man.name; //"Tomy"
man.hasOwnProperty('salary'); //true
man.hasOwnProperty('name'); //false
由
Worker生成的实例man只有salary属性存在。
当man的__proto__挂载到people之后便能访问到name属性。
原因在于:当 js 对象没有该属性时,会在其所在的原型链上寻找相应原型的属性,直到找到或到达顶层原型(Object的prototype为null)。
new 关键字
由于 JavaScript 通过原型链的实现方式,
new关键字的作用不仅在于创建新的对象,同时也实现原型的继承。
function Person() {
this.name = 'Tomy';
this.setName = function(name) {
this.name = name;
};
}
function createInstance(fn) {
const relt = {};
relt.__proto__ = fn.prototype;
fn.call(relt);
return relt;
}
const instance = createInstance(Person);
instance.name; //"Tomy"
instance.setName('Jack');
instance.name; //"Jack"
new关键字的作用就类似于上段代码中的createInstance。
class 、 extends 、 super
class是ES6新出现的语法,其创建实例的方式依旧是原型链。
class Person {
constructor() {
this.name = 'Tomy';
}
work(){
return 'job'
}
}
class Worker extends Person {
constructor() {
super()
this.salary = 1000;
}
draw(){
return '领取' + this.salary
}
}
const man = new Worker();
man.name; //"Tomy"
man.work(); //"job"
man.salary; //1000
man.draw(); //"领取1000"
man.hasOwnProperty('salary'); //true
man.hasOwnProperty('name'); //true
man.hasOwnProperty('work'); //false
man.hasOwnProperty('draw'); //false
man.__proto__ === Worker.prototype; //true
man.__proto__.hasOwnProperty('draw'); //true
man.__proto__.hasOwnProperty('work'); //false
man.__proto__.__proto__ === Person.prototype; //true
man.__proto__.__proto__.hasOwnProperty('work'); //true
如上演示,
class中函数的this均指向了实例本身。
class中的函数挂载在prototype上,而并不挂载在实例上。
若继承的父类class存在constructor,则子类class必须调用super()使实例上也有父类的属性。
Function
Function与Array、Number、Date等同样是继承于Object。
不同的是其余构建函数都返回一个实例,而Function返回动态函数。
Function.prototype.__proto__.constructor === Object //true
const fn = new Function('arg1','arg2','arg3','return arg1 + arg2 + arg3')
fn //ƒ anonymous(arg1,arg2,arg3) {return arg1 + arg2 + arg3}
typeof fn //'function'
fn.a = 1
fn.a //1
Function的优点在于可以创建动态函数,但其性能比传统直接定义的方式开销大。
instanceof 关键字
class Person {}
class Worker extends Person {}
const man = new Worker()
man instanceof Worker //true
man instanceof Person //true
man instanceof Object //true
man instanceof Array //false
当构建函数在其原型链上即返回
true。
function isExtendsOf(Fn){
let proto = this.__proto__;
do{
if(proto.constructor === Fn){
return true
}
proto = proto.__proto__
}while(proto)
return false
}
class Person {}
class Worker extends Person {}
const man = new Worker()
isExtendsOf.call(man,Worker) //true
isExtendsOf.call(man,Person) //true
isExtendsOf.call(man,Array) //false
instanceof类似于如上代码中的isExtendsOf。

浙公网安备 33010602011771号