ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
# 原型模式 原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 这种模式是实现了一个原型接口,该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时,则采用这种模式。 > 形象描述 [https://www.cnblogs.com/fengyumeng/p/10646487.html](https://www.cnblogs.com/fengyumeng/p/10646487.html) ## **new** 的过程 ``` # 原始 function Person(name) { this.name = name } new Person('张三') # 普通函数 - 类比过程 objectFactory(Person, '张三') var objectFactory = function() { // 从Object.prototype上克隆一个空对象 var obj = new Object() // 取得外部传入的构造器,在此是Person var Constructor = [].shift.call( arguments ) // 指向正确的原型 obj.__proto__ = Constructor.prototype // 借用构造函数给obj设置属性 var ret = Constructor.apply(obj, arguments) return typeof ret === 'object' ? ret : obj } ```` ### `prototype` **只要创建了一个新函数,就会根据一组特定的规则为该函数创建一个`prototype`属性**,这个**属性**指向**函数**的**原型对象**,这个对象被所有实例所共享,存放一些共有属性或者方法; ``` Person.prototype ----> Person函数的原型对象 ``` > 在构造函数中,同一类相同的方法可以直接写在构造函数里,但这样每实例化一个对象都会产生一个新的该方法,但其实这个方法都是一样的,这样会浪费大量空间,另外,可以将相同的方法写在构造函数外,这样虽然解决了空间浪费问题,但在全局作用域设置变量污染了命名空间,也不安全。这时可以将相同的属性和方法放在原型对象中。 ### `Constructor` `constructor`属性**不影响**任何JavaScript的内部属性。 > constructor其实没有什么用处,只是JavaScript语言设计的历史遗留物。由于constructor属性是可以变更的,所以未必真的指向对象的构造函数,只是一个提示。不过,从编程习惯上,我们应该尽量让对象的constructor指向其构造函数,以维持这个惯例。 原型对象都会自动获得一个constructor属性,这个属性是一个指向prototype属性所在函数的指针。 ``` Person.prototype.constructor -----> Person函数 # 在特定的环境下,constructor也能起到一定作用 var a,b; (function(){ function A(arg1,arg2) { this.a = 1 this.b=2 } A.prototype.log = function () { console.log(this.a) } a = new A() b = new A() })() // 1 a.log() // 1 b.log() # 因为A在闭包里,所以现在我们是不能直接访问A的,那如果我想给类A增加新方法怎么办? // a.constructor.prototype 在chrome,firefox中可以通过 a.__proto__ 直接访问 a.constructor.prototype.log2 = function () { console.log(this.b) } // 2 a.log2() // 2 b.log2() ``` ### `__proto__` `__proto__`是指向本对象的原型对象的指针。可称为隐式原型,一个对象的隐式原型指向构造该对象的构造函数的原型,这也保证了实例能够访问在构造函数原型中定义的属性和方法。 ``` person.__proto__ --------> Person.prototype ``` ## 原型链变量查找机制 查找机制是这样的:**首先会先在实例上面搜索属性,如果找到了直接返回,否则就继续去原型上面寻找**。 > 图解指向 ![](https://img.kancloud.cn/5b/2b/5b2bdaccb8f7495d62193e95c1480750_518x245.png) > 原型链简图 ![](https://img.kancloud.cn/6c/60/6c60fcd0a8db3e7fa6a09fe690f9474f_604x497.png)