ECMAScript ဆက်နွယ်ရာ အမျိုးအစား အစီအစဉ် ဖန်တီး
- အရှေ့စာမျက်နှာ တက်ကြွမှု အမှုလက္ခဏာ
- နောက်ပိုင်းစာမျက်နှာ JavaScript အမြင့်အစား ကျမ်းသစ်
继承机制的实现
要用 ECMAScript 实现继承机制,您可以从要继承的基类入手。所有开发者定义的类都可作为基类。出于安全原因,本地类和宿主类不能作为基类,这样可以防止公用访问编译过的浏览器级的代码,因为这些代码可以被用于恶意攻击。
ပြင်ပလိုက်သော အကြီးအကျယ် အား အချက်အလက်များ ကို ဖန်တီးပြီး အသုံးပြုနိုင်ပါသည်။ အချက်အလက်များ ကို အချက်အလက်များ ကို အချက်အလက်များ ကို အသုံးပြုနိုင်သည်။
ECMAScript သည် အခြား ဘာသာစကား ကဲ့သို့ အကြီးအကျယ်အောက်မှာ အတိုင်းအတာ မပြင်ဆင်ခဲ့ သော်လည်း အချိန်ကြာခဲ့သော် အကြီးအကျယ်အောက်မှာ အသုံးပြုခြင်း မပြုရသေးသည်။ အချိန်ကြာခဲ့သော် အကြီးအကျယ်အောက်မှာ အသုံးပြုခြင်း မပြုရသေးသည်။
ဖန်တီးထားသောအကြီးအကျယ်အောက်မှာ အဆိုပါအကြီးအကျယ်၏ အချက်အလက်များ နှင့် အမိန့်များ အား သီးသန့်ပြီး နောက်ပြီးခဲ့သည်။ အဆိုပါ အချက်အလက်များ နှင့် အမိန့်များ အား အသုံးပြုနိုင်သည်။ အဆိုပါ အကြီးအကျယ်၏ အချက်အလက်များ နှင့် အမိန့်များ ကို အဆိုပါ အကြီးအကျယ်၏ အချက်အလက်များ နှင့် အမိန့်များ ကို အသုံးပြုနိုင်သည်။
继承的方式
和其他功能一样,ECMAScript 实现继承的方式不止一种。这是因为 JavaScript 中的继承机制并不是明确规定的,而是通过模仿实现的。这意味着所有的继承细节并非完全由解释程序处理。作为开发者,你有权决定最适用的继承方式。
下面为您介绍几种具体的继承方式。
对象冒充
构想原始的 ECMAScript 时,根本没打算设计对象冒充(object masquerading)。它是在开发者开始理解函数的工作方式,尤其是如何在函数环境中使用 this 关键字后才发展出来。
其原理如下:构造函数使用 this 关键字给所有属性和方法赋值(即采用类声明的构造函数方式)。因为构造函数只是一个函数,所以可使 ClassA 构造函数成为 ClassB 的方法,然后调用它。ClassB 就会收到 ClassA 的构造函数中定义的属性和方法。例如,用下面的方式定义 ClassA 和 ClassB:
function ClassA(sColor) { this.color = sColor; this.sayColor = function () { alert(this.color); }; } function ClassB(sColor) { }
还记得吗?关键字 this 引用的是构造函数当前创建的对象。不过在这个方法中,this 指向的所属的对象。这个原理是把 ClassA 作为常规函数来建立继承机制,而不是作为构造函数。如下使用构造函数 ClassB 可以实现继承机制:
function ClassB(sColor) { this.newMethod = ClassA; this.newMethod(sColor); delete this.newMethod; }
在这段代码中,为 ClassA 赋予了方法 newMethod(请记住,函数名只是指向它的指针)。然后调用该方法,传递给它的是 ClassB 构造函数的参数 sColor。最后一行代码删除了对 ClassA 的引用,这样以后就不能再调用它。
အသစ် အခြေအား နှင့် အမျိုးသစ် စနစ်များ သို့ ကို သတ်မှတ်ထားသော အောက်ပါ အကြိမ်ကို ဖြိုဖျက်ပြီး အသုံးပြုရန် အရာရှိသည်။ အကြောင်းမှာ သတ္တုပိုင်းဆိုင်ရာ တရားဥပဒေကို ကျော်ဖြတ်ခြင်း ဖြစ်ပါသည်။
function ClassB(sColor, sName) { this.newMethod = ClassA; this.newMethod(sColor); delete this.newMethod; this.name = sName; this.sayName = function () { alert(this.name); }; }
အောက်ပါ အကျိုးသက်ရောက်ချက်ကို သေချာစွာ ပြသြီးဖြစ်ရန် အောက်ပါ အကျိုးသက်ရောက်ချက်ကို အသုံးပြုနိုင်ပါသည်။
var objA = new ClassA("blue"); var objB = new ClassB("red", "John"); objA.sayColor(); //ပြန်လည်ပေး "blue" objB.sayColor(); //ပြန်လည်ပေး "red" objB.sayName(); // ပြန်လိုက်သည့် "John"
အောက်ပါအတိုင်း အရင်းသို့ ဆက်နွယ်ပြီး သတ္တုပိုင်းဆိုင်ရာ တရားဥပဒေကို ဖော်ပြပါသည်။
ရိုးရိုးသည့် ကား အောက်ပါအတိုင်း အရင်းသို့ ဆက်နွယ်ပြီး သတ္တုပိုင်းဆိုင်ရာ တရားဥပဒေကို ဖော်ပြပါသည်။

