原型
原型,prototype,中文含义:模具,表示以此为起点,可以生成功能一致的产品。例如:武器设备的原型机;小说中的原型人物。
js中的原型指的是构造函数上的prototype属性。它是js中实现继承的基础。
js中的原型链是用来确认对象属性的查找机制。例如,当我们console.log(obj.p)时,如何在obj对象上找到a这个属性的值? 沿着原型链来找。
想要说明这个问题,先确定两个概念和一个关系
两个概念
- 原型
原型:构造器的prototype属性值
- 隐式原型
隐式原型: 对象的
__proto__属性值
一个关系
原型与隐式原型的关系
先直接给出结论:
对象.__proto__ === 构造器.prototype
用语言来表述是:对象的隐式原型等于 创建这个对象的构造器的原型 (把这句话读出来,念3遍)
用公式表达就是:
如果: 对象 = new 构造器()
那么: 对象.__proto__ === 构造器.prototype
原型链
原型链是用来确认对象属性的查找机制。例如,当我们console.log(obj.p)时,如何在obj对象上找到a这个属性的值? 沿着原型链来找。
寻找属性p的步骤如下:
(1)先在自有属性中找,如果找到,则返回;如果找不到,则进入到它的隐式原型中去找。
(2)由于对象的隐式原型也是一个对象(对象又是属性的集合),所以继续在obj.__proto__的自有属性中去找。找到则返回,找不到,则继续。
(3)在obj.__proto__这个对象的隐式原型中继续找。找到返回,找不到,则继续到obj.__proto__.__proto__中去找。
(4)直到__proto__为null 停止,返回undefined
上图中,红色的箭头标识的路径就是原型链。
原型链的应用
- vue2中,在Vue的原型上挂载eventBus,以便所有的组件实例都能访问
Vue.prototype.$eventBus = new Vue()
- es5中定义类时,将方法挂载在构造器的prototype上 打开,cdn.bootcdn.net/ajax/libs/v… , ctrl+f,prototype。就可以找到它们
- vue2中对数组元素响应式拦截
vue2中对数组元素响应式拦截时,就用到了Object.create(Array.prototype)的用法
var arrayProto = Array.prototype;
var arrayMethods = Object.create(arrayProto);
var methodsToPatch = [
'push',
'pop',
'shift',
'unshift',
'splice',
'sort',
'reverse'
];
/**
* Intercept mutating methods and emit events
*/
methodsToPatch.forEach(function (method) {
// cache original method
var original = arrayProto[method];
def(arrayMethods, method, function mutator () {
var args = [], len = arguments.length;
while ( len-- ) args[ len ] = arguments[ len ];
var result = original.apply(this, args);
var ob = this.__ob__;
var inserted;
switch (method) {
case 'push':
case 'unshift':
inserted = args;
break
case 'splice':
inserted = args.slice(2);
break
}
if (inserted) { ob.observeArray(inserted); }
// notify change
ob.dep.notify();
return result
});
});
- 判断数据类型时,使用Object的原型上的toString方法
Object.prototype.toString.call([])