# 原型模式
原型模式(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)
- 版本控制之Git简介
- Git工作流程
- Git工作区、暂存区、版本库
- Git 指令汇总
- Git 忽略文件规则 .gitignore
- pull request
- HTTP简介
- HTTP - Keep-Alive
- HTTP缓存
- XMLHttpRequest
- Fetch
- 跨域
- HTTP 消息头
- TCP/IP
- TCP首部
- IP首部
- IP 协议
- TCP/IP漫画
- 前端开发规范
- 前端开发规范整理
- 前端未来规划
- HTML思维导图
- CSS思维导图
- 布局
- position,float,display的关系和优先级
- line-height、height、font-size
- 移动端适配
- JS 对象
- JS 原型模式 - 创建对象
- JS 预编译
- 探索JS引擎
- ES