ဥပမာ၊ ငါးရာချီ ClassX နှင့် ClassY ရှိသော်၊ ClassZ က ထိုနှစ်ခုကို ဆက်နွယ်ရန် အောက်ပါ ကုက္ခဏီကို အသုံးပြုနိုင်ပါသည်။
function ClassZ() { this.newMethod = ClassX; this.newMethod(); delete this.newMethod; this.newMethod = ClassY; this.newMethod(); delete this.newMethod; }
这里存在一个弊端,如果存在两个类 ClassX 和 ClassY 具有同名的属性或方法,ClassY 具有高优先级。因为它从后面的类继承。除这点小问题之外,用对象冒充实现多重继承机制轻而易举。
အဆိုပါ အကျိုးသားအရာတွင် အသုံးပြုသည်။
call() စက္ခု
call() စက္ခု သည် အမျိုးသား ကိုယ်စားပြု စက္ခု နှင့် အတူ အသုံးပြုသည်။ အသုံးပြုသည်။
function sayColor(sPrefix,sSuffix) { alert(sPrefix + this.color + sSuffix); }; var obj = new Object(); obj.color = "blue"; sayColor.call(obj, "The color is ", "a very nice color indeed.");
အဆိုပါ အကျိုးသားအရာတွင် ပြောင်းလဲပြီး အသုံးပြုပါ။
သင့်သည့် အောက်ပါ အရာပေါင်း ကို ပြောင်းလဲပြီး အသုံးပြုပါ။
function ClassB(sColor, sName) { //this.newMethod = ClassA; //this.newMethod(color); //delete this.newMethod; ClassA.call(this, sColor); this.name = sName; this.sayName = function () { alert(this.name); }; }
ဒါကြောင့် ကိုယ်စားပြုရာတွင် အသုံးပြုသည်။ အထူးသဖြင့် အသုံးပြုသည်။
apply() စက္ခု
apply() စက္ခု သုံးပုံသတ် ပြီး သတ္တုပုံစံ ကို အသုံးပြုသည်။ ဥပမာ:
function sayColor(sPrefix,sSuffix) { alert(sPrefix + this.color + sSuffix); }; var obj = new Object(); obj.color = "blue"; sayColor.apply(obj, new Array("The color is ", "a very nice color indeed."));
这个例子与前面的例子相同,只是现在调用的是 apply() 方法。调用 apply() 方法时,第一个参数仍是 obj,说明应该赋予 sayColor() 函数中的 this 关键字值是 obj。第二个参数是由两个字符串构成的数组,与 sayColor() 函数中的参数 sPrefix 和 sSuffix 匹配,最后生成的消息仍是 "The color is blue, a very nice color indeed.",将被显示出来。
该方法也用于替换前三行的赋值、调用和删除新方法的代码:
function ClassB(sColor, sName) { //this.newMethod = ClassA; //this.newMethod(color); //delete this.newMethod; ClassA.apply(this, new Array(sColor)); this.name = sName; this.sayName = function () { alert(this.name); }; }
同样的,第一个参数仍是 this,第二个参数是只有一个值 color 的数组。可以把 ClassB 的整个 arguments 对象作为第二个参数传递给 apply() 方法:
function ClassB(sColor, sName) { //this.newMethod = ClassA; //this.newMethod(color); //delete this.newMethod; ClassA.apply(this, arguments); this.name = sName; this.sayName = function () { alert(this.name); }; }
当然,只有超类中的参数顺序与子类中的参数顺序完全一致时才可以传递参数对象。如果不是,就必须创建一个单独的数组,按照正确的顺序放置参数。此外,还可使用 call() 方法。
原型链(prototype chaining)
继承这种形式在 ECMAScript 中原本是用于原型链的。上一章介绍了定义类的原型方式。原型链扩展了这种方式,以一种有趣的方式实现继承机制。
在上一章学过,prototype 对象是个模板,要实例化的对象都以这个模板为基础。总而言之,prototype 对象的任何属性和方法都被传递给那个类的所有实例。原型链利用这种功能来实现继承机制。
အထင်ကျေးဇူးချင်သော ပြုအုပ်စက် ပေါ်မူရင်း အဆိုပါ အမျိုးအစား ကို ပြန်လည်အစားထိုးပြီး အထဲတွင် သည် ထိုအမျိုးအစား အတွက် အခြား အပြုအမူများ ဖြစ်ကြလိမ့်မည့်နည်းလမ်းများ ဖြစ်လာကြလိမ့်မည်။
function ClassA() { } ClassA.prototype.color = "blue"; ClassA.prototype.sayColor = function () { alert(this.color); }; function ClassB() { } ClassB.prototype = new ClassA();
原型方式的神奇之处在于突出显示的蓝色代码行。这里,把 ClassB 的 prototype 属性设置成 ClassA 的实例。这很有意思,因为想要 ClassA 的所有属性和方法,但又不想逐个将它们 ClassB 的 prototype 属性。还有比把 ClassA 的实例赋予 prototype 属性更好的方法吗?
注意:调用 ClassA 的构造函数,没有给它传递参数。这在原型链中是标准做法。要确保构造函数没有任何参数。
与对象冒充相似,子类的所有属性和方法都必须出现在 prototype 属性被赋值后,因为在它之前赋值的所有方法都会被删除。为什么?因为 prototype 属性被替换成了新对象,添加了新方法的原始对象将被销毁。所以,为 ClassB 类添加 name 属性和 sayName() 方法的代码如下:
function ClassB() { } ClassB.prototype = new ClassA(); ClassB.prototype.name = ""; ClassB.prototype.sayName = function () { alert(this.name); };
可通过运行下面的例子测试这段代码:
var objA = new ClassA(); var objB = new ClassB(); objA.color = "blue"; objB.color = "red"; objB.name = "John"; objA.sayColor(); objB.sayColor(); objB.sayName();
အရင်းမြစ်ဆိုင်ရာ အကျိုးသည် သုံးစွဲခြင်း အကြောင်း အတိုင်း အပေါ်ဆိုင်ရာ အက်ဥပဒေ သုံးစွဲခြင်း မပါဘူး။ အခြား အမျိုးအစား အား သုံးစွဲထားသော အရင်းမြစ် အား အုပ်ချုပ်ထားသည်။
var objB = new ClassB(); alert(objB instanceof ClassA); //ပြန်ပေး "true" alert(objB instanceof ClassB); //ပြန်ပေး "true"
ECMAScript အက္ခရာ အကျဉ်းချုပ် အခြေအနေ တွင် ဒါဟာ အလွန် အသုံးဝင်သော အက်ဥပဒေ ဖြစ်သည်။ သို့သော် အရင်းမြစ်ဆိုင်ရာ အကျိုးသည် အပေါ်ဆိုင်ရာ အက်ဥပဒေ သုံးစွဲခြင်း မပါဘူး။
အရင်းမြစ်ဆိုင်ရာ အကျိုးသည် အသုံးပြုခြင်း မပါဘူး ပုံးပိုင်းအုပ်ချုပ်ခြင်း မပါဘူး။ သို့သော် အရင်းမြစ်ဆိုင်ရာ အကျိုးသည် အခြား အမျိုးအစား အား သုံးစွဲထားသော အရင်းမြစ် အား အုပ်ချုပ်ထားသည်။ သို့သော် အရင်းမြစ်ဆိုင်ရာ အကျိုးသည် အခြား အမျိုးအစား အား သုံးစွဲထားသော အရင်းမြစ် အား အုပ်ချုပ်ထားသည်။
ဆက်သွယ်ထားသော အုံး
ဒါဟာ အသုံးပြုထားသော အဆိုပါ တည်ဆောက်ပုံ သည် အက်ဥပဒေအား သုံးစွဲထားသည် သော်လည်း အရင်းမြစ်အား သုံးစွဲခြင်း မပါဘူး။ အရင်းမြစ်ပါဝင်မှု၏ အခြေခံ အကျိုးသည် သုံးစွဲခြင်း အကြောင်း အတိုင်း သူတို့ကို အက်ဥပဒေအား သုံးစွဲခြင်း သည် အကောင်းဆုံး အကြောင်း မဟုတ်ဘူး။ သို့သော် အရင်းမြစ်ဆိုင်ရာ ဆက်တိုက် သုံးစွဲခြင်း သည် အပေါ်ဆိုင်ရာ အက်ဥပဒေကို သုံးစွဲခြင်း မပါဘူး။ သတ္တုပညာရှင် က ဘယ်လို ရွေးချယ်မူလိုသနည်း။ အောက်ပါ အောက်ပါ အကြောင်းအရာ သည် ပို၍ ရှိသည်။
在前一章,我们曾经讲解过创建类的最好方式是用构造函数定义属性,用原型定义方法。这种方式同样适用于继承机制,用对象冒充继承构造函数的属性,用原型链继承 prototype 对象的方法。用这两种方式重写前面的例子,代码如下:
function ClassA(sColor) { this.color = sColor; } ClassA.prototype.sayColor = function () { alert(this.color); }; function ClassB(sColor, sName) { ClassA.call(this, sColor); this.name = sName; } ClassB.prototype = new ClassA(); ClassB.prototype.sayName = function () { alert(this.name); };
အခြေခံအရ အမှုလက္ခဏာ မှာ သုံးပါး ခုံးလုံး ပြန်လည်ပေးထားသည်။ ပထမဆုံး ခုံးလုံး မှာ ပထမဆုံး သုံးပါး အခုံးလုံး မှာ ClassB ကို တစ်ဦးတည်း သုံးပါး တူညီစေခြင်းဖြင့် ClassA အမျိုးအစား၏ sColor အခွင့်အရေး ကို တက်ကြွမှု ဖြင့် ကူညီစေခြင်းဖြင့် ပြုလုပ်ထားသည်။ ဒုတိယဆုံး ခုံးလုံး မှာ ဒုတိယဆုံး အခုံးလုံး မှာ ClassA အမျိုးအစား၏ prototype အမျိုးအစား၏ နည်းလမ်းကို တက်ကြွမှု ဖြင့် ကူညီစေခြင်းဖြင့် ပြုလုပ်ထားသည်။ အဆိုပါ အဆိုချက်မှာ တက်ကြွမှု ကို အသုံးပြုသော အမှုလက္ခဏာ ဖြစ်သောကြောင်းမှာ instanceof အသုံးပြုခြင်း သည် အခြေခံအရ အသုံးပြုနိုင်ပါ
အောက်ပါ အမှုလက္ခဏာ သည် အခြေခံအရ အစီအစဉ်ကို စစ်ဆေးပြီးပြီ
var objA = new ClassA("blue"); var objB = new ClassB("red", "John"); objA.sayColor(); //ပြန်လည်ပေး "blue" objB.sayColor(); //ပြန်လည်ပေး "red" objB.sayName(); //ပြန်လည်ပေး "John"
- အရှေ့စာမျက်နှာ တက်ကြွမှု အမှုလက္ခဏာ
- နောက်ပိုင်းစာမျက်နှာ JavaScript အမြင့်အစား ကျမ်းသစ်