一、原型 ( prototype )
//构造函数 constructor:类似现实生活中的模具,图纸,模板
//Prototype 原型:类似于女娲,只有函数才拥有prototype属性
function Animal(name) {
this.name = name
this.eat = function(){
console.log('I like to eat');
}
}
//如果把方法挂载到原型上面,这样就可以让使用该对象的实例共享这个方法,不会每个都创建新的方法,不会造成资源的浪费
Animal.prototype.run = function(){
console.log('I can run');
}
var dog = new Animal('🐕')
var pig= new Animal('🐖')
console.log(dog.eat());
console.log(pig.eat());
console.log(dog.eat === pig.eat); //false
console.log(dog.run());
console.log(pig.run());
console.log(dog.run === pig.run);//true
//原型属性prototype是一个普通对象
//内部属性[[prototype]] 是一个隐藏属性
function Person(){
console.log(Person.prototype.constructor === Person); //true
}
二、隐式原型 ( .proto)
//隐士原型:__proto__这个属性是浏览器实现得给实例对象使用得一个属性,可以用来访问该对象的原型对象prototype。
function Person(){}
var p1 = new Person()
console.log(Person.prototype);
console.log(p1.__proto__);
console.log(Person.prototype === p1.__proto__);//true
三、原型链(Object prototype)
function Person(name) {
this.name = name
}
Person.prototype.name = '女娲'
var p1 = new Person('亚当')
// // console.log(p1.prototype);//undefined
// console.log(p1.__proto__.name);
//自定义构造函数的原型链
function Person() { }
Person.prototype.__proto__.__proto__//null
//对象字面量的原型链
var o = {}
o.__proto__.__proto__//null
//内置对象构造函数的原型链
var obj = new Object()
obj.__proto__.__proto__//null
//函数构造函数的原型链
var f = new Function()
f.__proto__.__proto__.__proto__ //null
console.log(f.__proto__.__proto__.__proto__);
console.log(f.prototype.__proto__.__proto__);
代码对相应的小三角形(图片)
完整的原型链
原型链概念:
//1.利用new关键字实例化构造函数创建一个实例对象
//2.每个实例对象有一个__proto__(隐士原型)指向的是构造函数的prototype(原型对象)
//3.每个构造函数原型对象有一个constructor属性,该属性指向构造函数的对象。
//4.这个原型对象本身也是一个对象,也有自己的原型prototype,这个原型还是对象,所以它也有自己的prototype。
//5.最后找到的是Object的原型对象,如果再往上就是null。
//6.我们在项目中如果要读取对象的某个属性会先从它本身去找,没找到会从对象身上找,再没找到会从原型对象的原型对象上找,直接最后找到的null
//7.这种形式类似于链条的形式,所以称为原型链
//Object 内置对象
var o = new Object()
console.log(o.__proto__ === Object.prototype) //true
console.log(Object.prototype.constructor === Object); //true 原型上有一个constructor
//Person自定义对象
function Person() { }
var p = new Person();
console.log(p.__proto__ === Person.prototype);//true
console.log(Person.prototype.constructor === Person);//true
//Function 特殊对象(也可以作为构造函数使用) 自己是自己的实例
//注意:在js中所有的函数(构造函数)都属于Function的实例
var f = new Function()
console.dir(f.__proto__);
console.log(f.prototype);
console.log(f.__proto__ === f.prototype); //false
console.log(f.prototype.constructor === f);//true
console.log(f.prototype.constructor === Function);//false
//---------------------上面是三个对象的小原型链--------------------------
//Function 的原型对象__proto__指向是Object.prototype的其中一个实例
console.log(Function.prototype.__proto__ === Object.prototype);
console.log(Function.__proto__.__proto__ === Object.prototype);
//Person的原型对象.__proto__指向的是对象的原型对象
console.log(Person.prototype.__proto__ === Object.prototype);//true
// 所有的(构造)函数都是Function的一个实例
console.log(Object.__proto__ === Function.prototype);//true
console.log(Person.__proto__ === Function.prototype);//true
//Function的原型对象指向Object的对象
console.log(Function.prototype.__proto__ ===Object.prototype);//true
//Object的原型对象__proto__属性指向的是null
console.log(Object.prototype.__proto__); //null
console.log(Function.prototype.constructor === Function);
完整原型链图(图片)