function bindFoo(){
console.log('My name is ' + this.name); } var bindObj = {
name : 'gui'} var foo = bindFoo.bind(bindObj); //改变this指向,并返回一个新的函数 foo(); //函数执行 输出My name is gui
Function.prototype.bindFunc = function (context){
var _self = this; //_self指向bindFoo函数 //_self = function bindFoo(){ console.log('My name is ' + this.name); } return function(){
// 通过apply来改变this对象 _self.apply(context); } }
第二步,我们要和call,apply一致考虑参数的情况
function bindFoo(age, height, weight){
console.log('My name is ' + this.name + '。age is ' + age + '。height is ' + height + '。weight is ' + weight); } var bindObj = {
name : 'gui'}; Function.prototype.bindFunc= function(context){
var _self = this; //重点1,先获取从第一个arguments,进行分割,var foo = bindFoo.bind(bindObj, '18')中因为传入的第一个是对象。所以获取从第二个到最后一个的参数 var args = Array.prototype.slice.call(arguments, 1); return function(){
//重点2,此处获取的arguments是第二次foo('175', '130')中传入的参数,所以不需要从第二个开始获取 //和call,apply类似,我们也通过arguments来处理 var args2 = Array.prototype.slice.call(arguments); var bindArgs = args.concat(args2); _self.apply(context,bindArgs); } } var foo = bindFoo.bindFunc(bindObj, '18'); //改变this指向,并返回一个新的函数 foo('175', '130'); //函数执行 输出My name is gui。age is 18。height is 175。weight is 130
function bindFoo(age, height, weight){
console.log('My name is ' + this.name + '。age is ' + age + '。height is ' + height + '。weight is ' + weight); } var bindObj = {
name : 'gui'} var name = 'sichao'; var foo = bindFoo.bind(bindObj, '18'); //改变this指向,并返回一个新的函数 var fooObj = new foo('175', '130'); // 输出My name is undefined。age is 18。height is 175。weight is 130
Function.prototype.bindFunc = function(context){
var _self = this; var args = Array.prototype.slice.call(arguments, 1); var bindFunc = function(){
var args2 = Array.prototype.slice.call(arguments, 0); var bindArgs = args.concat(args2); /* 第二步: 当作为构造函数new foo('175', '130')时,this 指向实例,因为第一步中bindFunc.prototype = this.prototype, 所以结果为true,当结果为 true 的时候,this 指向实例。 当作为普通函数foo('175', '130')时,this 指向 window,bindFunc指向绑定函数, 此时结果为 false,当结果为 false 的时候,this 指向绑定的 context。*/ var bindThis = this instanceof bindFunc?this :context; _self.apply(bindThis, bindArgs); } //第一步:先将返回函数bindFunc的原型对象修改为绑定函数bindFoo的原型对象 //实例就可以继承绑定函数的原型中的值 bindFunc.prototype = _self.prototype; return bindFunc; }
Function.prototype.bindFunc = function(context){
var _self = this; var args = Array.prototype.slice.call(arguments, 1); var turnFunc = function(){
}; var bindFunc = function(){
var args2 = Array.prototype.slice.call(arguments, 0); var bindArgs = args.concat(args2); var bindThis = this instanceof bindFunc?this:context; _self.apply(bindThis, bindArgs); } turnFunc.prototype = _self.prototype; bindFunc.prototype = new turnFunc(); return bindFunc; }
好了,最后的最后,我们再兼容一下绑定函数不正确的情况:
Function.prototype.bindFunc = function(context){
if(typeof this != 'function'){
console.log(typeof this); throw new Error("not function!"); } var _self = this; var args = Array.prototype.slice.call(arguments, 1); var turnFunc = function(){
}; var bindFunc = function(){
var args2 = Array.prototype.slice.call(arguments, 0); var bindArgs = args.concat(args2); var bindThis = this instanceof bindFunc?this:context; _self.apply(bindThis, bindArgs); } turnFunc.prototype = _self.prototype; bindFunc.prototype = new turnFunc(); return bindFunc; }
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/230323.html原文链接:https://javaforall.net
