问题
How do I use decorators without having access to object.defineProperty?
I am looking into the shims available:
- es5-sham
- polyfill
but in case those don't pass testing, is there another way decorators were intended to work?
I am using the decorator for $onRootScope.
I am using angular 1.08. I need compatibility with IE7.
Update
I have tried out a few methods that seem to work but I don't know the difference between them: plunkr
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';
});
Thank You.
回答1:
Well, an equivalent solution to the pice of code you shared is:
var proto = Object.getPrototypeOf(Object.getPrototypeOf($delegate));
proto['$onRootScope'] = function (name, listener) {
var unsubscribe = $delegate.$on(name, listener);
this.$on('$destroy', unsubscribe);
};
In the original code this line $delegate.constructor.prototype
is getting access to the $delegate's prototype prototype.
Then, once you get access to it, you can simply define a new function in it. You do not need to use defineProperty
. The only caveat is that by using defineProperty
you can configure that the method is not enumerable (should not appear in for-each loops). In this other way, the method added would appear in for-each loops. It may not be a problem for you though.
I have created a JSFiddle for this.
You can use John Resig's polyfill for getObjectPrototypeOf
if the function is not available for your current browser:
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; }; } }
来源:https://stackoverflow.com/questions/22080588/angularjs-decorator-without-object-defineproperty