我正在学习bind
,call
和apply
个功能。我正在使用bind为api调用设置回调。这是我的职能:
function errorCallback(list, error) {
$log.error('Somehting went wrong while loading json.');
$log.log(list, error);
}
function successCallback(list, response) {
$log.info('JSON loaded successfully.');
//$log.log(list, response);
//this works
//$scope.list = list.concat(response.data);
//this doesn't
list = list.concat(response.data);
$log.log($scope.list, list);
}
这是我绑定他们的方式:
var successCb = successCallback.bind(null, $scope.list),
errorCb = errorCallback.bind(null, $scope.list);
当我将它们用作回调时:
$scope.loadJson = function() {
$http.get('data.json').then(successCb, errorCb);
};
他们正在被正确调用。但值得关注的是,当我更新list
时,它不会更新传递的实际参数。我想知道当我们绑定bind的参数时,它们是使用值还是引用绑定的?这是plunkr。
答案 0 :(得分:4)
JavaScript中的所有内容都是按值传递的。其中一些值可以引用可变事物(对象 - 也称为参考值),但这就是它。当您重新分配到list
时,除了本地范围内的list
变量之外,没有任何变化。你实际上需要改变你的数组,concat
不做 - 改为使用push
。
如果要改变$scope
,则需要自行传递并明确指定其.list
属性。
答案 1 :(得分:1)
Function.prototype.bind
与调用或apply相同,但不会立即调用该函数,而是返回一个新函数,其参数绑定到此函数,并且当从新作用域或上下文调用该函数时,它会保持不变。
绑定还允许您防止您的构造函数被攻击"由apply
或call
提升,因为无论有人发送什么来尝试通过call
或apply
覆盖此内容,它都会始终使用绑定参数。
如果您已注意到,即使我们通过guest
尝试rajini
,最后一个也不会从override
更改为call
。
function Profile(u) {
this.user = u;
this.getUser = function () {
return this.user;
};
}
var x = new Profile('guest');
alert(x.getUser.apply({
user: 'Vinoth'
})); // Vinoth
alert(x.getUser.call({
user: 'Google'
})); // Google
alert(x.getUser.bind(x).call({
user: 'Rajini'
})); // guest