阅读背景:

深入理解js中的bind

来源:互联网 
/**
* bind 函数在js中的运用
*/
this.name = "test";
let testObj = {
	name:"zhangsan",
	introduce:function(){
		return this.name;
	}
}
let test = {
	name:"lisi"
}
let test1 = {
	name:"wangwu"
}
let fn = testObj.introduce;
console.log(fn());//test   
console.log(fn.bind(test)());//lisi
console.log(fn.bind(test1)());//王五
console.log(fn());//test 注:不存在永久转变this指向的说法  


/**
	*bind()的另外一个最简略的用法是使一个函数具有预设的初始参数。这些参数(如果有的话)作为bind()的第二个参数             跟在this(或其他对象)后面,以后它们会被插入到
	*目的函数的参数列表的开端地位,传递给绑定函数的参数会跟在它们的后面。
*/
function list() {
  return Array.prototype.slice.call(arguments);
}


var list1 = list(1, 2, 3); // [1, 2, 3]


var leadingThirtysevenList = list.bind(undefined, 37,21);


var list2 = leadingThirtysevenList(); // [37]
var list3 = leadingThirtysevenList(1, 2, 3); // [37,21, 1, 2, 3]
var list4 = leadingThirtysevenList(1, 2, 3, 4); // [37,21, 1, 2, 3,4]

/**
* 来看es6中的函数初始值 
*/
function EsArguments(name="zhangsan"){
	console.log(name);
}
EsArguments();//zhangsan
EsArguments("lisi");//lisi


/**
* 在自定义对象中的运用  demo 
* 跟es6中函数的初始值的区分在于不会笼罩原始值 
*/
function testBind(){
	this.cacheArgs = this.transformArgs.bind(undefined,...arguments);
};
testBind.prototype.transformArgs = function(){
	return Array.prototype.slice.call(arguments);
}
testBind.prototype.showArgList = function(){
	return this.cacheArgs(...arguments);
}
 let Test = new testBind(1,2,3); 
 console.log(Test.showArgList(13,14));
 console.log(Test.showArgList(5,21));


/* bind和call apply的区分在于不会立即调用 缘由在于 bind() 函数会创立一个新函数(称为绑定函数),
* 新函数与被调函数(绑定函数的目的函数)具有雷同的函数体。
* bind一般用在异步调用和事件
* ->下面看bind函数的原生实现方法 
*/
Function.prototype.bind = function() {
        var self = this, // 保留原函数履行高低文中的this指向 
        context = Array.prototype.shift.call(arguments), // 须要绑定的this高低文
        args = Array.prototype.slice.call(arguments); // 剩余的参数转成数组
        return function() { //返回一个新函数
        // 履行新函数时,将传入的高低文context作为新函数的this
        // 并且组合两次分离传入的参数,作为新函数的参数
		return self.apply(context, Array.prototype.concat.call(args, Array.prototype.slice.call(arguments))); 
      }
};
/**bind 官方文档说明
* 语法
* fun.bind(thisArg[, arg1[, arg2[, ...]]])
* 参数thisArg

* 当绑定函数被调用时,该参数会作为原函数运行时的 this 指向。当应用new 操作符调用绑定函数时,该参

                    数 无 效。 (注:缘由在于new操作会创立一个空对象)

* arg1, arg2, ...
* 当绑定函数被调用时,这些参数将置于实参之前传递给被绑定的办法。

* 返回值

                 * 返回由指定的this值和初始化参数改革的原函数拷贝
*/

/**
  * bind函数在setTimeout中的运用
*/
let testBingMethod = {
	name:"123",
	test:function(){
		console.log(this.name);
},
showList:function(){
	setTimeout(this.test.bind(this),1000);
//第一个this为当前对象履行上文的this 
//第二个this为setTimeout函数的this指向即window对象
	}
}
testBingMethod.showList()
/**
  * bind作为结构函数应用的绑定函数

  * 自但是然地,绑定函数实用于用new操作符 new 去结构一个由目的函数创立的新的实例。当一个绑定函数是用来

                    构建一个值的,本来供给的 this 就会被疏忽。但是, 

  * 本来供给的那些参数依然会被前置到结构函数调用的前面。 <---缘由在于new操作会创立一个空对象-->
  */
function Point(x, y) {
  this.x = x;
  this.y = y;
}


Point.prototype.toString = function() { 
  return this.x + "," + this.y; 
};


var p = new Point(1, 2);
p.toString(); // "1,2"


// 以下这行代码在 polyfill 不支撑,polyfill下必需指向一个新的对象 
// 在原生的bind办法运行没问题: 
var YAxisPoint = Point.bind(null, 0/*x*/);
var axisPoint = new YAxisPoint(5);
axisPoint.toString(); // "0,5"


/**
*bind 的快捷调用

*你可以用 Array.prototype.slice 来将一个相似于数组的对象(array-like object)转换成一个真实的数组,就

                            拿它来举例子吧。你可以创立这样一个捷径:

*/
function testFn(){
	var slice = Array.prototype.slice;
	slice.apply(arguments);

	/* 用 bind()可使这个进程变得简略。在下面这段代码里面,slice 是 Function.prototype 的 apply() 方

	法的绑定函数,并且将 Array.prototype 的 

	*slice() 办法作为 this 的值。这意味着我们压根儿用不着上面那个 apply()调用了。
	*/ 
	var unboundSlice = Array.prototype.slice;
	var slice = Function.prototype.apply.bind(unboundSlice);
	slice(arguments);
}/**
* bind 函数在js中的运用
*/
this.name = "test";
let t



你的当前访问异常,请进行认证后继续阅读剩余内容。

分享到: