Yup, до тех пор, пока Proxies не придет в полную силу, единственный способ добиться того, что вы пытаетесь сделать, - это затенять встроенные методы на карте/множестве и т. Д. Самостоятельно.
Например, если у вас есть карта, как так:
var myMap = new Map([ ['key1', 'value1'], ['key2', 'value2']])
Вы должны были бы иметь некоторую обертку, чтобы передать его в добавить встроенные методы, например, для получения/установки:
function proxify(obj){
var $fnMapGet = function(key){
console.log('%cmap get', 'color:limegreen', 'key:', key)
if(!Map.prototype.has.call(this, key)){
throw(new Error('No such key: '+ key))
} else {
return Map.prototype.get.call(this, key)
}
}
var $fnMapSet = function(key, value){
console.log('%cmap set', 'color:tomato', 'key:', key, 'value:', value)
if(Map.prototype.has.call(this, key)){
throw(new Error('key is already defined: ' + key))
} else {
if(Map.prototype.get.call(this, key) == value){
console.log('%cmap set', 'color:tomato', '*no change')
return this
}
return Map.prototype.set.call(this, key, value)
}
}
Object.defineProperty(obj, 'get', {
get(){
return $fnMapGet
}
})
Object.defineProperty(obj, 'set', {
get(){
return $fnMapSet
}
})
return obj
}
Итак:
proxify(myMap)
myMap.get('key1') // <= "value1"
myMap.get('key2') // <= "value2"
myMap.get('key3') // <= Uncaught Error: No such key: key3
myMap.set('key3', 'value3') // <= Map {"key1" => "value1", "key2" => "value2", "key3" => "value3"}
myMap.set('key3', 'another value3') // <= Uncaught Error: key is already defined: key3
Это было бы добавить возможность сделать свой собственный набор/получить на карте, не почти такая же приятная, как и подклассическая карта, и не так проста, как прокси-серверы es6, но она по крайней мере работает.
Полный фрагмент кода работает ниже:
var myMap = new Map([ ['key1', 'value1'], ['key2', 'value2']])
function proxify(obj){
\t var $fnMapGet = function(key){
\t \t console.log('get key:', key)
\t \t if(!Map.prototype.has.call(this, key)){
\t \t \t throw(new Error('No such key: '+ key))
\t \t } else {
\t \t \t return Map.prototype.get.call(this, key)
\t \t }
\t }
\t var $fnMapSet = function(key, value){
\t \t console.log('set key:', key, 'value:', value)
\t \t if(Map.prototype.has.call(this, key)){
\t \t \t throw(new Error('key is already defined: ' + key))
\t \t } else {
\t \t \t if(Map.prototype.get.call(this, key) == value){
\t \t \t \t console.log('*no change')
\t \t \t \t return this
\t \t \t }
\t \t \t return Map.prototype.set.call(this, key, value)
\t \t }
\t }
\t Object.defineProperty(obj, 'get', {
\t \t get(){
\t \t \t return $fnMapGet
\t \t }
\t })
\t Object.defineProperty(obj, 'set', {
\t \t get(){
\t \t \t return $fnMapSet
\t \t }
\t })
\t return obj
}
proxify(myMap)
myMap.get('key1')
myMap.get('key2')
try {
myMap.get('key3')
} catch(ex){
console.warn('error:', ex.message)
}
myMap.set('key3', 'value3')
try {
myMap.set('key3', 'another value3')
} catch(ex){
console.warn('error:', ex.message)
}
Я просто получаю 'Объявления с блочной областью (let, const, function, class) еще не поддерживаются за пределами строгого режима. – thefourtheye
И я получаю' Uncaught SyntaxError: Unexpected reserved word'. Возможно, Chrome не поддерживает расширение встроенных классов. –
Yup, in io.js Я могу скомпилировать его без каких-либо ошибок (хотя я должен был использовать '' строгое "' вверху) – thefourtheye