成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

JavaScript面向?qū)ο蟮某绦蛟O(shè)計(jì)——“對(duì)象繼承”的注意要點(diǎn)

zhongmeizhi / 3002人閱讀

摘要:如繼承了這里就不必寫該方法的主要優(yōu)勢(shì)就是可以在子類型構(gòu)造函數(shù)中向超類型構(gòu)造函數(shù)傳遞參數(shù)。以上原型式繼承通常只是想讓一個(gè)對(duì)象與另一個(gè)對(duì)象保持類似的情況下,原型式繼承是完全可以勝任的。

繼承

繼承分為接口繼承實(shí)現(xiàn)繼承;接口繼承只繼承方法簽名,實(shí)現(xiàn)繼承則繼承實(shí)際的方法;由于函數(shù)沒(méi)有簽名,所以ECMAScript 中沒(méi)有接口繼承,只能依靠原型鏈來(lái)實(shí)現(xiàn)實(shí)現(xiàn)繼承。

原型鏈

基本思想是利用原型鏈讓一個(gè)引用類型繼承另一個(gè)引用類型的屬性和方法:

如:Person2.prototype 是Person1.prototype 的繼承,那么(“--->” 意為“指向”):

Person2.prototype - [[Prototype]] ---> Person1.prototype
Person2 - prototype ---> Person2
person2 - [[Prototype]] ---> Person2.prototype
//Person2.prototype 無(wú) constructor

Person1.prototype - cunstructor ---> Person1
Person1 - prototype ---> Person1.prototype
person1 - [[Prototype]] ---> Person1.prototype
具體方法

具體如何繼承呢:

function People(){}; //原始的
People.prototype.sayWorld = function(){
    return "World people"
};

function Person(){}; //繼承的
Person.prototype = new People(); //這里應(yīng)該注意要先繼承
Person.prototype.sayNation = function(){ //然后再修改prototype
    return "Chinese people"
};

var person = new Person(); //實(shí)例
console.log(person.sayNation()); //Chinese people
console.log(person.sayWorld()); //World people

一定要注意?。?!給原型添加方法的代碼一定要放在替換原型的語(yǔ)句之后?。?!

再舉個(gè)例子:

function WorldPeople(){};
WorldPeople.prototype = {
    constructor: WorldPeople,
    color: "",
    say: function(){
        return "People in the Earth."
    },
    friends: ["Oliver","Alice","Troy"]
};

function Chinese(){};
Chinese.prototype = new WorldPeople();
Chinese.prototype.color = "yellow";
Chinese.prototype.say = function(){
    return "i am Chinese."
};

var person1 = new Chinese();

console.log(person1.friends.toString());
console.log(person1.color);
console.log(person1.say());    
/*
[Log] Oliver,Alice,Troy (repetition.html, line 163)
[Log] yellow (repetition.html, line 164)
[Log] i am Chinese. (repetition.html, line 165)
*/
確定原型和實(shí)例的關(guān)系

instanceof 操作符和insPrototypeOf() 方法即可,如:

console.log(person1 instanceof Object); //true;
console.log(person1 instanceof WorldPeople); //true;
console.log(person1 instanceof Chinese); //true;

console.log(Object.prototype.isPrototypeOf(person1)); //true
console.log(WorldPeople.prototype.isPrototypeOf(person1)); //true
console.log(Chinese.prototype.isPrototypeOf(person1)); //true
謹(jǐn)慎定義方法

一定要記得,給原型添加方法的代碼一定要放在替換原型的語(yǔ)句之后!

還要記得,通過(guò)原型鏈實(shí)現(xiàn)繼承時(shí),不能使用字面兩創(chuàng)建原型方法,因?yàn)檫@樣會(huì)重寫原型鏈!

原型鏈的問(wèn)題

包含引用類型值的原型,該屬性會(huì)被所有實(shí)例共享;

在創(chuàng)建子類型的實(shí)例時(shí),不能向超類型的構(gòu)造函數(shù)中傳遞參數(shù);

對(duì)于第一種問(wèn)題:

function People(){}
People.prototype.friends = ["Alice","Oliver"];

function Person(){};
Person.prototype = new People();

var person1 = new Person();
var person2 = new People();

person1.friends.push("Troy");

console.log(person1.friends);
console.log(person2.friends); //兩者完全相同

有什么解決辦法呢:

借用構(gòu)造函數(shù)(不推薦使用)

