gpt4 book ai didi

javascript - 使用 Angularjs module.service 的原型(prototype)继承

转载 作者:行者123 更新时间:2023-11-30 16:13:09 25 4
gpt4 key购买 nike

我已经使用 Angularjs 几个月了,我想知道如何使用这个框架实现高效的 OOP。

我在一个项目中工作,我需要实例化一个“终端”类,它具有构造函数属性和一系列方法(作为普通类)。在普通 JS 中,我会使用伪经典模式(将构造函数属性与原型(prototype)链中的方法分开)。

根据我对 Angularjs 的了解,model.service() 将是最佳选择,因为我每次调用它时都会创建一个新的服务实例。但在定义方法时,我通常会看到下一个实现:

myApp.service('helloWorldFromService', function() {
this.sayHello = function() {
return "Hello, World!"
};
});

但是,它不会在我每次调用类时创建函数 sayHello() 吗?我想知道将功能分开是否会更好,例如:

myApp.service('helloWorldFromService', function() {
this.msg= "Hello, World!";
});

helloWorldFromService.prototype.showMessage = function() {
return this.msg;
};

这样一来,函数 showMessage() 将只在内存中创建一次,并在创建的所有服务实例之间共享。

另外,如果这是可能的(如果它确实使代码更高效),那么实现它的方式是什么? (上面的代码只是胡乱猜测)

谢谢

最佳答案

根据评论进行编辑:看起来如果您只需返回对象的构造函数就可以执行此操作,然后通过对服务的调用访问原型(prototype)。

快速解释,在示例中,单击“再次获取”将调用原型(prototype)函数 changeHelloWorldString 并使用控件名称更新字符串。单击“Change Prototype”后,changeHelloWorldString 函数将更改为将“[PROTOTYPE CHANGE]”附加到字符串。单击任一“再次获取”按钮将表明在第二个 Controller 中所做的原型(prototype)更改影响了两个 Controller 中对象的原型(prototype)链。

请看下面的例子:

