तलाश कर रहा हूँ नहीं कर रहा है आप एक शैक्षिक सवाल पूछ रहे थे के रूप में, मुझे लगता है कि ब्राउज़र संगतता एक नहीं है मुद्दा। यदि यह वास्तव में नहीं है, तो मैं इसके लिए सद्भावना प्रॉक्सी शुरू करना चाहता हूं। onerror
बहुत अच्छा अभ्यास नहीं है क्योंकि यह केवल एक घटना है यदि कहीं कोई त्रुटि उत्पन्न होती है। इसे, यदि कभी, केवल अंतिम उपाय के रूप में उपयोग किया जाना चाहिए। (मुझे पता है कि आपने कहा है कि आप इसे किसी भी तरह से उपयोग नहीं करते हैं, लेकिन onerror
सिर्फ डेवलपर-अनुकूल नहीं है।)
असल में, प्रॉक्सी आपको जावास्क्रिप्ट में अधिकांश मौलिक संचालन को रोकने में सक्षम बनाता है - सबसे विशेष रूप से कोई भी संपत्ति जो प्राप्त हो रही है यहां उपयोगी इस मामले में, आप .slice
प्राप्त करने की प्रक्रिया को रोक सकते हैं।
ध्यान दें कि प्रॉक्सी डिफ़ॉल्ट रूप से "ब्लैक होल" हैं। वे किसी ऑब्जेक्ट से मेल नहीं खाते हैं (उदाहरण के लिए प्रॉक्सी पर एक संपत्ति सेट करना सिर्फ set
जाल (इंटरसेप्टर) को कॉल करता है; वास्तविक भंडारण आपको स्वयं करना है)। लेकिन एक "फॉरवर्डिंग हैंडलर" उपलब्ध है जो सबकुछ सामान्य वस्तु (या पाठ्यक्रम का उदाहरण) के माध्यम से करता है, ताकि प्रॉक्सी सामान्य वस्तु के रूप में व्यवहार करे। हैंडलर को विस्तारित करके (इस मामले में, get
भाग), आप निम्नानुसार Array.prototype
विधियों को आसानी से रूट कर सकते हैं।
तो, जब भी किसी भी संपत्ति (नाम name
के साथ) प्राप्त किए गए किया जा रहा है, कोड पथ इस प्रकार है:
inst[name]
लौटने का प्रयास करें।
- अन्यथा, इस फ़ंक्शन को दिए गए तर्कों के साथ उदाहरण पर
Array.prototype[name]
लागू करने वाले फ़ंक्शन को वापस करने का प्रयास करें।
- अन्यथा, बस
undefined
वापस करें।
आप प्रॉक्सी के साथ चारों ओर खेलने के लिए चाहते हैं, आप क्रोमियम का एक रात का निर्माण में उदाहरण के लिए वी 8 का नवीनतम संस्करण, उपयोग कर सकते हैं (chrome --js-flags="--harmony"
के रूप में चलाने के लिए सुनिश्चित कर लें)। दोबारा, प्रॉक्सी "सामान्य" उपयोग के लिए उपलब्ध नहीं हैं क्योंकि वे अपेक्षाकृत नए हैं, जावास्क्रिप्ट के बहुत से मौलिक हिस्सों को बदलते हैं और वास्तव में आधिकारिक तौर पर अभी तक निर्दिष्ट नहीं हैं (अभी भी ड्राफ्ट)।
यह एक सरल चित्र है कि यह कैसा चल रहा है (inst
वास्तव में प्रॉक्सी है जिसे उदाहरण में लपेटा गया है)। ध्यान दें कि यह केवल को संपत्ति को चित्रित करता है; असम्बद्ध अग्रेषण हैंडलर की वजह से अन्य सभी परिचालनों को प्रॉक्सी द्वारा पारित किया जाता है।
प्रॉक्सी कोड इस प्रकार हो सकता है:
function Test(a, b, c) {
this[0] = a;
this[1] = b;
this[2] = c;
this.length = 3; // needed for .slice to work
}
Test.prototype.foo = "bar";
Test = (function(old) { // replace function with another function
// that returns an interceptor proxy instead
// of the actual instance
return function() {
var bind = Function.prototype.bind,
slice = Array.prototype.slice,
args = slice.call(arguments),
// to pass all arguments along with a new call:
inst = new(bind.apply(old, [null].concat(args))),
// ^is ignored because of `new`
// which forces `this`
handler = new Proxy.Handler(inst); // create a forwarding handler
// for the instance
handler.get = function(receiver, name) { // overwrite `get` handler
if(name in inst) { // just return a property on the instance
return inst[name];
}
if(name in Array.prototype) { // otherwise try returning a function
// that calls the appropriate method
// on the instance
return function() {
return Array.prototype[name].apply(inst, arguments);
};
}
};
return Proxy.create(handler, Test.prototype);
};
})(Test);
var test = new Test(123, 456, 789),
sliced = test.slice(1);
console.log(sliced); // [456, 789]
console.log("2" in test); // true
console.log("2" in sliced); // false
console.log(test instanceof Test); // true
// (due to second argument to Proxy.create)
console.log(test.foo); // "bar"
अग्रेषण हैंडलर the official harmony wiki पर उपलब्ध है।
Proxy.Handler = function(target) {
this.target = target;
};
Proxy.Handler.prototype = {
// Object.getOwnPropertyDescriptor(proxy, name) -> pd | undefined
getOwnPropertyDescriptor: function(name) {
var desc = Object.getOwnPropertyDescriptor(this.target, name);
if (desc !== undefined) { desc.configurable = true; }
return desc;
},
// Object.getPropertyDescriptor(proxy, name) -> pd | undefined
getPropertyDescriptor: function(name) {
var desc = Object.getPropertyDescriptor(this.target, name);
if (desc !== undefined) { desc.configurable = true; }
return desc;
},
// Object.getOwnPropertyNames(proxy) -> [ string ]
getOwnPropertyNames: function() {
return Object.getOwnPropertyNames(this.target);
},
// Object.getPropertyNames(proxy) -> [ string ]
getPropertyNames: function() {
return Object.getPropertyNames(this.target);
},
// Object.defineProperty(proxy, name, pd) -> undefined
defineProperty: function(name, desc) {
return Object.defineProperty(this.target, name, desc);
},
// delete proxy[name] -> boolean
delete: function(name) { return delete this.target[name]; },
// Object.{freeze|seal|preventExtensions}(proxy) -> proxy
fix: function() {
// As long as target is not frozen, the proxy won't allow itself to be fixed
if (!Object.isFrozen(this.target)) {
return undefined;
}
var props = {};
Object.getOwnPropertyNames(this.target).forEach(function(name) {
props[name] = Object.getOwnPropertyDescriptor(this.target, name);
}.bind(this));
return props;
},
// == derived traps ==
// name in proxy -> boolean
has: function(name) { return name in this.target; },
// ({}).hasOwnProperty.call(proxy, name) -> boolean
hasOwn: function(name) { return ({}).hasOwnProperty.call(this.target, name); },
// proxy[name] -> any
get: function(receiver, name) { return this.target[name]; },
// proxy[name] = value
set: function(receiver, name, value) {
this.target[name] = value;
return true;
},
// for (var name in proxy) { ... }
enumerate: function() {
var result = [];
for (var name in this.target) { result.push(name); };
return result;
},
// Object.keys(proxy) -> [ string ]
keys: function() { return Object.keys(this.target); }
};
यह लग रहा है जैसे आप [ "pollyfills" या "की परतें"] (http://remysharp.com/2010/10/08/what-is-a-polyfill/) –
संयोग से जावास्क्रिप्ट बारे में सोच रहे कोशिश-पकड़ ब्लॉक के साथ अपवादों को पकड़ने के लिए यह आमतौर पर अधिक सुरुचिपूर्ण और भरोसेमंद होता है। –