被稱為“借用構(gòu)造函數(shù)”的技術(shù)或偽造對(duì)象或經(jīng)典繼承。如:

function People(){
    this.friends = ["Alice","Oliver"];
}

function Person(){
    People.call(this); //繼承了People
}

//這里就不必寫Person.prototype = new People()

var person1 = new Person();
var person2 = new Person();

person1.friends.push("Troy");

console.log(person1.friends); //["Alice", "Oliver", "Troy"]
console.log(person2.friends); //["Alice", "Oliver"]

該方法的主要優(yōu)勢(shì)就是可以在子類型構(gòu)造函數(shù)中向超類型構(gòu)造函數(shù)傳遞參數(shù)。

又如:

function SuperType(name){
    this.name = name;
}

function SubType(){
    SuperType.call(this,"Oliver"); //這里不僅僅繼承了SuperType,而且還向它傳遞了參數(shù)
    this.age = 18;
}

var person = new SubType();
console.log(person.name); //Oliver
console.log(person.age); //18

由于函數(shù)不可復(fù)用等問(wèn)題,不推薦使用。

組合繼承(最常用的模式)

也叫做偽經(jīng)典繼承。如:

//不通用的屬性
function SuperType(name){
    this.name = name;
    this.colors = ["Blue","Red","Black"];
}
//通用的方法
SuperType.prototype.sayName = function(){
    return (this.name);
};

//繼承屬性并新增屬性
function SubType(name,age){
    SuperType.call(this,name);//繼承屬性
    this.age = age;//新增屬性
}
//繼承方法并新增方法
SubType.prototype = new SuperType();//繼承方法
SubType.prototype.constructor = SubType;
SubType.prototype.sayAge = function(){//新增方法
    return (this.age);
};

var person1 = new SubType("Oliver",18);
var person2 = new SubType("Troy",24);
person1.colors.pop();
console.log(person1.colors);
console.log(person2.colors);
console.log(person1.sayName() + person1.sayAge());
console.log(person2.sayName() + person2.sayAge());

/*
[Log] ["Blue", "Red"] (repetition.html, line 255)
[Log] ["Blue", "Red", "Black"] (repetition.html, line 256)
[Log] Oliver18 (repetition.html, line 257)
[Log] Troy24 (repetition.html, line 258)
*/

最常用的方法。再舉個(gè)例子:

function People(name,age){
    this.name = name;
    this.age = age;
    this.friends = [];
}
People.prototype.friendsList = function(){
    document.write(this.friends.toString());
};

function Person(name,age,color,job){
    People.call(this,name,age);
    this.color = color;
    this.job = job;
}
Person.prototype = new People();
Person.prototype.constructor = Person;
Person.prototype.sayInfo = function(){
    document.write(this.name + this.age + this.color + this.job);
};

var person1 = new Person("Oliver",18,"yellow","Hero");
person1.friends.push("Alice");
person1.sayInfo(); //Oliver18yellowHero
person1.friendsList(); //Alice

var person2 = new Person("Troy",24,"White","Fighter");
person2.friends.push("Oliver","Islan");
person2.sayInfo(); //Troy24WhiteFighter
person2.friendsList(); //Oliver,Islan

平時(shí)用這個(gè)方法已經(jīng)足夠。又如:

function Cars(name){
    this.name = name;
    this.hasColor = ["blue","black"];
}
Cars.prototype.sayName = function(){
    console.log(this.name);
};

function Car(name,color){
    Cars.call(this,name);
    this.color = color;
}
Car.prototype = new Cars();
Car.prototype.constructor = Car;
Car.prototype.sayColor = function(){
    console.log(this.color);
};
var benz = new Car("Benz-C200","Black");
benz.hasColor.push("red");
benz.sayName();
benz.sayColor();
console.log(benz.hasColor);
var benz2 = new Car("Benz-C180","White");
benz2.hasColor.push("white");
benz2.sayName();
benz2.sayColor();
console.log(benz2.hasColor);    
/*
[Log] Benz-C200 (repetition.html, line 309)
[Log] Black (repetition.html, line 319)
[Log] ["blue", "black", "red"] (repetition.html, line 325)
[Log] Benz-C180 (repetition.html, line 309)
[Log] White (repetition.html, line 319)
[Log] ["blue", "black", "white"] (repetition.html, line 330)
*/