angular.module('myModule2', [])
.factory('myService', function() {
function FactoryConstructor(thirdFunction) {
this.helloWorldFunction = function() {
return this.helloWorldString;
}
this.thirdFunction = thirdFunction;
}
FactoryConstructor.prototype.helloWorldString = 'Hello World';
FactoryConstructor.prototype.changeHelloWorldString = function(newString) {
this.helloWorldString = newString;
};
FactoryConstructor.prototype.changeThirdFunction = function(newFunction) {
this.thirdFunction = newFunction;
}
return FactoryConstructor;
})
.controller('ctrl1', function($scope, myService) {
var factoryResult = new myService(function() {
this.helloWorldString += ' first';
});
$scope.hwString = factoryResult.helloWorldString;
$scope.hwString2 = factoryResult.helloWorldFunction();
// console.log(factoryResult instanceof myService) //tested true
$scope.getAgain = function() {
factoryResult.changeHelloWorldString('ctrl1 String');
factoryResult.thirdFunction();
$scope.hwString = factoryResult.helloWorldString;
$scope.hwString2 = factoryResult.helloWorldFunction();
}
})
.controller('ctrl2', function($scope, myService) {
var factoryResult = new myService(function() {
this.helloWorldString += ' second';
});
$scope.hwString = factoryResult.helloWorldString;
$scope.hwString2 = factoryResult.helloWorldFunction();
// console.log(factoryResult instanceof myService) //tested true
$scope.getAgain = function() {
factoryResult.changeHelloWorldString('ctrl2 String');
factoryResult.thirdFunction();
factoryResult.changeThirdFunction(function() {
this.helloWorldString += ' third';
});
$scope.hwString = factoryResult.helloWorldString;
$scope.hwString2 = factoryResult.helloWorldFunction();
}

$scope.changePrototype = function() {
myService.prototype.changeHelloWorldString = function(newString) {
this.helloWorldString = newString + " [PROTOTYPE CHANGE]";
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app='myModule2'>
<div ng-controller='ctrl1'>
<div>{{hwString}}</div>
<div>{{hwString2}}</div>
<button ng-click='getAgain()'>Get again</button>
</div>
<div ng-controller='ctrl2'>
<div>{{hwString}}</div>
<div>{{hwString2}}</div>
<button ng-click='getAgain()'>Get again</button>
<button ng-click='changePrototype()'>Change Prototype</button>
</div>
</div>

另一个很好的解释可以在 this answer 中找到。 .这可能会显示一种更好/更清晰的方法来执行此示例中显示的内容,即使用提供程序(哪个服务和工厂都派生自,请参阅作者的附注)。

下面原始帖子的其余部分作为背景

Angular 服务是可以注入(inject)到很多地方的单例。所以如果你这样做:

angular.module('myModule', [])
.service('myService', function() {
var myService = this;
this.helloWorldString = 'Hello World String';
this.helloWorldFunction = function() {
return myService.helloWorldString;
}
})
.controller('main', function($scope, myService) {
$scope.getAgain = function() {
$scope.hwString = myService.helloWorldString;
$scope.hwString2 = myService.helloWorldFunction();
}
$scope.getAgain();
})
.controller('notMain', function($scope, myService) {
myService.helloWorldString = 'edited Hello World String';
$scope.hwString = myService.helloWorldString;
$scope.hwString2 = myService.helloWorldFunction();
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app='myModule'>
<div ng-controller='main'>
<div>{{hwString}}</div>
<div>{{hwString2}}</div>
<button ng-click='getAgain()'>Get again</button>
</div>
<div ng-controller='notMain'>
<div>{{hwString}}</div>
<div>{{hwString2}}</div>
</div>
</div>

您会注意到最初两者是不同的,因为第一对是在更改之前获得的,但是在第二个 Controller 中所做的更改实际上会影响第一个。只需单击 Get Again 按钮,它就会从服务中重新提取信息,现在它会匹配,证明它们是同一个对象,尽管它们被注入(inject)到两个不同的 Controller 中。

看起来你真正想要的是一个工厂(虽然这主要是语义,你可以在下一个例子中将“工厂”换成“服务”,它会产生相同的结果。这也可以在 Angular 中看到文档本身。documentation for a service 从未实际使用 .service,它始终使用 .factory)。通过这种方式,您实质上可以在调用时构造工厂对象的新实例,在本例中为“myService(...)”。使用这些函数参数,您可以自定义返回对象的属性(包括函数),如您在示例中所见。

angular.module('myModule2', [])
.factory('myService', function() {
return function(stringInput, thirdFunction) {
return {
helloWorldString: stringInput,
helloWorldFunction: function() {
return this.helloWorldString;
},
thirdFunction: thirdFunction
}
}
})
.controller('ctrl1', function($scope, myService) {
var factoryResult = myService('Hello World String', function () {
this.helloWorldString += ' first';
});
$scope.hwString = factoryResult.helloWorldString;
$scope.hwString2 = factoryResult.helloWorldFunction();

$scope.getAgain = function() {
factoryResult.thirdFunction();
$scope.hwString = factoryResult.helloWorldString;
$scope.hwString2 = factoryResult.helloWorldFunction();
}
})
.controller('ctrl2', function($scope, myService) {
var factoryResult = myService('new Hello World String', function () {
this.helloWorldString += ' second';
});
$scope.hwString = factoryResult.helloWorldString;
$scope.hwString2 = factoryResult.helloWorldFunction();

$scope.getAgain = function() {
factoryResult.thirdFunction();
$scope.hwString = factoryResult.helloWorldString;
$scope.hwString2 = factoryResult.helloWorldFunction();
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app='myModule2'>
<div ng-controller='ctrl1'>
<div>{{hwString}}</div>
<div>{{hwString2}}</div>
<button ng-click='getAgain()'>Get again</button>
</div>
<div ng-controller='ctrl2'>
<div>{{hwString}}</div>
<div>{{hwString2}}</div>
<button ng-click='getAgain()'>Get again</button>
</div>
</div>

关于javascript - 使用 Angularjs module.service 的原型(prototype)继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35925112/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com