# 20191221

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

* 原型的作用
  1. 数据共享
  2. 节省内存
* 实现继承 ----> 数据共享
* 通过原型进行继承
* 缺陷：因为改变原型指向实现继承，必须同时进行初始化赋值，所以导致属性重复，如果想改变属性，只有通过调用对象属性重新赋值
```js
function Person(name) {
  this.name = name
}
Person.prototype.eat = function() {
  console.log('真好吃')
}
// 创建学生对象
function Student(score) {
  this.score = score
}
Student.prototype = new Person('张三')
Student.prototype.play = function() {
  console.log('每天都在写代码')
}
var st1 = new Student(100)
console.log(st1.name)
console.log(st1.eat)
console.log(st1.play)
```

## 组合继承
* 改变原型对象的指向但是不进行初始化
* 解决了属性重复赋值，共享方法
```js
function Student(name, score) {
  Person.call(this.name)
  this.score = score
}
Student.prototype = new Person() // 不传参数
Student.prototype.play = function() {
  console.log('考试真是太有意思了')
}
var str1 = new Student('张三',100)
console.log(st1.name, st1.score)
```

## 拷贝继承
```js
// 字面量创建对象
var obj1 = {
  name: '张三',
  age: 18,
  eat: function() {
    console.log('午饭没吃')
  }
}

// 改变了指向，对象之间传值，其实是改变了引用，也叫指针
var obj2 = obj1
console.log(obj2.name)

var obj2 = {}
for(var key in obj1) {
  obj2[key] = obj1[key]
}

function Person() {

}
Person.prototype.name = '李四'
Person.prototype.age = 18
Person.prototype.eat = function() {
  console.log('eat')
}
for( var key in Person.prototype) {
  obj3[key] = Person.prototype[key]
}
console.log(p.name)
```

## 函数的声明
* 推荐使用函数表达式，函数声明在嵌套表达式中在ie8中会出现问题（后边覆盖前面的）
```js
var fn = function() {}
var fn = () => {}
```
## this指向
* 普通函数的this指向window
* 严格模式下，普通函数this指向调用者
* 对象方法的this指向 实例对象
* 定时器this指向 window
* 构造函数this指向 实例对象
* 原型方法的this指向 实例对象

## 

* 对象中有__proto__ 
* 函数中有prototype 也是对象
* 函数中有prototype 对象也有__proto__ 是一个实例对象
* 任何函数都是Function的实例对象