結(jié)合創(chuàng)建對(duì)象和繼承對(duì)象,來(lái)一個(gè)比較吧:

重要!

重要!

重要!

//組合使用構(gòu)造函數(shù)模式和原型模式-創(chuàng)建對(duì)象
function Person(name,age){
    this.name = name;
    this.age = age;
    this.friendsList = ["Alice","Islan"];
}
Person.prototype.friends = function(){
    console.log(this.friendsList.toString());
};

var person1 = new Person("Oliver",18);
var person2 = new Person("Troy",24);
person1.friendsList.pop();
person1.friends(); //Alice
person2.friends(); //Alice,Islan
//組合繼承-繼承對(duì)象
function Person(name,age){
    this.name = name;
    this.age = age;
    this.friendsList = ["Alice","Islan"];
}
Person.prototype.friends = function(){
    console.log(this.friendsList.toString());
};
function Info(name,age,job){
    Person.call(this,name,age);
    this.job = job;
}
Info.prototype = new Person();
Info.prototype.constructor = Info;
Info.prototype.sayJob = function(){
    console.log(this.job);
};

var person1 = new Info("Oliver",18,"Master");
var person2 = new Info("Troy",24,"Hero");
person1.friendsList.pop();
person1.friends(); //Alice
person2.friends(); //Alice,Islan
person1.sayJob(); //Master
person2.sayJob(); //Hero

對(duì)比一下,就可以看出,繼承屬性主要應(yīng)用到call 操作符給超類型構(gòu)造函數(shù)傳遞參數(shù);而繼承方法則要注意不可使用字面量語(yǔ)法。

以上

原型式繼承

通常只是想讓一個(gè)對(duì)象與另一個(gè)對(duì)象保持類似的情況下,原型式繼承是完全可以勝任的。共享相應(yīng)的引用類型的值的屬性。

語(yǔ)法是:

function object(o){
    function F(){};
    F.prototype = o;
    return new F();
}

如:

function object(o){
    function F(){};
    F.prototype = o;
    return new F();
}

var person = {
    name: "Oliver",
    friends: ["Alice","Islan"]
};

var anotherPerson = object(person);
anotherPerson.name = "Troy";
anotherPerson.friends.push("Ellen");

var yetAnotherPerson = object(person);
yetAnotherPerson.name = "Ellen";
yetAnotherPerson.friends.push("Troy","Oliver");

console.log(person.friends);

又如:

function object(o){
    function F(){};
    F.prototype = o;
    return new F();
}

var person = {
    name: "Oliver",
    friends: ["Alice","Islan"]
};

var anotherPerson = object(person);
anotherPerson.name = "Troy";
anotherPerson.friends.push("Oliver");

console.log(person.friends);["Alice", "Islan", "Oliver"]

這種方法比較簡(jiǎn)單,只是想讓person 和anotherPerson 保持類似并共享引用類型的值的屬性。

寄生式繼承(不能做到函數(shù)復(fù)用而導(dǎo)致效率降低)

創(chuàng)建一個(gè)封裝繼承過(guò)程的函數(shù)而已:

function createAnotherObj(obj){
    var clone = obj;
    clone.sayHi = function(){
        console.log("hi");
    };
    return clone;
}

var person = {
    name: "Troy",
    friends: ["Alice"]
};

var anotherObj = createAnotherObj(person);
anotherObj.sayHi();
anotherObj.name = "Oliver";
anotherObj.friends.push("Ellen");
console.log(person.friends);
console.log(anotherObj.friends); //兩個(gè)完全一樣
寄生組合式繼承(最理想的繼承范式)

基本邏輯就是首先創(chuàng)建一個(gè)超類型原型的一個(gè)副本;然后為副本添加constructor 屬性;最后把副本賦值給子類型的原型。如:

function inheritPrototype(SubType,SuperType){
    var prototype = Object(SuperType.prototype);
    prototype.constructor = SubType;
    SubType.prototype = prototype;
}

function SuperType(name){
    this.name = name;
    this.color = ["red","yellow"];
}
SuperType.prototype.list = function(){
    console.log(this.color.toString());
};

function SubType(name,age){
    SuperType.call(this,name);
    this.age = age;
}
inheritPrototype(SubType,SuperType);
SubType.prototype.sayName = function(){
    console.log(this.name);
};

var type1 = new SubType("Oliver",18);
var type2 = new SubType("Troy",24)
type2.color.pop();
type1.list(); //red,yellow
type2.list(); //red

