可以将原型理解为对象的父亲,对象从原型对象继承属性。
1.所有函数的原型默认是 Object的实例,所以可以使用toString/toValues/isPrototypeOf 等方法的原因。


2.我们也可以创建一个极简对象(纯数据字典对象)没有原型(原型为null)

3.函数拥有多个原型,prototype 用于实例对象使用,__proto__用于函数对象使用


4.使用Object.setPrototypeOf 可设置对象的原型。使用Object.getPrototypeOf 用于获取一个对象的原型。

5.原型检测
一、instanceof 检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。
二、使用isPrototypeOf检测一个对象是否是另一个对象的原型链中,b.isPrototype(a)。
三、使用in 检测原型链上是否存在属性(“name” in a),使用 hasOwnProperty 只检测当前对象(a.hasOwnPrototype("name"))。
6.除了使用Object.setPrototypeOf(a,b)让a继承b的原型,从而使用b拥有的方法。使用call和apply借助其他原型方法来完成功能。

也就是说我们可以通过这种方式直接借用String/Number/Math/RegExp/Date等系统方法了。

7.使用Object.getPorotypeOf获得对象的原型,而constructor存在于prototype原型中,用于指向构建函数的引用。


8.给我一个对象,还你整个世界。通过一个对象可以找到原型(Object.getPorotype()),通过原型的constructor能够找到构造函数,通过构造函数就可以创建一个对象。

根据上面讲到的__proto__ 我们来分析下,首先obj是没有constructor 这个属性的,但是 obj.__proto__ = a.prototype;就从a.prototype中寻找,而 a.prototype.constructor 是就a,所有两者的结果是一一样的.

通俗的讲,就是为了将实例的构造器的原型对象暴露出来, 比如你写了一个插件,别人得到的都是你实例化后的对象, 如果别人想扩展下对象,就可以用 instance.constructor.prototype 去修改或扩展原型对象。
9.使用Object.create创建一个新对象时使用现有对象做为新对象的原型对象。在实例化对象上存在 __proto__ 记录了原型,所以可以通过对象访问到原型的属性或方法。修改对象的__proto__只语序是对象或者是null


10.使用Object.create()实现继承会影响对象constructor 。
如:Admin.prototype = Object.create(User.prototype);需要设置Admin.prototype.constructor = Admin;确保constructor属性存在。这使这个属性变成了可遍历的,所以使用Object.defineProperty(Admin.prototype,"constructor",{ value:Admin,enumerale:false})就不可以遍历了。可以将这两行代码封装成一个方法,减少重复书写类似代码。
11.javascript脚本语言不支持多继承,如果要使用多个类的方法时可以使用mixin混合模式来完成。
网友评论