猛然发现太久没去复习了,于是复习了一些知识,顺便冒个泡。本次主要总结的知识点关于原型,再文章后半部分有原型相关的题,感兴趣的可直接观看。
一、原型
1.什么是原型
简单理解,原型就是一个对象,通过原型对象我们可以实现属性的继承。
当我们每次打印对象的时候其实也可以发现对象的原型[[prototype]];
在js的原型对象中,还包括constructor属性,这个属性对应的未创建所有指向该原型的实例的构造函数(即constructor指向的为构造函数);
在js的每个函数中都有一个prototype属性,当函数被作用为构造函数来创建实例时,这个函数的prototype属性值会被作为原型赋值给实例化对象(即构造函数会通过prototype将属性赋值给实例化对象);
任何一个对象都有__proto__属性,是一个指针,实例化对象的__proto__属性指向的是构造函数的原型;原型的__proto__属性指向Object的原型(这里需要注意:__proto__指针是具有兼容问题的,因此可以使用Object.getPrototypeOf()来指向Object的原型)
2.构造函数、实例化对象、原型三者的关系
1).任何一个函数都有prototype属性,是一个对象,称为原型
2).构造函数也是函数,也有prototype属性
3).实例化对象可以继承构造函数原型的属性和方法(构造函数的原型对象上的属性和方法都可以被实例化对象所继承)
4).任何一个对象都有constructor属性,实例化对象的constructor属性指向构造函数
5).原型也是对象,也有constructor属性,原型的constructor属性指向构造函数
6).任何一个对象都有__proto__属性,是一个指针,实例化对象的__proto__属性指向的是构造函数的原型;原型的__proto__属性指向Object的原型
示例图:
3.原型链
既然提到了原型就不得不提一下原型链:
在js中每个对象都有__proto__属性,当外面访问一个对象的属性时,如果这个对象内部不存在这个属性,那么就会去__proto__里去找这个属性,这个__proto__又会有自己的__proto__,于是就这样一直找下去,这就是原型链的概念;
原型链最终指向null
二、面试题
var o = (function () {var obj = {a: 1,b: 2}return {get: function (k) {return obj[k]}}})()// 如何在不改变上面代码的情况下// 修改 obj 对象
简单理解就是修改o中的obj,并且不去修改以上的代码,大家可以先思考一下。
|
|
|
|
|
三、解决方法
// 通过数据劫持,当我们获取Object原型中c属性的时候触发
Object.defineProperty(Object.prototype, 'c', {get() {return this}
})// 由于o中的obj并没有c属性,因此会通过原型接着寻找c属性,结果通过数据劫持会返回obj这个对象
o.get('c').a = 3// 此时我们打印会发现打印结果是我们所修改的结果
console.log(o.get('a'))