概述
原型是什么
在 JavaScript 中,函数是一个 包含属性和方法的 Function 类型的对象。而原型 ( Prototype ) 就是 Function 类型对象的一 个属性。
在函数定义时就包含了prototype属性,它的初始值是一个空对象。 在 JavaScript 中并没有定义函数的原型类型,所以原型可以是任何类型。
用于保护对象的共享属性和方法的,原型的属性和方法并不影响函数本身的属性和方法
获取原型
- 通过构造函数的
prototype
属性。 - 通过
Object
对象的getPrototypeOf(obj)
方法
原型的属性和方法
设置原型的属性和方法:
-
原型的属性和方法单独进行定义
构造函数.protitype.属性名 = 属性值; 构造函数.protitype.方法名 = function(){}
-
直接为原型定义一个新对象
构造函数.prototype = { 属性名:属性值, 方法名:function(){} }
构造函数的原型
原型属性
自有属性与原型属性
- 自有属性:通过对象的引用添加的属性。其他对象可能无此属性;即使有,也是彼此独立的属性。
- 原型属性:从原型对象中继承来的属性,一旦原型对象中属性值改变,所有继承自该原型的对象属性均改变。
检测自有属性与原型属性
-
使用hasOwnProperty()方法检测对象是否具有指定的自有属性
function Hero(){} var hero = new Hero(); console.log(hero.hasOwnProperty('name'));
-
使用in关键字检测对象及其原型链中是否有指定属性
function Hero(){} var hero = new Hero(); console.log('name' in hero);
扩展属性或方法
通过原型可以为指定构造函数或对象扩展器属性或方法,如下所示:
function Hero(){}
Hero.prototype = {
name : 'Mary',
salary : 3000
}
var hero = new Hero();
console.log(hero.name); // Mary
操作原型的方式
__proto__
属性
如下代码,说明hero
对象存在一个指向构造函数Hero的原型,可以称这个链接叫做__proto__
属性。
function Hero(){}
Hero.prototype.age = 18;
var hero = new Hero();
console.log(hero.name); // 对象调用自有属性
console.log(hero.age); // 对象调用原型属性
console.log(hero.prototype); // undefined 表示对象不存在该属性
console.log(hero.__proto__); // { age: 18 }
区分
- 将函数的原型 -> 显示原型
- 将对象的原型 -> 隐式原型
注意:
- 对象的原型(
__proto__
)并非是函数的原型(prototype
),__proto__
属性与prototype
属性并不等价。 - 对象的原型(
__proto__
)属性只能在调试时使用。 __proto__
属性是指定对象的属性prototype
属性是指定构造函数的属性
重写原型属性
- 通过构造函数或对象的自有属性可以重写原型的属性
- 自有属性与原型属性同名时,默认访问的是自有属性 -> 自有属性的优先级别高于原型属性
删除属性
function Hero(){
this.name = '李玉刚';
}
//删除对象的属性
delete hero.name;
isPrototypeOf()
方法
每个对象都会具有一个isPrototypeOf()
方法,该方法用来判断一个对象是否是另一个对象的原型。
通过初始化器方式定义对象
var obj = { name:'李玉刚' }
定义构造函数
function Hero(){}
将对象obj赋值给构造函数Hero的原型
Hero.prototype = obj;
通过构造函数创建对象
var hero = new Hero();
判断指定对象是否是另一个对象的原型
var result = obj.isPrototypeOf(hero); //true // var result = hero.isPrototypeOf(obj); // false console.log(result);
扩展内建对象
JavaScript 中的内置对象有些也具有 prototype
属性,利用内置对象的 pretotype
属性可以为内置对象扩展属性或方法。
通过原型扩展内置对象的属性和方法非常灵活,根据个性化要求制定 JavaScript 语言的具体内容。
一般建议慎用这种方式,如果 JavaScript 的版本更新时可能会提供个性化的属性或方法,导致冲突。