什么是原型?
在JS中我们每创建一个函数都有一个 prototype(原型)属性,这个属性是一个指针,指向函数的原型对象。所有原型对象都会自动获得一个 constructor(构造函数)属性,这个属性包含一个指向 prototype 属性所在函数的指针。
function Person(){
}
Person.prototype.name = "李白";
Person.prototype 指向了原型对象,而 Person.prototype.constructor 又指回了 Person。
prototype属性存在于构造函数(函数里面都有)中指向构造函数的原型对象。
constructor属性存在于原型对象中,指向构造函数
什么是原型链?
每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针。当把原型对象等于另一个类型的实例,此时的原型对象将包含一个指向另一个原型的指针,相应地,另一个原型中也包含着一个指向另一个构造函数的指针。假如另一个原型又是另一个类型的实例,那么上述关系依然成立,如此层层递进,就构成了实例与原型的链条。这就是所谓原型链的基本概念。
function Person1(){
this.Person1Name= '李白';
}
Person1.prototype.getPerson1Name = function(){
return this.Person1Name;
};
function Person2(){
this.Person2Name= "虞姬";
}
Person2.prototype = new Person1(); //继承了Person1属性和方法
Person2.prototype.getPerson2Name = function (){
return this.Person1Name;
};
var Person= new Person2();
console.log(Person.Person1Name); //李白
console.log(Person.Person2Name); //虞姬
console.log(Person.getPerson1Name()); //李白
console.log(Person.getPerson2Name()); //李白
console.log(Person2.prototype.constructor);//function Person1()
console.log(Person.constructor);//function Person1()
console.log(Person2.prototype.__proto__===Person1.prototype);//true
console.log(Person2.__proto__)//function ()
Person2继承了 Person1的属性和方法,而继承是通过创建 Person1 的实例,并将该实例赋给Person2.prototype 实现的。实现的本质是重写原型对象,原来存在于 Person1的实例中的所有属性和方法,现在也存在于 Person2.prototype 中了。给 Person2.prototype 添加了一个方法,这样就在继承了 Person1的属性和方法的基础上又添加了一个新方法。Person2.prototype指向Person2的原型对象,Person2的原型对象指针指向Person1的原型对象,所以Person2.prototype.constructor指向Person1,Person.constructor指向同理也是指向Person1
当调用构造函数创建一个新实例后,该实例的内部将包含一个指针(内部属性),指向构造函数的原型对象。ECMA-262 第 5 版中管这个指针叫[[Prototype]]。可以通过__proto__
给这个内部属性赋值或者查找上级原型对象。
在创建对象的时候会自动创建一个__proto__
属性或者说[[Prototype]],指向它构造函数的prototype,当访问这个对象的属性的时候会顺带访问__proto__
中对应的属性,也就是构造函数prototype这样实现了继承。
实例化的对象没有prototype属性,prototype是构造器/函数才具有的属性
Person是 Person2的一个实例,不是一个函数,所以没有prototype属性;Person2是Function的一个实例,而Function是一个函数,他的实例Person2也是一个函数,所以他们都有prototype。
console.log(typeof Person)//object
console.log(typeof Person2)//function
console.log(Person instanceof Object)//true
console.log(Person2 instanceof Function)//true
JavaScript内置的构造器有Object,Number,Boolean,String,Array,RegExp,Date,Function,Error,Math,JSON等,其中Math和JSON是以对象形式存在的,无需new便可创建。
Object,Number,Boolean,String,Array,RegExp,Date,Function,Error的原型是Function.prototype。
Math和JSON对象的原型是Object.prototype。
let myArray = [Object, Number, Boolean, String, Array, RegExp, Date, Function, Error, Math, JSON],
functionArr = [],
objectArr = [];
myArray.filter(el => {
if(el.__proto__ === Function.prototype) {
functionArr.push(el)
}
if(el.__proto__ === Object.prototype) {
objectArr.push(el)
}
})
console.log(functionArr)
console.log(objectArr)