apply
概念
概念:方法调用一个具有给定this值的函数,以及以一个数组(或类数组对象)的形式提供的参数。 语法:function.call(thisArg, [argsArray]) 参数: thisArg:可选的。一个数组或者类数组对象,其中的数组元素将作为单独的参数传给 func 函数。如果该参数的值为 null 或 undefined,则表示不需要传入任何参数。从ECMAScript 5 开始可以使用类数组对象。 返回值:使用调用者提供的 this 值和参数调用该函数的返回值。若该方法没有返回值,则返回 undefined。
原理
分析: 他们改变的this指向的原理:
- 其实就是通过在 某个对象上添加这样一个方法,
 - 然后拿到参数,
 - 再去调用这个对象的这个方法(符合this指向调用者。) 。
 - 得到结果后,再在这个对象上删去这个属性方法。
 - 
实现
call
 首先 context 为可选参数,
- 如果不传的话默认上下文为 window 接下来给 context 创建一个 fn 属性,并将值设置为需要调用的函数
 - 因为 apply 传参是数组传参,所以取得数组,将其剥离为顺序参数进行函数调用
 - 然后调用函数并将对象上的函数删除
 
function Animal(name,color){this.name = name||'动物';this.color = color||'颜色';this.say=function(){console.log(`Animal:${this.name},${this.color}`)}}function Dog(name,color){Animal.apply(this,[name,color]);this.say=function(){console.log(`Dog:${this.name},${this.color}`)}}let newDog = new Dog('小狗','棕色');let newDog2 = new Dog();newDog.say()newDog2.say();Function.prototype.myApply=function(context){// 判断调用者是否为函数if (typeof this !== 'function') {throw new TypeError('Error')}//如果不传默认windowcontext = context || window;// 新增 fn 属性,将值设置为需要调用的函数context.fn = this;// 返回执行结果let result;//判断是否有参数传入if(arguments[1]){result = context.fn(...arguments[1])}else{result = context.fn();}// 删除函数delete context.fn;return result}function Cat(name,color){Animal.myApply(this,[name,color]);this.say=function(){console.log(`Cat:${this.name},${this.color}`)}}let newCat = new Cat('小猫','棕色');let newCat2 = new Cat();newCat.say()newCat2.say();
示例
- 用 apply 将数组各项添加到另一个数组
 - 使用apply和内置函数
 - 使用apply来链接构造器
 
