/**
* 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