函数的定义方式:
    1、函数声明方式function关键字();
    2、函数表达式(匿名函数);
    3、new Function()
    this的指向是当调用函数的时候确定的。调用方式的不同决定了this的指向不同。一般指向调用者。

    函数的调用方式:
    1.普通函数(window);
    2.对象的方法(该方法所属对象);
    3.构造函数(实例对象 原型对象里面的方法也指向实例对象);
    4.绑定事件函数(绑定事件对象);
    5.定时器函数(window);
    6.立即执行函数(window)

    改变函数内部this指向:bind()、call()、apply()
    .call()简单理解为调用函数的方式,可以改变函数的this指向。主要作用可以实现继承
    .apply()方法调用一个函数。简单理解为调用函数的方式,可以改变函数的this指向。参数必须是数组(伪数组)。
    .bind()不会调用函数。但是能改变函数内部this指向。返回由指定的this值和初始化参数改造的原函数拷贝(返回的是原函数改变this之后产生的新函数)。
    相同点:都可以改变函数内部的this指向
    区别:
    1、call和apply会调用函数,并且改变函数内部this指向。
    2、传递的参数不一样,call传递参数aru1,aru2的形式,apply必须数组形式[arg]。
    3、bind不会调用函数,可以改变函数内部this指向

    主要应用场景:
    1、call经常做继承。
    2、apply经常跟数组有关系。
    3、bind不调用函数,但是还想改变this指向。比如改变定时器内部的this指向。

    ES6之前并没有提供extends继承。我们可以通过构造函数+原型对象模拟实现继承,被称为组合继承
    核心原理:通过call()把父类型的this指向子类型的this,这样就可以实现子类型继承父类型的属性。
    ES5中新增数组方法:迭代(遍历)方法:forEach()、map()、filter()、some()、every();字符串方法:trim()方法从字符串两端删除空白字符。并不影响原字符串本身,返回的是一个新的字符串。
    对象方法:Object.defineProperty()定义对象中新属性或修改原有属性。

    Object.keys()用于获取对象自身所有的属性。 返回一个数组,数组值为对象自有的属性,不会包括继承原型的属性
    for…in 遍历对象可枚举属性,包括自身属性,以及继承自原型的属性