আমি জাভাস্ক্রিপ্টে [] অপারেটরটিকে ওভারলোড করার উপায় খুঁজে পাচ্ছি না। বাইরে কেউ জানেন?
আমি চিন্তা করেছিলাম ...
MyClass.operator.lookup(index)
{
return myArray[index];
}
বা আমি সঠিক জিনিসগুলির দিকে তাকাচ্ছি না
আমি জাভাস্ক্রিপ্টে [] অপারেটরটিকে ওভারলোড করার উপায় খুঁজে পাচ্ছি না। বাইরে কেউ জানেন?
আমি চিন্তা করেছিলাম ...
MyClass.operator.lookup(index)
{
return myArray[index];
}
বা আমি সঠিক জিনিসগুলির দিকে তাকাচ্ছি না
MyClass
বস্তুকে একটি অ্যারে করুন। আপনি কী এবং মানগুলি myArray
আপনার var myObj = new MyClass()
অবজেক্টে অনুলিপি করতে পারেন ।
উত্তর:
আপনি জাভাস্ক্রিপ্টে অপারেটরগুলি ওভারলোড করতে পারবেন না।
এটি ECMAScript 4 এর জন্য প্রস্তাব করা হয়েছিল তবে তা প্রত্যাখ্যান করা হয়েছে।
আমি মনে করি না আপনি তাড়াতাড়ি যে কোনও সময় দেখতে পাবেন।
Object arg1: a arg2: b arg3: c
হিসাবে Object["arg1:arg2:arg3:"](a,b,c)
। সুতরাং আপনি থাকতে পারেন myObject["[]"](1024)
: পি
target[name]
, ওপি কেবল উদাহরণগুলি দেখিয়েছে
[]
পাশাপাশি অপারেটর, BTW:var key = 'world';
console.log(proxy[key]);
সহজ উত্তরটি হল জাভাস্ক্রিপ্ট স্কয়ার বন্ধনীগুলির মাধ্যমে কোনও অবজেক্টের শিশুদের অ্যাক্সেসের অনুমতি দেয়।
সুতরাং আপনি আপনার শ্রেণি সংজ্ঞায়িত করতে পারেন:
MyClass = function(){
// Set some defaults that belong to the class via dot syntax or array syntax.
this.some_property = 'my value is a string';
this['another_property'] = 'i am also a string';
this[0] = 1;
};
এরপরে আপনি আপনার বর্গের যে কোনও পরিস্থিতিতে সিন্টেক্স সহ সদস্যদের অ্যাক্সেস করতে সক্ষম হবেন।
foo = new MyClass();
foo.some_property; // Returns 'my value is a string'
foo['some_property']; // Returns 'my value is a string'
foo.another_property; // Returns 'i am also a string'
foo['another_property']; // Also returns 'i am also a string'
foo.0; // Syntax Error
foo[0]; // Returns 1
foo['0']; // Returns 1
foo['random']
আপনার কোডটি করতে সক্ষম নয় যা ধরার জন্য একটি উপায় জিজ্ঞাসা করছে ।
একটি প্রক্সি ব্যবহার করুন। উত্তরে এটি অন্য কোথাও উল্লেখ করা হয়েছিল তবে আমি মনে করি এটি একটি আরও ভাল উদাহরণ:
var handler = {
get: function(target, name) {
if (name in target) {
return target[name];
}
if (name == 'length') {
return Infinity;
}
return name * name;
}
};
var p = new Proxy({}, handler);
p[4]; //returns 16, which is the square of 4.
ব্র্যাকেট অপারেটর প্রকৃতপক্ষে সম্পত্তি অ্যাক্সেস অপারেটর হিসাবে, আপনি গেটর এবং সেটটারগুলির সাহায্যে এটি আঁকতে পারেন। আই-এর জন্য আপনাকে তার পরিবর্তে অবজেক্ট.ডেফাইনপোপার্টি () ব্যবহার করতে হবে। উদাহরণ:
var obj = {
get attr() { alert("Getter called!"); return 1; },
set attr(value) { alert("Setter called!"); return value; }
};
obj.attr = 123;
আইই 8 + এর জন্য একই:
Object.defineProperty("attr", {
get: function() { alert("Getter called!"); return 1; },
set: function(value) { alert("Setter called!"); return value; }
});
আইআই 5-7 এর জন্য onpropertychange
কেবল ইভেন্ট রয়েছে, যা ডিওএম উপাদানগুলির জন্য কাজ করে, তবে অন্যান্য বস্তুর জন্য নয়।
পদ্ধতির অপূর্ণতা হ'ল আপনি কেবল পূর্বনির্ধারিত বৈশিষ্ট্যের সেটগুলির অনুরোধগুলিতে ঝুঁকতে পারেন, কোনও পূর্বনির্ধারিত নাম ব্যতীত স্বেচ্ছাসেবী সম্পত্তিতে নয়।
obj['any_key'] = 123;
তবে আমি আপনার কোডে যা দেখছি তার জন্য কোনও (এখনও জানা যায়নি) কীটির জন্য আমাকে সেটার / গেটর সংজ্ঞায়িত করতে হবে। যে অসম্ভব.
যেমন ব্যাখ্যা করেছেন আপনি এখানে প্রক্সি ব্যবহার করতে হবে, কিন্তু এটা শেষ পর্যন্ত একটি বর্গ একত্রিত করা যেতে পারে কন্সট্রাকটর
return new Proxy(this, {
set: function( target, name, value ) {
...}};
এর সাথে'. তারপরে সেট অ্যান্ড গেট (ডিলিটপ্রোপার্টি) ফাংশনগুলিতে আগুন লাগবে। যদিও আপনি একটি প্রক্সি অবজেক্ট পেয়েছেন যা বেশিরভাগ অংশের তুলনায় এটির চেয়ে পৃথক বলে মনে হয় (টার্গেট.constructor === মাই ক্লাস) এটি শ্রেণীর ধরণের ইত্যাদি [[যদিও এটি এমন একটি ফাংশন যেখানে টার্গেট.constructor.name শ্রেণীর নাম পাঠ্য (কিছুটা পৃথকভাবে কাজ করে এমন উদাহরণগুলির উল্লেখ করা ing)
সুতরাং আপনি আশা করছেন ভেরার মতো কিছু করুন = MyClassInstance [4]; ? যদি তা হয় তবে সরল উত্তরটি হ'ল জাভাস্ক্রিপ্ট বর্তমানে অপারেটর ওভারলোডিং সমর্থন করে না।
এটির জন্য একটি স্পিচী উপায় হ'ল ভাষা নিজেই প্রসারিত করা।
একটি কাস্টম ইনডেক্সিং কনভেনশন সংজ্ঞায়িত করুন, আসুন একে কল করুন, "[]"।
var MyClass = function MyClass(n) {
this.myArray = Array.from(Array(n).keys()).map(a => 0);
};
Object.defineProperty(MyClass.prototype, "[]", {
value: function(index) {
return this.myArray[index];
}
});
...
var foo = new MyClass(1024);
console.log(foo["[]"](0));
একটি নতুন eval বাস্তবায়ন সংজ্ঞায়িত। (এইভাবে করবেন না, তবে এটি ধারণার প্রমাণ)।
var MyClass = function MyClass(length, defaultValue) {
this.myArray = Array.from(Array(length).keys()).map(a => defaultValue);
};
Object.defineProperty(MyClass.prototype, "[]", {
value: function(index) {
return this.myArray[index];
}
});
var foo = new MyClass(1024, 1337);
console.log(foo["[]"](0));
var mini_eval = function(program) {
var esprima = require("esprima");
var tokens = esprima.tokenize(program);
if (tokens.length == 4) {
var types = tokens.map(a => a.type);
var values = tokens.map(a => a.value);
if (types.join(';').match(/Identifier;Punctuator;[^;]+;Punctuator/)) {
if (values[1] == '[' && values[3] == ']') {
var target = eval(values[0]);
var i = eval(values[2]);
// higher priority than []
if (target.hasOwnProperty('[]')) {
return target['[]'](i);
} else {
return target[i];
}
return eval(values[0])();
} else {
return undefined;
}
} else {
return undefined;
}
} else {
return undefined;
}
};
mini_eval("foo[33]");
উপরেরগুলি আরও জটিল সূচকগুলির জন্য কাজ করবে না তবে এটি শক্তিশালী বিশ্লেষণের সাথে হতে পারে।
আপনার নিজের সুপারসেট ভাষা তৈরির আশ্রয় না করে আপনি পরিবর্তে বিদ্যমান ভাষায় আপনার স্বরলিপিটি সংকলন করতে পারেন, তারপরে এটিকে ব্যাখ্যা করুন। এটি প্রথমবার ব্যবহার করার পরে নেটিভকে পার্সিং ওভারহেড হ্রাস করে।
var compile = function(program) {
var esprima = require("esprima");
var tokens = esprima.tokenize(program);
if (tokens.length == 4) {
var types = tokens.map(a => a.type);
var values = tokens.map(a => a.value);
if (types.join(';').match(/Identifier;Punctuator;[^;]+;Punctuator/)) {
if (values[1] == '[' && values[3] == ']') {
var target = values[0];
var i = values[2];
// higher priority than []
return `
(${target}['[]'])
? ${target}['[]'](${i})
: ${target}[${i}]`
} else {
return 'undefined';
}
} else {
return 'undefined';
}
} else {
return 'undefined';
}
};
var result = compile("foo[0]");
console.log(result);
console.log(eval(result));
আমরা প্রক্সি পেতে পারি | সরাসরি পদ্ধতি সেট করুন । দ্বারা অনুপ্রাণিত এই ।
class Foo {
constructor(v) {
this.data = v
return new Proxy(this, {
get: (obj, key) => {
if (typeof(key) === 'string' && (Number.isInteger(Number(key)))) // key is an index
return obj.data[key]
else
return obj[key]
},
set: (obj, key, value) => {
if (typeof(key) === 'string' && (Number.isInteger(Number(key)))) // key is an index
return obj.data[key] = value
else
return obj[key] = value
}
})
}
}
var foo = new Foo([])
foo.data = [0, 0, 0]
foo[0] = 1
console.log(foo[0]) // 1
console.log(foo.data) // [1, 0, 0]