prototype翻译过来叫做原型,每一个构造函数都有一个prototype,并且prototype是一个对象,里面有两条属性:constructor和__proto__。
Nice.prototype {
constructor: ƒ Nice(),
__proto__: Object
}
其中,“constructor” 叫做构造器,返回的是构造这个对象的构造函数,也就是Nice()本身。
"__proto__"是一个内置属性,每一个对象里都有__proto__,该属性指向创建它的构造函数的原型对象prototype,最终指向的是Object,Object里内置了一些方法和属性。
原型的概念基本理清,下面开始看prototype的用法。这里是一个最简单的用法,在构造函数原型里定义属性,从而使它的实例化对象都能继承。
Person.prototype.name = "hehe"; //在Person原型中定义了属性
function Person(){
}
var person = new Person();
console.log(person.name)
-----------------------------------------
"hehe"
在构造函数Person的prototype中添加了name属性,那么通过Person,实例化一个对象,它就自带了name属性。
prototype,一般是将公有的属性放到原型里,从而不用每创建一个对象都要赋值一遍,造成冗余。
Car.prototype.height = 1400;
Car.prototype.long = 4900;
Car.prototype.carName = "BMW";
/*
可以这样写:
Car.prototype = {
height = 1400,
long = 4900,
carName = "BMW"
}
*/
function Car(color,owner) {
this.owner = owner;
this.color = color;
this.drive = function() {
console.log('driving')
}
}
var car = new Car('red','zc');
var car = new Car('white','ln');
console.log(car1.height);
-----------------------------------
1400
实例化的对象都继承了构造函数的原型属性,可以直接调用。
增加属性
Person.prototype.LastName = '张';
function Person(name) {
this.name = name;
}
var person = new Person('徐明');
查找属性
console.log(person.LastName)
----------------------------------------
"张"
修改属性
Person.prototype.LastName = '曾';
删除属性
delete Person.prototype.LastName
这时候再通过new实例化一个新对象时,将继承不到LastName属性,无法调用。
JavaScript的原型链有些类似于python的继承类,最终都是指向的Object。每个实例化对象,内部都有个__proto__属性,指向的是构造函数的原型prototype。
Grand.prototype.name = "Deng";
function Grand (){
this.height = 180;
}
var grand = new Grand();
Father.prototype = grand; //继承了grand的原型
function Father (){
this.name = "xiaoming";
this.num = 100;
}
var father = new Father();
Son.prototype = father; //继承了father的原型
function Son() {
this.hobbit = "smoke";
}
var son = new Son();
grand >father >son,原型连成一条链,有着和作用域一样的查找模式,子集没有的属性就向上往父级身上去查找。
son.__proto__ === Son.prototype
Son.prototype === father
father.__proto__ === Father.prototype
Father.prototype === grand
grand.__proto__ === Grand.prototype
Grand.prototype.__proto__ === Object.prototype