var person = {
value : 1
}
function bar() {
console.log(this.value)
}
// 若是不对this进行绑定执行bar() 会返回undefined,this指向window
bar.call(person) // 1复制代码
试想一下当调用call的时候也就相似于数组
var person = { value: 1,
bar: function() {
console.log(this.value)
}
}
person.bar() // 1复制代码
这样就把 this 指向到了 person上,可是这样给 person 对象加了一个属性,不太合适,不过没关系,执行完删除这个属性就能够实现了。
bash
也就是说步骤实际上是这样的app
Function.prototype.call = function(context){
context = context ? Object(context) : window;//不传递context默认为window
context.fn = this;//this也就是调用call的函数
let args = [...arguments].slice(1);
let r = context.fn(...args);
delete context.fn;
return r;
}复制代码
apply
的方法和 call
方法的实现相似,只不过是若是有参数,以数组形式进行传。
函数
Function.prototype.apply= function(context,args){
context = context ? Object(context) : window;//不传递context默认为window
context.fn = this;
if(!args){
return context.fn();
}
let r = context.fn(...args);
delete context.fn;
return r;
}复制代码
用法:ui
let obj = {
name:'gjf'
}
function fn(){
console.log(this.name)
}
let bindFn = fn.bind(obj); //返因一个绑定后的方法
findFn() //用绑定后的方法,让原方法执行复制代码
实现:this
Function.prototype.bind = function(context){
let that = this;
return function(){
return that.apply(context);
}
}复制代码
这样实现了最简单的改变this指向的bind,可是这样还远远不够,由于bind还能够绑定参数;spa
方法传参能够分两批传,一批能够先在bind方法里面先绑定好,另外一批在调用的时候传参,例如如下示例;prototype
用法:code
let obj = {
name:'gjf'
}
function fn(name,age){
console.log(this.name+'养了一只'+name+age+'岁了')
}
let bindFn = fn.bind(obj,'猫'); //返因一个绑定后的方法
findFn(8) //用绑定后的方法,让原方法执行复制代码
实现:对象
Function.prototype.bind = function(context){
let that = this;
let bindArgs = Array.prototype.slice.call(argument,1)//['猫']
return function(){
let args = Array.prototype.slice.call(argument);
return that.apply(context,bindArgs.concat(args));
}
}复制代码
调用bind返回的函数除了能够直接调用,还能够把函数当成一个类来调用;原函数上绑定了属性,new出来的实例上可否访问。
用法:
fn.prototype.flag = '哺乳类'; //原函数上绑定了属性
let findFn = fn.bind(obj,'猫');
let instance = new findFn(8);//若是绑定的函数被new了,当前函数的this就是当前的实例
console.log(instance.flag) //undefined复制代码
实现:
Function.prototype.bind = function(context){
let that = this;
let bindArgs = Array.prototype.slice.call(argument,1)//['猫']
function Fn(){} //Object.create的原理
function fBound(){
let args = Array.prototype.slice.call(argument);
return that.apply(this instanceof fBound ? this:context,bindArgs.concat(args));
}
Fn.prototype = this.prototype;
fBound.prototype = new Fn();
return fBound;
}复制代码
这里,咱们js里的三种改变this指向的方法就实现啦。。。。。