一、bind
bind 的其中一个用法就是:绑定函数,使其无论怎么样调用都用相同的 this
示例:
var obj = {
getThis: function() {
console.log(this);
}
};
obj.getThis();
var getThisCopy = obj.getThis;
getThisCopy();
运行结果如下:
通过上述例子我们会发现,虽然是 getThisCopy 是复制了 obj 的 getThis 方法,但是他们所属的对象却不一样。在对象里面,所有的 this 都指向对象本身,而在全局作用域定义的变量的 this 指向 Window。
示例:
var obj = {
num: 100,
numFun: function() {
console.log(this.num);
}
};
var numFunCopy = obj.numFun;
numFunCopy();
运行结果如下:
原因:复制了函数numFun,但是没有复制num属性,导致后面调用numFunCopy的时候,num是未定义的
bind 的存在就是 为了解决 this 不能够指向原来的问题。
所以,试试这段代码:
var obj = {
getThis: function(){
console.log(this);
}
}
var getThisCopy = obj.getThis;
obj.getThis();
getThisCopy.bind(obj)();
var obj = {
num: 100,
numFun: function(){
console.log(this.num);
}
}
var numFunCopy = obj.numFun;
obj.numFun();
numFunCopy.bind(obj)();
输出结果如下:
总结:
总结bind使用方法:
fun.bind(thisArgument, argument1, argument2, ...)
thisArgument:在 fun 函数运行时指定的 this 值,如果绑定函数时使用 new 运算符构造的,则该值将被忽略。
argument1, argument2, ...:指定的参数列表。
返回值:具有指定 this 值和初始参数的给定函数的副本
使用1:创建绑定函数,使函数无论怎么样调用,都有相同的 this 值
this.x = 9;
var module = {
x: 81,
getX: function() { return this.x; }
};
module.getX(); // 返回 81
var retrieveX = module.getX;
retrieveX(); // 返回 9, 在这种情况下,"this"指向全局作用域
// 创建一个新函数,将"this"绑定到module对象
// 新手可能会被全局的x变量和module里的属性x所迷惑
var boundGetX = retrieveX.bind(module);
boundGetX(); // 返回 81
二、call
语法:fun.call(thisArgument, argument1, argument2, ...)
thisArgument:在 fun 函数运行时指定的 this 值。在非严格模式下,该函数 this 指定为 null 和 undefined ,则 this 值会自动只想全局对象,同时只为原始值的 this 会指向该原始值的自动包装对象。
argument*:指定的参数列表。
返回值:调用该方法的返回值,如果没有,则返回undefined。
使用1:使用 call 方法来实现继承
function Product(name,price){
console.info(this);
this.name = name;
this.price = price;
}
function Car(name,price){
Product.call(this,name,price);
this.category = 'car';
}
$(function(){
new Product();
var car = new Car('奔驰',100);
console.info(car);
});
测试结果:
使用2:使用 call 调用匿名函数,方法为for循环传入不同的对象
$(function(){
var people = [
{name:'aaa',age:10},
{name:'bbb',age:20},
];
for(var i = 0;i<people.length;i++){
(function(i){
console.info('第'+i+'个人的名字:'+this.name+',年龄:'+this.age);
}).call(people[i],i);
}
});
测试结果如下:
如果代码修改为:
$(function(){
var people = [
{name:'aaa',age:10},
{name:'bbb',age:20},
];
for(var i = 0;i<people.length;i++){
//(function(i){
console.info('第'+i+'个人的名字:'+this.name+',年龄:'+this.age);
//}).call(people[i],i);
}
});
测试结果如下:
使用3:指定上下文 this
function greet(name,price){
var reply = [this.person,'aaa',this.role].join('|');
console.info(reply);
}
var i = {
person:'bbb',role:'ccc'
}
$(function(){
greet.call(i);
});
测试结果如下:
三、apply
语法:fun.apply(thisArg [, argsArray])
thisArg:可选,在非严格模式下,如果 this 值设置为 null/undefined,则 this 指向去全局对象(浏览器中就是 window 对象),同时为原始值(数字,字符串,布尔值)的 this 会指向该原始的包装对象。
argsArray:可选。数组或者类数组对象(从ES5开始可以使用类数组对象)。
返回值:调用有指定this值和参数的函数的结果。
使用:其使用跟 call() 非常相似,只是提供参数的方式不同。