没有 object.defineProperty 的 AngularJS 装饰器
-
24-12-2019 - |
题
如何在无法访问 object.defineProperty 的情况下使用装饰器?
我正在研究可用的垫片:
但如果这些没有通过测试,装饰器是否还有其他工作方式?
我正在使用装饰器 $onRootScope.
我使用的是角度 1.08。我需要与 IE7 兼容。
更新
我尝试了一些似乎有效的方法,但我不知道它们之间的区别: 普朗克
var app = angular.module('plunker', []);
app.config(['$provide', function($provide){
$provide.decorator('$rootScope', ['$delegate', function($delegate){
$delegate.a = 1;
$delegate.constructor.prototype.b = 2;
Object.defineProperty($delegate.constructor.prototype, 'c', {
value: 3
});
return $delegate;
}]);
}]);
app.controller('MainCtrl', function($rootScope, $scope) {
console.log($rootScope); //reveals `a` property
console.log($rootScope.constructor.prototype); //=> {b:2, c:3}
console.log($rootScope.a); //=> 1
console.log($rootScope.b); //=> 2
console.log($rootScope.c); //=> 3
$scope.name = 'World';
});
谢谢。
解决方案
好吧,您共享的代码的等效解决方案是:
var proto = Object.getPrototypeOf(Object.getPrototypeOf($delegate));
proto['$onRootScope'] = function (name, listener) {
var unsubscribe = $delegate.$on(name, listener);
this.$on('$destroy', unsubscribe);
};
在原始代码中这一行 $delegate.constructor.prototype
正在访问 $delegate 的原型原型。
然后,一旦您可以访问它,您就可以在其中简单地定义一个新函数。您不需要使用 defineProperty
. 。唯一的警告是通过使用 defineProperty
您可以配置该方法不可枚举(不应出现在 for-each 循环中)。以这种方式,添加的方法将出现在 for-each 循环中。但这对你来说可能不是问题。
我创建了一个 JSFiddle 为了这。
您可以使用 John Resig 的 Polyfill 为了 getObjectPrototypeOf
如果您当前的浏览器无法使用该功能:
if ( typeof Object.getPrototypeOf !== "function" ) { if ( typeof "test".__proto__ === "object" ) { Object.getPrototypeOf = function(object){ return object.__proto__; }; } else { Object.getPrototypeOf = function(object){ // May break if the constructor has been tampered with return object.constructor.prototype; }; } }
不隶属于 StackOverflow