# 20191123

![js](https://img.shields.io/badge/language-js-orange.svg)

js 高级

```js
function Person(name, age) {
  this.name = name
  this.age = age
  this.sayHi = () => {
    console.log('你好')
  }
}
// 实例化对象，并进行初始化
let pwr = new Person('张三', 18)
```
通过原型解决构造函数的缺点

原型的作用：数据共享，节省内存

既是属性，又是对象
```js
Person.prototype.sayHi = function(){}
...
per1.sayHi == per2.sayHi   // =>  true
```

示例对象中有一个属性是`__proto__`也是一个对象,也叫原型对象，是提供给浏览器使用的，不是标准的对象，我们可以在一定情况下使用

构造函数中有一个属性prototype，也是一个对象，也叫原型对象，是标准的提供给程序员使用

实例对象是通过构造函数创建的

构造函数 => Person + prototype属性(指向原型对象)

原型对象 => constructor构造器(指向Person) + sayHi()

实例对象 => name + age(先用构造函数创建) + __proto__属性(指向的是该构造函数的原型对象即构造函数的prototype属性)

面向对象编程示例

```js
// 更新div的颜色
function ChangeBg(btnId, divId, color){
  this.btnId = document.getElementById(btnId)
  this.divId = document.getElementById(divId)
  this.color = color
}
ChangeBg.prototype.init = () => {
  // this 与 that 之争
  let that = this
  this.btnId.onclick = function() {
    that.divId.style.background = that.color
  }
}

// 实例化并初始化
let cb = new ChangeBg()
cb.init()
```

```js
// 第二版
// 按钮，div。color都是对象
function ChangeBg(btnObj, dvObj, json) {
  this.btn = btnObj
  this.dv = dvObj
  this.json = json
}

ChangeBg.prototype.init = () =>{
  let that = this
  this.btn.onclick = function() {
    for(let key in tht.json) {
      that.dv.style[key] = that.json[key]
    }
  }
}
// 实例化
btnObj = document.getElementById(btnId)
divObj = document.getElementById(divId)
json = {...}
let cb = new ChangeBg(btnObj, divObj, json)
```

什么的数据需要写在原型中？

需要共享的数据写在原型中

需要共享的属性，需要共享的方法，都可以写在原型中

原型作用：共享数据，节省内存

不需要共享的数据，不需要共享属性，不需要共享方法，写在构造函数中

```js
function Person(name, age, sex) {
  this.name = name
  this.age = age
  this.sex = sex
}

// 人的身高都是200
Person.prototype.height = '200cm'
// 人的体重都是250kg
Person.prototype.width = '250KG'
// 人都爱写代码
Person.prototype.coding = function(){
  console.log('今天每个人都要写完20000行代码，不写完不准睡觉')
}
// 人都爱吃鱼
Person.prototype.eat = function() {
  console.log('人人都爱吃鱼')
}

// 以上等同于，这种写法会丢失构造器，原型对象的构造器容易被重写
Person.prototype = {
  // 防止构造器被重写
  constructor: Person,
  ...
}

let per = new Person('yingbo', 1, 'niko')
console.dir(per)
console.dir(Person)
```

属性的搜索机制

实例对象的属性或者方法，先在实例对象中查找，在向实例对象中的原型对象中查找

实例对象中的方法可以相互调用

原型对象中的方法可以相互访问

四大内置对象

String

Array

Date

Math

内置对象中可以添加原型方法