与同事讨论获取私有数组的返回值与对作为私有数组的引用的变量的赋值之间的区别,但无法想到以下内容会产生不同结果的充分理由:

控制者

app.controller("MyController", ["MyService", function(MyService) {
    var ctrl = this;
    ctrl.arrayAssign = [];

    ctrl.doSomething = function() {
        // Empty out array, usually assigned at one point, code is omitted for example
        ctrl.arrayAssign = []

        // This does not work, ctrl.arrayAssign = []
        ctrl.arrayAssign = MyService.serviceArray;

        // This works, ctrl.arrayAssign correctly assigned to serviceArray in MyService
        ctrl.arrayAssign = MyService.getServiceArray();
    }
}]);


服务

app.service("MyService", [function(){
    var service = this;
    var serviceArray = [];

    service.serviceArray = serviceArray;

    // This is called, either from controller above, or another controller
    service.assignToServiceArray = function(arr) {
        serviceArray = angular.copy(arr);
    };

    service.getServiceArray = function() {
        return serviceArray;
    };

    return service;
}]);


注意:ctrl.doSomething()在service.assignToServiceArray()之后调用

为什么上述两个控制器分配具有如上所述的不同结果,这是一个很好的解释?

我认为service.serviceArray会公开私有数组serviceArray并成为对私有数组的引用(service.serviceArray = serviceArray),因此对serviceArray的新赋值(即从service.assignToServiceArray)应该允许service.serviceArray引用可以直接由控制器访问的新数组分配。

service.getServiceArray()也将公开私有变量serviceArray,但直接公开,因为我没有尝试访问仅是对数组的引用的变量(即上面的service.serviceArray)。

在这种情况下,尝试为私有变量分配引用不是理想的选择,而只返回私有值会受到青睐吗?我可能错过了一些非常明显的东西...

最佳答案

service.serviceArray = serviceArray将对[]数组的引用分配给serviceArray属性,而不是对serviceArray变量的引用。

将新值分配给serviceArray时,会将其分配给此变量,除此之外没有其他值。

angular.copy的优点是它接受两个参数并允许保留对对象的引用:


  如果提供了目标,则将删除其所有元素(用于数组)或属性(对于对象),然后将源中的所有元素/属性复制到该目标。


因此,它将与:

angular.copy(arr, serviceArray);


该服务实际上滥用了JS提供的OOP功能。 service服务接受构造函数。如果它的行为类似于普通的对象构造函数,则不会出现这样的问题:

app.service("MyService", [function(){
    this.serviceArray = [];

    service.assignToServiceArray = function(arr) {
        this.serviceArray = arr;
    };

    service.getServiceArray = function() {
        return this.serviceArray;
    };

    // not needed
    // return service;
}]);


如果应该在重新分配后使用MyService.serviceArray,则应仅通过其getter和setter方法在任何地方引用它。在OOP中使用getter和setter的实际原因是,该值一直保持私有状态,从不直接从外部访问。例如。鉴于:

{{ vm.MyService.getServiceArray()[0] }}

09-07 16:21