原型
定义
- JavaScript 只有一种结构:对象.
- 全称
原型对象
, 每个实例对象( object )都有一个私有属性(称之为__proto__
)指向它的构造函数的原型对象(prototype )
相关属性
prototype
: 构造函数属性, 指向构造函数对应的原型构造函数名.prototype === 构造函数对应的原型对象
__proto__
: 实例对象属性, 指向创建实例对象的构造函数对应的原型, 开发测试可以用, 但生产环境不推荐使用实例对象.__proto__ === 构造函数名.prototype
constructor
: 原型属性, 指向创建实例对象的构造函数原型对象.constructor === 构造函数名
原型链
定义
- 每个实例对象有原型对象(prototype )
- 该原型对象也有一个自己的原型对象(
__proto__
) - 层层向上直到一个对象的原型对象为 null
- 根据定义,null 没有原型,并作为这个原型链中的最后一个环节
相关属性
- instanceof
对象 instanceof 构造函数
: 判断构造函数的原型在不在该对象的原型链中var arr = [10,20,30]; //arr的原型链: arr -> Array.prototype -> Object.prototype -> null console.log(arr instanceof Array); //true console.log(arr instanceof Object); //true
完整原型链
- 以下为示例的构造函数, 内置构造函数也适用以下原型链描述
function Person(name , age ){ this.name = name; this.age = age; }
- 第一条 p1是对象
原型链: p1 -> Person.prototype -> Object.prototype -> nullvar p1 = new Person("小红",18) p1.__proto__ === Person.prototype // true p1.__proto__.__proto__ === Object.prototype // true p1.__proto__.__proto__.__proto__ === null // true
- 第二条 Person函数是对象
原型链: Person -> Function.prototype -> Object.prototype -> nullPerson = new Function(); // 构造函数为Function Person.__proto__ === Function.prototype // true Person.__proto__.__proto__ === Object.prototype // true Person.__proto__.__proto__.__proto__ === null // true
- 第三条链 O1是对象
原型链: O1 -> Object.prototype -> nullvar O1= new Object(); O1.__proto__ === Object.prototype // true O1.__proto__.__proto__ === null // true
- 第四条 Object是一个对象
原型链: Object -> Function.prototype -> Object.prototype -> null// 构造函数为Function Object.__proto__ === Function.prototype // true Object.__proto__.__proto__ === Object.prototype // true Object.__proto__.__proto__.__proto__ === null // true
- 第五条 Function是一个对象, Function 实例化自身
Function.__proto__ === Function.prototype // true Function.__proto__.__proto__ === Object.prototype // true Function.__proto__.__proto__.__proto__ === null // true
- 第六条链 Person.prototype 是一个对象
//Object实例化Person.prototype Person.prototype.__proto__ === Object.prototype // true Person.prototype.__proto__.__proto__ === null // true
- 第七条 Function.prototype 是一个对象
//Object实例化Function.prototype Function.prototype.__proto__ === Object.prototype // true Function.prototype.__proto__.__proto__ === null // true
原型链图
注: 第六条和第七条原型链未画出来, 读者自行脑补
Object.project
- 原型链最终都流经
Object.prototype -> null
- js中所有的对象都可以访问Object.prototype的成员
- 成员
3.1 hasOwnProperty
对象名.hasOwnProperty("属性名")
: 判断该属性名是否为该对象的自身属性, 而不是其原型链上的某个属性
3.1.1 解决的问题
在原型链上查找属性比较耗时, 对性能有副作用, 同时试图访问不存在的属性时会遍历整个原型链. 遍历对象的属性时, 原型链上的每个可枚举属性都会被枚举出来. hasOwnProperty可实现只遍历自身属性.
3.1.2 补充
另一个处理自身属性并且不会遍历原型链的方法为Object.keys()
3.2 isPrototypeOf
判断一个对象是否是另外一个对象的原型.
3.3 propertyIsEnumerablevar obj1 = {} var obj2 = {} obj2.__proto__ = obj1 obj1.isPrototypeOf(obj2) //true
判断属性能够被遍历, 并判断这个属性是否是自己的function Person(name){ this.name = name; } Person.prototype.type = "人类" var p1 = new Person('小红') p1.propertyIsEnumerable("name") //true p1.propertyIsEnumerable("type") //false