摘要:在創(chuàng)建子類型的實(shí)例時(shí),不能向超類型的構(gòu)造函數(shù)中傳遞參數(shù)。實(shí)際上,應(yīng)該說是沒有辦法在不影響所有對象實(shí)例的情況下,給超類型的構(gòu)造函數(shù)傳遞參數(shù)。
面向?qū)ο蟮恼Z言有一個(gè)標(biāo)志,那就是它們都有類的概念,而通過類可以創(chuàng)建任意多個(gè)具有相同屬性和方法的對象。
理解對象創(chuàng)建自定義對象的最簡單的方法就是創(chuàng)建一個(gè)Object的實(shí)例,然后再為它添加屬性和方法。例如:
var person = new Object(); person.name="Nicholas"; person.age=29; person.job="Software Engineer"; person.SayName=function(){ alert(this.name); }
同樣上面的例子可以通過對象字面量語法寫成如下:
var person ={ name:"Nicholas", age:29, person.job:"Software Engineer", SayName:function(){ alert(this.name); } }
屬性類型
ECMAScript中有兩種屬性:數(shù)據(jù)屬性和訪問器屬性。
1.數(shù)據(jù)屬性
數(shù)據(jù)屬性包含一個(gè)數(shù)據(jù)值的位置。在這個(gè)位置可以讀取和寫入值。數(shù)據(jù)屬性有四個(gè)描述其行為的特性。
Configurable:表示能否通delete刪除屬性從而重新定義屬性,能否修改屬性的特性,或者能否把屬性修改為訪問器屬性。像前面的例子中那樣直接在對象上定義屬性,它們的這個(gè)特性默認(rèn)值為true。
Enumerable:表示能否通過for-in循環(huán)返回屬性。像前面的例子中那樣直接在對象上定義屬性,它們的這個(gè)特性的默認(rèn)值為true。
Writable:表示能否修改屬性的值。前面例子直接在對象上定義的屬性,它們的這個(gè)特性默認(rèn)值為true。
Value:包含這個(gè)屬性的數(shù)據(jù)值。讀取屬性值的時(shí)候,從這個(gè)位置讀;寫入屬性值的時(shí)候,把新值保存到這個(gè)位置。這個(gè)特性默認(rèn)值為undefined。
對于前面的例子,value特性被設(shè)置為特定的值。例如:
var person={ name="Niceholas" }
這里創(chuàng)建一個(gè)名為name的屬性,為它指定的值是"Niceholas"。也就是說value特性將被設(shè)置為"Niceholas",而對這個(gè)值的任何修改都將反映在這個(gè)位置。
要修改屬性默認(rèn)的特性,必須使用ECMAScript5的Object.defineProperty()方法。這個(gè)方法接收三個(gè)參數(shù):屬性所在的對象、屬性名字和一個(gè)描述符對象。其中,描述符對象的屬性必須是Configurable、Enumerable、Writable、Value。設(shè)置其中的一或多個(gè)值??梢孕薷膶?yīng)的特性值。例如:
var person={}; Object.defineProperty(person,"name",{ writable:false, value:"Nich" }); alert(person.name);//Nich person.name="Greg"; alert(person.name);//Nich
這個(gè)例子創(chuàng)建了一個(gè)名為name的屬性,它的值為Nich是只讀的。這個(gè)屬性的值是不可以修改的,如果嘗試為它指定新值,則在非嚴(yán)格模式下,賦值操作將被忽略;在嚴(yán)格模式下,賦值操作將會(huì)拋出錯(cuò)誤。
類似的規(guī)則也適用與不可配置的屬性。例如:
var person={}; Object.defineProperty(person,"name",{ configurable:false, value:"Nich" }); alert(person.name);//Nich delete person.name; alert(person.name);//Nich
注意:一旦把屬性定義為不可配置的,就不能再把它變回可配置了。此時(shí),再調(diào)用Object.defineProperty()方法修改除了writable之外的特性,都會(huì)導(dǎo)致錯(cuò)誤。
var person={}; Object.defineProperty(person,"name",{ configurable:false, value:"Nich" }); //拋出錯(cuò)誤 Object.defineProperty(person,"name",{ configurable:true, value:"Nich" });
也就是說,多次調(diào)用Object.defineProperty()方法修改同一個(gè)屬性,但是把configurable特性設(shè)置為false之后就會(huì)有限制了。
在調(diào)用Object.defineProperty()方法時(shí),如果不指定,configurable、Enumerable和writable特性的默認(rèn)值為false。多數(shù)情況下,可能都沒有必要利用Object.defineProperty()方法提供的這些高級功能。不過,理解這些概念對于理解javascript對象卻非常有用。
注:IE8是第一個(gè)實(shí)現(xiàn)Object.defineProperty()方法的瀏覽器版本。然而,這個(gè)版本的實(shí)現(xiàn)存在諸多的限制:只能在DOM對象上使用這個(gè)方法,而且只能創(chuàng)建訪問器屬性。由于實(shí)現(xiàn)不徹底,建議不要在IE8中使用Object.defineProperty()方法。
2.訪問器屬性
訪問器屬性不包含數(shù)據(jù)值;它們包含一對兒getter和setter函數(shù)(不過,這兩個(gè)函數(shù)都不是必需的)。
在讀取訪問器屬性時(shí),會(huì)調(diào)用getter函數(shù),這個(gè)函數(shù)負(fù)責(zé)返回有效的值;在寫入訪問器屬性時(shí),會(huì)調(diào)用setter函數(shù)并傳入新值,這個(gè)函數(shù)負(fù)責(zé)決定如何處理數(shù)據(jù)。訪問器屬性有如下4個(gè)特性。
[Configurable]:表示能否通過delete刪除屬性從而重新定義屬性,能否修改屬性的特性,或者能否把屬性修改為數(shù)據(jù)屬性。對于直接在對象上定義的屬性,這個(gè)特性的默認(rèn)值為true。
[Enumerable]:表示能否通過for-in循環(huán)返回屬性。對于直接在對象上定義的屬性,這個(gè)特性默認(rèn)值為true。
[Get]:在讀取屬性時(shí)調(diào)用的函數(shù)。默認(rèn)值為undefined。
[Set]:在寫入屬性時(shí)調(diào)用的函數(shù)。默認(rèn)值為undefined。
訪問器屬性不能直接定義,必須使用Object.defineProperty()來定義。下面例子:
var book={ _year:2004, edition:1 } Object.defineProperty(book,"year",{ get:function(){ return this._year; }, set:function(newValue){ console.log(newValue); if(newValue>2004){ this._year=newValue; this.edition+=newValue-2004; } } }); book.year=2005; console.log(book.edition);//2 上面代碼創(chuàng)建了一個(gè)book對象,并給它定義兩個(gè)默認(rèn)的屬性:_year和edition。_year前面的下劃線是一種常用的記號,用于表示只能通過對象方法訪問的屬性。 支持ECMAScript5的這個(gè)方法的瀏覽器有IE9+、Firefox4+、SaFari5+、Opera12+和Chrome。在這個(gè)方法之前,要?jiǎng)?chuàng)建訪問器屬性,一般都使用兩個(gè)非標(biāo)準(zhǔn)的方法:__defineGetter__()和__defineSetter__()。這2個(gè)方法最初是由Firefox引入的,后來SaFari3、Chrome1、opera9.5也給出了相同的實(shí)現(xiàn)。使用這2個(gè)遺留的方法,可以實(shí)現(xiàn)上面的例子如下: var book={ _year:2004, edition:1 } //定義訪問器的舊有方法 book.__defineGetter__("year",function(){ return this._year; }); book.__defineSetter__("year",function(newValue){ if(newValue>2004){ this._year=newValue; this.edition+=newValue-2004; } }); book.year=2005; alert(book.edition);//2
在不支持Object.defineProperty()方法的瀏覽器中不能修改[Configurable] 和[Enumerable]。
定義多個(gè)屬性
ECMAScript5又定義了一個(gè)Object.defineProperties()方法。這個(gè)方法接收兩個(gè)對象參數(shù):第一個(gè)對象是要添加和修改其屬性的對象;第二個(gè)對象的屬性與第一個(gè)對象中添加或修改的屬性一一對應(yīng)。例如:
var book={}
Object.defineProperties(book,{ _year:{ value:2004 }, edition:{ value:1 }, year:{ get:function(){ return this._year; }, set:function(newValue){ if(newValue>2004){ this._year=newValue; this.edition+=newValue-2004; } } } })
讀取屬性的特性
var book={};
Object.defineProperties(book,{ _year:{ value:2004 }, edition:{ value:1 }, year:{ get:function(){ return this._year; }, set:function(newValue){ if(newValue>2004){ this._year=newValue; this.edition+=newValue-2004; } } } }) var descriptor=Object.getOwnPropertyDescriptor(book,"_year"); alert(descriptor.value);//2004 alert(descriptor.configurable);//false alert(typeof descriptor.get);//undefined var descriptor=Object.getOwnPropertyDescriptor(book,"year"); alert(descriptor.value);//undefined alert(descriptor.configurable);//false alert(typeof descriptor.get);//"function"創(chuàng)建對象
雖然object構(gòu)造函數(shù)或?qū)ο笞置媪慷伎梢杂脕韯?chuàng)建單個(gè)對象。但這些方式有個(gè)明顯的缺點(diǎn):使用同一個(gè)接口創(chuàng)建很多對象,會(huì)產(chǎn)生大量重復(fù)代碼。
工廠模式
function createPerson(name, age,job){ var o = new Object(); o.name = name; o.age = age; o.job = job; o.sayName = function(){ alert(this.name); } return o; } var person1 = createPerson("Nicholas", 29, "Software Engineer"); var person2 = createPerson("Greg", 27, "Doctor");
工廠模式雖然解決了創(chuàng)建多個(gè)相似對象的問題,但卻沒有解決對象識別的問題(即怎樣知道一個(gè)對象的類型)。
構(gòu)造函數(shù)模式
function Person(name, age,job){ this.name = name; this.age = age; this.job = job; this.sayName = function(){ alert(this.name); } } var person1 = new Person("Nicholas", 29, "Software Engineer"); var person2 = new Person("Greg", 27, "Doctor");
1.將構(gòu)造函數(shù)當(dāng)函數(shù)
例如前面例子中的Person函數(shù)可以用下面任何一種方式調(diào)用:
//當(dāng)成構(gòu)造函數(shù)使用 var person1 = new Person("Nicholas", 29, "Software Engineer"); person1.sayName();//Nicholas
//作為普通函數(shù)調(diào)用 Person("Greg", 27, "Doctor"); window.sayName();//Greg //在另一個(gè)對象的作用域中調(diào)用 var o=new Object(); Person.call(o,"Kristen",25,"Nurse"); o.sayName();
2.構(gòu)造函數(shù)的問題
function Person(name,age,job){ this.name = name; this.age = age; this.job = job; this.sayName = new Function("console.log(this.name)"); // 與聲明函數(shù)在邏輯上是等價(jià)的 }
以這種方法創(chuàng)建函數(shù),會(huì)導(dǎo)致不同的作用域鏈和標(biāo)示符解析。不同實(shí)例上的同名函數(shù)是不相等的。
var person1 = new Person("Nicholas", 29, "Software Engineer"); var person2 = new Person("Greg", 27, "Doctor"); console.log(person1.sayName == person2.sayName); // false
然后,創(chuàng)建兩個(gè)完成同樣任務(wù)的Function實(shí)例的確沒有必要;況且有this對象在,根本不用在執(zhí)行代碼前就把函數(shù)綁定到特定對象上面。因此,大可像下面這樣,通過把函數(shù)定義轉(zhuǎn)移到構(gòu)造函數(shù)外部來解決這個(gè)問題。
function Person(name, age,job){ this.name = name; this.age = age; this.job = job; this.sayName = sayName; } function sayName(){ alert(this.name); } var person1 = new Person("Nicholas", 29, "Software Engineer"); var person2 = new Person("Greg", 27, "Doctor");
可是新問題又來了:在全局作用域中定義的函數(shù)實(shí)際上只能被某個(gè)對象調(diào)用,這讓全局作用域有點(diǎn)名不副實(shí)。而更讓人無法接受的是:如果對象需要定義很多方法,那么就要定義很多多個(gè)全局函數(shù),于是我們這個(gè)自定義的引用類型就絲毫沒有封裝性可言了。好在,這些問題可以通過使用原型模式來解決。
原型模式
function Person(){} Person.prototype.name = "Nicholas"; Person.prototype.age = 29; Person.prototype.job = "Software Engineer"; Person.prototype.sayName = function(){ alert(this.name); } var person1 = new Person(); person1.sayName(); // Nicholas var person2 = new Person(); person2.sayName(); // Nicholas alert(person1.sayName == person2.sayName);
isPrototypeOf()
console.log(Person.prototype.isPrototypeOf(person1)); // true console.log(Person.prototype.isPrototypeOf(person2)); // true
hasOwnProperty()
function Person(){} Person.prototype.name = "Nicholas"; Person.prototype.age = 29; Person.prototype.job = "Software Engineer"; Person.prototype.sayName = function(){ console.log(this.name); } var person1 = new Person(); var person2 = new Person(); console.log(person1.hasOwnProperty("name")); // false person1.name = "Greg"; console.log(person1.name); // Greg console.log(person1.hasOwnProperty("name")); // true console.log(person2.name); // Nicholas console.log(person2.hasOwnProperty("name")); // false delete person1.name; console.log(person1.name); // Nicholas console.log(person1.hasOwnProperty("name")); // false
原型與in操作符
function Person(){} Person.prototype.name = "Nicholas"; Person.prototype.age = 29; Person.prototype.job = "Software Engineer"; Person.prototype.sayName = function(){ console.log(this.name); } var person1 = new Person(); var person2 = new Person(); console.log(person1.hasOwnProperty("name")); // false console.log("name" in person1); // true person1.name = "Greg"; console.log(person1.name); // Greg console.log(person1.hasOwnProperty("name")); // true console.log("name" in person1); // true console.log(person2.name); // Nicholas console.log(person2.hasOwnProperty("name")); // false console.log("name" in person2); // true delete person1.name; console.log(person1.name); // Nicholas console.log(person1.hasOwnProperty("name")); // false console.log("name" in person1); // true
同時(shí)使用hasOwnProperty()方法和in操作符,就可以確定該屬性到底是存在于對象中,還是存在于原型中,如下:
function hasPrototypeProperty(object,name){ return !object.hasOwnProperty(name)&&(name in object); }
只要in操作符返回true而hasOwnProperty()返回false,就可以確定屬性是原型中的屬性。
更簡單的原型語法
function Person(){} Person.prototype = { name: "Nicholas", age:29, job: "Software Engineer", sayName: function(){ console.log(this.name); } } var friend = new Person(); console.log(friend instanceof Object); // true console.log(friend instanceof Person); // true console.log(friend.constructor == Person); // false console.log(friend.constructor == Object); // true
如果constructor的值真的很重要,可以像下面這樣特意將它設(shè)置回適當(dāng)?shù)闹怠?/p>
function Person(){} Person.prototype = { constructor: Person, name: "Nicholas", age:29, job: "Software Engineer", sayName: function(){ console.log(this.name); } }
原型對象的問題
function Person(){} Person.prototype = { constructor: Person, name: "Nicholas", age:29, job: "Software Engineer", friends: ["Shelby", "Court"], sayName: function(){ console.log(this.name); } } var person1 = new Person(); var person2 = new Person(); person1.friends.push("Van"); console.log(person1.friends); //Shelby,Court,Van console.log(person2.friends); //Shelby,Court,Van console.log(person1.friends===person2.friends); // true
假如我們的初衷就是像這樣在所有實(shí)例中共享一個(gè)數(shù)組,那么對這個(gè)結(jié)果無話可說。可是,實(shí)例一般都是要有屬于自己的全部屬性的。而這個(gè)問題正是我們很少看到有人多帶帶使用原型模式的原因所在。
組合使用構(gòu)造函數(shù)模式和原型模式
function Person(name,age,job){ this.name = name; this.age = age; this.job = job; this.friends = ["Shelby", "Court"]; } Person.prototype = { constructor: Person, sayName: function(){ console.log(this.name);} } var person1 = new Person("Nicholas", 29, "Software Engineer"); var person2 = new Person("Greg", 27, "Doctor"); person1.friends.push("Van"); console.log(person1.friends); // Shelby, Count, Van console.log(person2.friends); // Shelby, Count console.log(person1.friends === person2.friends); // false console.log(person1.sayName === person2.sayName); // true
在這個(gè)例子中,實(shí)例屬性都是在構(gòu)造函數(shù)中定義的,而由所有實(shí)例共享的屬性constructor和方法sayName()則是在原型中定義的。這種構(gòu)造函數(shù)與原型混成的模式,是目前認(rèn)同度最高的一種創(chuàng)建自定義類型的方法。
動(dòng)態(tài)原型模式
function Person(name, age,job){ this.name = name; this.age = age; this.job = job; } if (typeof this.sayName!="function"){ Person.prototype.sayName = function(){ console.log(this.name); } } var friend = new Person("Nicholas",29,"Software Engineer"); friend.sayName(); //Nicholas
寄生構(gòu)造函數(shù)模式
function Person(name,age,job){ var o = new Object(); o.name = name; o.age = age; o.job = job; o.sayName = function(){ console.log(this.name); }; return o; } var friend = new Person("Nicholas", 29, "Software Engineer"); friend.sayName(); // Nicholas
關(guān)于寄生構(gòu)造函數(shù)模式,返回的對象與構(gòu)造函數(shù)或者構(gòu)造函數(shù)的原型屬性之間沒有關(guān)系;也就是說,構(gòu)造函數(shù)返回的對象與在構(gòu)造函數(shù)外部創(chuàng)建的對象沒有什么不同。
function SpecialArray(){ var values=new Array(); values.push.apply(values,arguments); values.toPipedString=function(){ return this.join("|"); } return values; } var colors=new SpecialArray("red","blue","green"); console.log(colors.toPipedString()); //red|blue|green繼承
原型鏈
function SuperType(){ this.property= true; } SuperType.prototype.getSuperValue = function(){ return this.property; }; function Subtype(){ this.subproperty = false; } // 繼承了SuperType Subtype.prototype = new SuperType(); Subtype.prototype.getSubValue = function(){ return this.subproperty; } var instance = new Subtype(); console.log(instance.getSuperValue()); // true
謹(jǐn)慎地定義方法
function SuperType(){ this.property= true; } SuperType.prototype.getSuperValue = function(){ return this.property; }; function Subtype(){ this.subproperty = false; } // 繼承了SuperType Subtype.prototype = new SuperType(); Subtype.prototype = { getSubValue: function(){ return this.subproperty; }, someOtherMethod: function(){ return false; } }; var instance = new Subtype(); console.log(instance.getSuperValue()); // error
原型鏈的問題
包含引用類型值的原型屬性會(huì)被所有實(shí)例共享;而這也正是為什么要在構(gòu)造函數(shù)中,而不是在原型對象中定義屬性的原因。
在創(chuàng)建子類型的實(shí)例時(shí),不能向超類型的構(gòu)造函數(shù)中傳遞參數(shù)。實(shí)際上,應(yīng)該說是沒有辦法在不影響所有對象實(shí)例的情況下,給超類型的構(gòu)造函數(shù)傳遞參數(shù)。
function SuperType(){ this.colors = ["red", "blue", "green"]; } function Subtype(){ } Subtype.prototype= new SuperType(); var instance1 = new Subtype(); instance1.colors.push("black"); console.log(instance1.colors); // red, blue, green, black var instance2 = new Subtype(); console.log(instance2.colors); // red, blue, green, black
傳遞參數(shù)
function SuperType(name){ this.name = name; } function Subtype(){ SuperType.call(this,"Nicholas"); this.age = 29; } var instance = new Subtype(); console.log(instance.name); //Nicholas console.log(instance.age); // 29
組合繼承
function SuperType(name){ this.name = name; this.colors = ["red", "blue", "green"]; } SuperType.prototype.sayName = function(){ console.log(this.name); }; function Subtype(name,age){ SuperType.call(this,name); this.age = age; } Subtype.prototype = new SuperType(); Subtype.prototype.sayAge = function(){ console.log(this.age); }; var instance1 = new Subtype("Nicholas", 29); instance1.colors.push("black"); console.log(instance1.colors); // red, blue, green, black instance1.sayName(); // Nicholas instance1.sayAge(); //29 var instance2 = new Subtype("Greg", 2); console.log(instance2.colors); // red, blue, green instance2.sayName(); // Greg instance2.sayAge(); //2
組合繼承避免了原型鏈和借用函數(shù)的缺陷,融合了它們的優(yōu)點(diǎn),成為Javascript中最常用的繼承模式。
原型式繼承
function object(o){ function F(){} F.prototype = o; return new F(); } var person = { name:"Nicholas", friends:["Shelby", "Court", "Van"] }; var anotherPerson = object(person); anotherPerson.name = "Greg"; anotherPerson.friends.push("Rob"); var yetAnotherPerson = object(person); yetAnotherPerson.name = "Linda"; yetAnotherPerson.friends.push("Barbie"); console.log(person.friends); // Shelby, Court, Van, Rob, Barbie
Object.create()
Object.create()方法規(guī)范了原型式繼承。
var person = { name:"Nicholas", friends:["Shelby", "Court", "Van"] }; var anotherPerson = Object.create(person); anotherPerson.name = "Greg"; anotherPerson.friends.push("Rob"); var yetAnotherPerson = Object.create(person); yetAnotherPerson.name = "Linda"; yetAnotherPerson.friends.push("Barbie"); console.log(person.friends); // Shelby, Court, Van, Rob, Barbie
寄生式繼承
function object(o){ function F(){} F.prototype = o; return new F(); } function inheritPrototype(subType,superType){ var prototype = object(superType.prototype); prototype.constructor = subType; subType.prototype = prototype; } function SuperType(name){ this.name = name; this.colors = ["red", "blue", "green"]; } SuperType.prototype.sayName = function(){ console.log(this.name); } function Subtype(name,age){ SuperType.call(this,name); this.age = age; } inheritPrototype(Subtype, SuperType); Subtype.prototype.sayAge = function(){ console.log(this.age); }
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/87657.html
摘要:繼承傳統(tǒng)的面向?qū)ο笳Z言,繼承是類與類之間的關(guān)系。原型繼承原型定義原型就是指構(gòu)造函數(shù)的屬性所引用的對象。創(chuàng)建構(gòu)造函數(shù)創(chuàng)建的實(shí)例對象張三李四就是對象的原型也是的原型在原型上創(chuàng)建一個(gè)屬性運(yùn)行和,并對比是否為同一個(gè)方法。 原文鏈接:http://www.hansmkiii.com/2018/07/06/javascript-node-1/ 面向?qū)ο?、原型、繼承 1、面向?qū)ο?1.1 什么...
摘要:三種使用構(gòu)造函數(shù)創(chuàng)建對象的方法和的作用都是在某個(gè)特殊對象的作用域中調(diào)用函數(shù)。這種方式還支持向構(gòu)造函數(shù)傳遞參數(shù)。叫法上把函數(shù)叫做構(gòu)造函數(shù),其他無區(qū)別適用情境可以在特殊的情況下用來為對象創(chuàng)建構(gòu)造函數(shù)。 一、工廠模式 工廠模式:使用字面量和object構(gòu)造函數(shù)會(huì)有很多重復(fù)代碼,在此基礎(chǔ)上改進(jìn)showImg(https://segmentfault.com/img/bVbmKxb?w=456&...
摘要:此時(shí)的原型對象包括一個(gè)指向另一個(gè)原型的指針,相應(yīng)的,另一個(gè)原型中的指向另一個(gè)構(gòu)造函數(shù)。這種關(guān)系層層遞進(jìn),就通過一個(gè)原型對象鏈接另一個(gè)構(gòu)造函數(shù)的原型對象的方式實(shí)現(xiàn)了繼承。 讀這篇之前,最好是已讀過我前面的關(guān)于對象的理解和封裝類的筆記。第6章我一共寫了3篇總結(jié),下面是相關(guān)鏈接:讀《javaScript高級程序設(shè)計(jì)-第6章》之理解對象讀《javaScript高級程序設(shè)計(jì)-第6章》之封裝類 一...
摘要:網(wǎng)上有很多前端的學(xué)習(xí)路徑文章,大多是知識點(diǎn)羅列為主或是資料的匯總,數(shù)據(jù)量讓新人望而卻步。天了解一個(gè)前端框架。也可以關(guān)注微信公眾號曉舟報(bào)告,發(fā)送獲取資料,就能收到下載密碼,網(wǎng)盤地址在最下方,獲取教程和案例的資料。 前言 好的學(xué)習(xí)方法可以事半功倍,好的學(xué)習(xí)路徑可以指明前進(jìn)方向。這篇文章不僅要寫學(xué)習(xí)路徑,還要寫學(xué)習(xí)方法,還要發(fā)資料,干貨滿滿,準(zhǔn)備接招。 網(wǎng)上有很多前端的學(xué)習(xí)路徑文章,大多是知...
摘要:繼承和前面兩篇文章中的知識非常相關(guān),如果對函數(shù)創(chuàng)建原理和原型鏈不熟悉,請猛戳高級程序設(shè)計(jì)筆記創(chuàng)建對象高級程序設(shè)計(jì)筆記原型圖解繼承,通俗的說,就是將自身不存在的屬性或方法,通過某種方式為自己所用文章分別介紹原型鏈繼承繼承借用構(gòu)造函數(shù)繼承組合繼 繼承和前面兩篇文章中的知識非常相關(guān),如果對函數(shù)創(chuàng)建原理和原型鏈不熟悉,請猛戳:《javascript高級程序設(shè)計(jì)》筆記:創(chuàng)建對象《javascri...
閱讀 4223·2021-11-22 13:52
閱讀 2114·2021-09-22 15:12
閱讀 1158·2019-08-30 15:53
閱讀 3485·2019-08-29 17:12
閱讀 2212·2019-08-29 16:23
閱讀 1693·2019-08-26 13:56
閱讀 1797·2019-08-26 13:44
閱讀 1915·2019-08-26 11:56