應(yīng)該常用這種模式,比較完善。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/86266.html

相關(guān)文章

  • JavaScript面向對(duì)象

    摘要:構(gòu)造函數(shù)的兩個(gè)特征函數(shù)內(nèi)部使用了,指向所要生成的對(duì)象實(shí)例。將一個(gè)空對(duì)象的指向構(gòu)造函數(shù)的屬性,這個(gè)對(duì)象就是要返回的實(shí)例對(duì)象。用面向?qū)ο箝_發(fā)時(shí),把要生成的實(shí)例對(duì)象的特有屬性放到構(gòu)造函數(shù)內(nèi),把共有的方法放到構(gòu)造函數(shù)的里面。 JS中面向?qū)ο蟮母拍?面向?qū)ο驩OP是一種組織代碼結(jié)構(gòu)、實(shí)現(xiàn)功能過(guò)程的思維方式。它將真實(shí)世界各種復(fù)雜的關(guān)系,抽象為一個(gè)個(gè)對(duì)象,然后由對(duì)象之間的分工與合作,完成對(duì)真實(shí)世界的...

    Eirunye 評(píng)論0 收藏0
  • JavaScript面向對(duì)象程序設(shè)計(jì)——“對(duì)象基本概念”注意要點(diǎn)

    摘要:描述符對(duì)象就是上面提到的個(gè)描述其行為的特性和。真是奇怪讀取屬性的特征使用的方法,可以取得給定屬性的描述符。接收兩個(gè)參數(shù)所在的對(duì)象和要讀取其描述符的屬性名稱。 對(duì)象的基本概念 面向?qū)ο螅∣bject-Oriented,OO),的語(yǔ)言最大的特征就是它們都有類的概念,通過(guò)類可以創(chuàng)建任意多個(gè)具有相同屬性和方法的對(duì)象。 創(chuàng)建自定義對(duì)象最簡(jiǎn)單的方式就是創(chuàng)建一個(gè)Object 的實(shí)例,然后再給他添加屬...

    HmyBmny 評(píng)論0 收藏0
  • SegmentFault 技術(shù)周刊 Vol.32 - 七夕將至,你對(duì)象”還好嗎?

    摘要:很多情況下,通常一個(gè)人類,即創(chuàng)建了一個(gè)具體的對(duì)象。對(duì)象就是數(shù)據(jù),對(duì)象本身不包含方法。類是相似對(duì)象的描述,稱為類的定義,是該類對(duì)象的藍(lán)圖或原型。在中,對(duì)象通過(guò)對(duì)類的實(shí)體化形成的對(duì)象。一類的對(duì)象抽取出來(lái)。注意中,對(duì)象一定是通過(guò)類的實(shí)例化來(lái)的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 馬上就要到七夕了,離年底老媽老爸...

    李昌杰 評(píng)論0 收藏0
  • SegmentFault 技術(shù)周刊 Vol.32 - 七夕將至,你對(duì)象”還好嗎?

    摘要:很多情況下,通常一個(gè)人類,即創(chuàng)建了一個(gè)具體的對(duì)象。對(duì)象就是數(shù)據(jù),對(duì)象本身不包含方法。類是相似對(duì)象的描述,稱為類的定義,是該類對(duì)象的藍(lán)圖或原型。在中,對(duì)象通過(guò)對(duì)類的實(shí)體化形成的對(duì)象。一類的對(duì)象抽取出來(lái)。注意中,對(duì)象一定是通過(guò)類的實(shí)例化來(lái)的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 馬上就要到七夕了,離年底老媽老爸...

    Lyux 評(píng)論0 收藏0
  • SegmentFault 技術(shù)周刊 Vol.32 - 七夕將至,你對(duì)象”還好嗎?

    摘要:很多情況下,通常一個(gè)人類,即創(chuàng)建了一個(gè)具體的對(duì)象。對(duì)象就是數(shù)據(jù),對(duì)象本身不包含方法。類是相似對(duì)象的描述,稱為類的定義,是該類對(duì)象的藍(lán)圖或原型。在中,對(duì)象通過(guò)對(duì)類的實(shí)體化形成的對(duì)象。一類的對(duì)象抽取出來(lái)。注意中,對(duì)象一定是通過(guò)類的實(shí)例化來(lái)的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 馬上就要到七夕了,離年底老媽老爸...

    AaronYuan 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<