每天一篇javascript學(xué)習(xí)小結(jié)(面向?qū)ο缶幊蹋?/h1>
更新時間:2015年11月20日 08:54:09 作者:史洲宇
這篇文章主要介紹了javascript中的面向?qū)ο缶幊讨R點(diǎn),對面向?qū)ο缶幊踢M(jìn)行概述,以及各種方法進(jìn)行整理,感興趣的小伙伴們可以參考一下
1、面向?qū)ο蟮墓S方法
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");
person1.sayName(); //"Nicholas"
person2.sayName(); //"Greg"
工廠模型的方法的缺點(diǎn)是會產(chǎn)生大量重復(fù)代碼!
2、構(gòu)造函數(shù)模式創(chuàng)建對象
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");
person1.sayName(); //"Nicholas"
person2.sayName(); //"Greg"
alert(person1 instanceof Object); //true
alert(person1 instanceof Person); //true
alert(person2 instanceof Object); //true
alert(person2 instanceof Person); //true
alert(person1.constructor == Person); //true
alert(person2.constructor == Person); //true
alert(person1.sayName == person2.sayName); //false
使用new關(guān)鍵字創(chuàng)建對象會經(jīng)歷以下四個過程
- 1、創(chuàng)建一個新對象
- 2、將構(gòu)造函數(shù)的作用域賦給一個新對象(因此this就指向了這個新對象)
- 3、執(zhí)行構(gòu)造函數(shù)的方法(為這個新對象賦值)
- 4、返回新對象
3、將構(gòu)造函數(shù)當(dāng)函數(shù)用
function Person(name, age, job){
this.name = name;
this.age = age;
this.job = job;
this.sayName = function(){
alert(this.name);
};
}
var person = new Person("Nicholas", 29, "Software Engineer");
person.sayName(); //"Nicholas"
Person("Greg", 27, "Doctor"); //adds to window
window.sayName(); //"Greg"
var o = new Object();
Person.call(o, "Kristen", 25, "Nurse");
o.sayName(); //"Kristen"
構(gòu)造函數(shù)當(dāng)做函數(shù)使用就和普通的函數(shù)沒有任何不同,它屬于window對象下面添加的方法而已。由于構(gòu)造函數(shù)創(chuàng)建的對象實(shí)際上是創(chuàng)建一個新對象,因此在本質(zhì)上兩者還是不一樣的,還是分離的,他們的方法還是不一樣的!
4、將共有的方法方法全局解決不一致的問題
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");
person1.sayName(); //"Nicholas"
person2.sayName(); //"Greg"
alert(person1 instanceof Object); //true
alert(person1 instanceof Person); //true
alert(person2 instanceof Object); //true
alert(person2 instanceof Person); //true
alert(person1.constructor == Person); //true
alert(person2.constructor == Person); //true
alert(person1.sayName == person2.sayName); //true
雖然上面的方法解決了一致的問題,但是定義的全局的方法本身屬于window,那么局部和全局就沒有分開!所以這個方法使用的并不多見!也不建議使用。
5、原型模式
我們創(chuàng)建的任何的一個函數(shù)都有一個原型對象,這個屬性是一個指針,它指向一個對象,而這個對象的作用是可以有特定的類型的所有的實(shí)例共享的方法!
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); //true
alert(Person.prototype.isPrototypeOf(person1)); //true
alert(Person.prototype.isPrototypeOf(person2)); //true
//only works if Object.getPrototypeOf() is available
if (Object.getPrototypeOf){
alert(Object.getPrototypeOf(person1) == Person.prototype); //true
alert(Object.getPrototypeOf(person1).name); //"Nicholas"
}
理解原型
無論什么時候只要是創(chuàng)建了一個函數(shù),就會創(chuàng)建一個原型屬性,這個屬性指向函數(shù)的原型對象。在默認(rèn)的情況下,原型對象都會包含一個constructor(構(gòu)造函數(shù)屬性),這個屬性包含一個指向prototype屬性所在函數(shù)的指針!
屬性讀取的順序
每當(dāng)代碼讀取某個對象的屬性時候,都會執(zhí)行一次搜索,目標(biāo)是具有給定名字的屬性,搜索從對象的實(shí)例本身開始查找,如有則返回,沒有則繼續(xù)搜索該對象的原型鏈,直至搜索到原型鏈的最外層!
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();
var person2 = new Person();
person1.name = "Greg";
alert(person1.name); //"Greg" 來自實(shí)例
alert(person2.name); //"Nicholas" 來自原型
如果刪除了這個元素的實(shí)例屬性
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();
var person2 = new Person();
person1.name = "Greg";
alert(person1.name); //"Greg" ?from instance
alert(person2.name); //"Nicholas" ?from prototype
delete person1.name;
alert(person1.name); //"Nicholas" - from the prototype
6、hasOwnProperty方法
這個方法可以檢測一個屬性是否存在于實(shí)例中,還是存在于原型中!hasOwnProperty是從Object繼承來的,只要給定屬性存在于對象實(shí)例中,才會返回true.
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();
var person2 = new Person();
alert(person1.hasOwnProperty("name")); //false
alert("name" in person1); //true
person1.name = "Greg";
alert(person1.name); //"Greg" ?from instance
alert(person1.hasOwnProperty("name")); //true
alert("name" in person1); //true
alert(person2.name); //"Nicholas" ?from prototype
alert(person2.hasOwnProperty("name")); //false
alert("name" in person2); //true
delete person1.name;
alert(person1.name); //"Nicholas" - from the prototype
alert(person1.hasOwnProperty("name")); //false
alert("name" in person1); //true
7、Object.keys() 可枚舉屬性方法
這個方法接收一個對象作為參數(shù),返回一個包含所有可枚舉屬性的字符串?dāng)?shù)組
function Person(){
}
Person.prototype.name = "Nicholas";
Person.prototype.age = 29;
Person.prototype.job = "Software Engineer";
Person.prototype.sayName = function(){
alert(this.name);
};
var keys = Object.keys(Person.prototype);
alert(keys); //"name,age,job,sayName"
如果想得到所有實(shí)例的屬性,無論它是否可以枚舉都可以使用這個方法來獲取
function Person(){
}
Person.prototype.name = "Nicholas";
Person.prototype.age = 29;
Person.prototype.job = "Software Engineer";
Person.prototype.sayName = function(){
alert(this.name);
};
var keys = Object.getOwnPropertyNames(Person.prototype);
alert(keys); //"constructor,name,age,job,sayName"
此方法高版本瀏覽器才支持
8、簡單的原型寫法
function Person(){
}
Person.prototype = {
name : "Nicholas",
age : 29,
job: "Software Engineer",
sayName : function () {
alert(this.name);
}
};
var friend = new Person();
alert(friend instanceof Object); //true
alert(friend instanceof Person); //true
alert(friend.constructor == Person); //false
alert(friend.constructor == Object); //true
重寫了原型就等于將默認(rèn)的原型方法覆蓋,那么同樣的構(gòu)造方法也會被重寫,重寫的構(gòu)造方法指向了Object對象!而不是原來的對象Person
如果還是想指向之前的構(gòu)造方法,可以顯示的指定
function Person(){
}
Person.prototype = {
constructor : Person,
name : "Nicholas",
age : 29,
job: "Software Engineer",
sayName : function () {
alert(this.name);
}
};
var friend = new Person();
alert(friend instanceof Object); //true
alert(friend instanceof Person); //true
alert(friend.constructor == Person); //true
alert(friend.constructor == Object); //false
9、原型方法的動態(tài)添加
function Person(){
}
Person.prototype = {
constructor: Person,
name : "Nicholas",
age : 29,
job : "Software Engineer",
sayName : function () {
alert(this.name);
}
};
var friend = new Person();
Person.prototype.sayHi = function(){
alert("hi");
};
friend.sayHi(); //"hi" ?works!
10、原生對象的原型方法
alert(typeof Array.prototype.sort); //"function"
alert(typeof String.prototype.substring); //"function"
String.prototype.startsWith = function (text) {//修改原生對象的原型方法
return this.indexOf(text) == 0;
};
var msg = "Hello world!";
alert(msg.startsWith("Hello")); //true
11、組合使用構(gòu)造函數(shù)和原型模式創(chuàng)建對象
//構(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 () {
alert(this.name);
}
};
var person1 = new Person("Nicholas", 29, "Software Engineer");
var person2 = new Person("Greg", 27, "Doctor");
person1.friends.push("Van");
alert(person1.friends); //"Shelby,Court,Van"
alert(person2.friends); //"Shelby,Court"
alert(person1.friends === person2.friends); //false
alert(person1.sayName === person2.sayName); //true
12、動態(tài)原型模式
function Person(name, age, job){
//properties
this.name = name;
this.age = age;
this.job = job;
//methods
if (typeof this.sayName != "function"){
Person.prototype.sayName = function(){
alert(this.name);
};
}
}
var friend = new Person("Nicholas", 29, "Software Engineer");
friend.sayName();
13、寄生構(gòu)造函數(shù)模式
function Person(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 friend = new Person("Nicholas", 29, "Software Engineer");
friend.sayName(); //"Nicholas"
function SpecialArray(){
//create the array
var values = new Array();
//add the values
values.push.apply(values, arguments);
//assign the method
values.toPipedString = function(){
return this.join("|");
};
//return it
return values;
}
var colors = new SpecialArray("red", "blue", "green");
alert(colors.toPipedString()); //"red|blue|green"
alert(colors instanceof SpecialArray);
上訴方法有一點(diǎn)說明下,由于它是依賴外層對象來創(chuàng)建一個新對象,因此不能依賴 instanceof方法來確定屬性和方法的來源!它實(shí)際上和構(gòu)造函數(shù)的沒有關(guān)系!
14、穩(wěn)妥構(gòu)造函數(shù)模式
function Person(name, age, job){
var o = new Object();
o.sayName = function(){
alert(name);
};
return o;
}
var friend = Person("Nicholas", 29, "Software Engineer");
friend.sayName(); //"Nicholas"
此方法不依賴任何new this 關(guān)鍵符!如果要訪問對象的方法和屬性,只能通過對象已經(jīng)定義好的方法來獲取!
15、繼承
javascript實(shí)現(xiàn)繼承是通過原型鏈來實(shí)現(xiàn)的
function SuperType(){
this.property = true;//定義一個屬性
}
SuperType.prototype.getSuperValue = function(){//定義的原型方法
return this.property;
};
function SubType(){
this.subproperty = false;
}
//inherit from SuperType
SubType.prototype = new SuperType();
SubType.prototype.getSubValue = function (){
return this.subproperty;
};
var instance = new SubType();
alert(instance.getSuperValue()); //true
alert(instance instanceof Object); //true
alert(instance instanceof SuperType); //true
alert(instance instanceof SubType); //true
alert(Object.prototype.isPrototypeOf(instance)); //true
alert(SuperType.prototype.isPrototypeOf(instance)); //true
alert(SubType.prototype.isPrototypeOf(instance)); //true
SubType繼承SuperType的方法和屬性,因此當(dāng)instance可以直接調(diào)用SuperType的方法!
function SuperType(){
this.property = true;
}
SuperType.prototype.getSuperValue = function(){
return this.property;
};
function SubType(){
this.subproperty = false;
}
//inherit from SuperType
SubType.prototype = new SuperType();
//new method
SubType.prototype.getSubValue = function (){
return this.subproperty;
};
//override existing method
SubType.prototype.getSuperValue = function (){
return false;
};
var instance = new SubType();
alert(instance.getSuperValue()); //false
上面的例子說明,重寫的原型會覆蓋之前繼承的原型,最后返回的往往不是預(yù)期的效果
function SuperType(){
this.property = true;
}
SuperType.prototype.getSuperValue = function(){
return this.property;
};
function SubType(){
this.subproperty = false;
}
//inherit from SuperType
SubType.prototype = new SuperType();
//使用字面量添加的方法導(dǎo)致上面的方法失效了
SubType.prototype = {
getSubValue : function (){
return this.subproperty;
},
someOtherMethod : function (){
return false;
}
};
var instance = new SubType();
console.log(instance);
alert(instance.getSuperValue()); //error!
下面的例子也說明重寫原型帶來的風(fēng)險(xiǎn)
function SuperType(){
this.colors = ["red", "blue", "green"];
}
function SubType(){
}
//inherit from SuperType
SubType.prototype = new SuperType();
var instance1 = new SubType();
instance1.colors.push("black");
alert(instance1.colors); //"red,blue,green,black"
var instance2 = new SubType();
alert(instance2.colors); //"red,blue,green,black"
原型共享導(dǎo)致兩個不同的對象調(diào)用的同一個數(shù)據(jù)
16、借用構(gòu)造函數(shù)來實(shí)現(xiàn)繼承
function SuperType(){
this.colors = ["red", "blue", "green"];
}
function SubType(){
//inherit from SuperType
SuperType.call(this);
}
var instance1 = new SubType();
instance1.colors.push("black");
alert(instance1.colors); //"red,blue,green,black"
var instance2 = new SubType();
alert(instance2.colors); //"red,blue,green"
傳遞參數(shù)
function SuperType(name){
this.name = name;
}
function SubType(){
//inherit from SuperType passing in an argument
SuperType.call(this, "Nicholas");
//instance property
this.age = 29;
}
var instance = new SubType();
alert(instance.name); //"Nicholas";
alert(instance.age); //29
17、組合繼承方式
function SuperType(name){
this.name = name;
this.colors = ["red", "blue", "green"];
}
SuperType.prototype.sayName = function(){
alert(this.name);
};
function SubType(name, age){
SuperType.call(this, name);
this.age = age;
}
18、原型繼承
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");
19、寄生組合式繼承
function object(o){
function F(){}
F.prototype = o;
return new F();
}
function inheritPrototype(subType, superType){
var prototype = object(superType.prototype); //create object
prototype.constructor = subType; //augment object
subType.prototype = prototype; //assign object
}
function SuperType(name){
this.name = name;
this.colors = ["red", "blue", "green"];
}
SuperType.prototype.sayName = function(){
alert(this.name);
};
function SubType(name, age){
SuperType.call(this, name);
this.age = age;
}
inheritPrototype(SubType, SuperType);
SubType.prototype.sayAge = function(){
alert(this.age);
};
var instance1 = new SubType("Nicholas", 29);
instance1.colors.push("black");
alert(instance1.colors); //"red,blue,green,black"
instance1.sayName(); //"Nicholas";
instance1.sayAge(); //29
var instance2 = new SubType("Greg", 27);
alert(instance2.colors); //"red,blue,green"
instance2.sayName(); //"Greg";
instance2.sayAge(); //27
以上就是今天的javascript學(xué)習(xí)小結(jié),之后每天還會繼續(xù)更新,希望大家繼續(xù)關(guān)注。
您可能感興趣的文章:- js實(shí)現(xiàn)對ajax請求面向?qū)ο蟮姆庋b
- 詳解JavaScript基于面向?qū)ο笾^承實(shí)例
- 詳解JavaScript基于面向?qū)ο笾^承
- 詳解JavaScript基于面向?qū)ο笾畡?chuàng)建對象(2)
- 詳解JavaScript基于面向?qū)ο笾畡?chuàng)建對象(1)
- Javascript簡單實(shí)現(xiàn)面向?qū)ο缶幊汤^承實(shí)例代碼
- 初步了解javascript面向?qū)ο?/a>
- js面向?qū)ο笾R妱?chuàng)建對象的幾種方式(工廠模式、構(gòu)造函數(shù)模式、原型模式)
- JavaScript的面向?qū)ο缶幊袒A(chǔ)
- 簡單分析javascript面向?qū)ο笈c原型
- JavaScript面向?qū)ο笾接徐o態(tài)變量實(shí)例分析
相關(guān)文章
-
JS按條件 serialize() 對應(yīng)標(biāo)簽的使用方法
serialize()方法通過序列化表單值,創(chuàng)建標(biāo)準(zhǔn)的URL編碼文本字符串,它的操作對象是代表表單元素集合的jQuery 對象。下面通過本文給大家介紹JS按條件 serialize() 對應(yīng)標(biāo)簽的相關(guān)知識,感興趣的的朋友一起看看吧 2017-07-07
-
JavaScript reduce和reduceRight詳解
這篇文章主要介紹了JavaScript reduce和reduceRight的高級用法詳解的相關(guān)資料,需要的朋友可以參考下 2016-10-10
-
js獲得當(dāng)前時區(qū)夏令時發(fā)生和終止的時間代碼
這篇文章主要介紹了js獲得當(dāng)前時區(qū)夏令時發(fā)生和終止的時間代碼,需要的朋友可以參考下 2014-02-02
-
JavaScript實(shí)現(xiàn)通過滑塊改變網(wǎng)頁顏色
這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)通過滑塊改變網(wǎng)頁顏色,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下 2021-08-08
-
JavaScript高級程序設(shè)計(jì) 錯誤處理與調(diào)試學(xué)習(xí)筆記
JavaScript高級程序設(shè)計(jì) 錯誤處理與調(diào)試學(xué)習(xí)筆記,學(xué)習(xí)js的朋友可以參考下。 2011-09-09
-
JS判斷當(dāng)前是否平板安卓并是否支持cordova方法的示例代碼
這篇文章主要介紹了JS判斷當(dāng)前是否平板安卓并是否支持cordova方法,pc和安卓平板共用一套代碼,平板的代碼用了cordova做了一個殼子嵌套如果用了cordova就不支持elementUI中的上傳功能,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下 2022-08-08
-
swiper動態(tài)改變滑動內(nèi)容的實(shí)現(xiàn)方法
假設(shè)當(dāng)前顯示的是1,往左滑動一個遞減1,往右滑動一個遞增1。下面通過實(shí)例代碼給大家講解swiper動態(tài)改變滑動內(nèi)容的實(shí)現(xiàn)方法,感興趣的朋友一起看看吧 2018-01-01
-
js實(shí)現(xiàn)iPhone界面風(fēng)格的單選框和復(fù)選框按鈕實(shí)例
這篇文章主要介紹了js實(shí)現(xiàn)iPhone界面風(fēng)格的單選框和復(fù)選框按鈕,涉及javascript動態(tài)操作頁面元素樣式的相關(guān)技巧,非常美觀大方,需要的朋友可以參考下 2015-08-08
-
javascript和jquery分別實(shí)現(xiàn)的九九乘法表代碼
javascript 九九乘法表 附j(luò)query 實(shí)現(xiàn)的九九乘法表代碼 2010-03-03
最新評論
1、面向?qū)ο蟮墓S方法
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"); person1.sayName(); //"Nicholas" person2.sayName(); //"Greg"
工廠模型的方法的缺點(diǎn)是會產(chǎn)生大量重復(fù)代碼!
2、構(gòu)造函數(shù)模式創(chuàng)建對象
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"); person1.sayName(); //"Nicholas" person2.sayName(); //"Greg" alert(person1 instanceof Object); //true alert(person1 instanceof Person); //true alert(person2 instanceof Object); //true alert(person2 instanceof Person); //true alert(person1.constructor == Person); //true alert(person2.constructor == Person); //true alert(person1.sayName == person2.sayName); //false
使用new關(guān)鍵字創(chuàng)建對象會經(jīng)歷以下四個過程
- 1、創(chuàng)建一個新對象
- 2、將構(gòu)造函數(shù)的作用域賦給一個新對象(因此this就指向了這個新對象)
- 3、執(zhí)行構(gòu)造函數(shù)的方法(為這個新對象賦值)
- 4、返回新對象
3、將構(gòu)造函數(shù)當(dāng)函數(shù)用
function Person(name, age, job){ this.name = name; this.age = age; this.job = job; this.sayName = function(){ alert(this.name); }; } var person = new Person("Nicholas", 29, "Software Engineer"); person.sayName(); //"Nicholas" Person("Greg", 27, "Doctor"); //adds to window window.sayName(); //"Greg" var o = new Object(); Person.call(o, "Kristen", 25, "Nurse"); o.sayName(); //"Kristen"
構(gòu)造函數(shù)當(dāng)做函數(shù)使用就和普通的函數(shù)沒有任何不同,它屬于window對象下面添加的方法而已。由于構(gòu)造函數(shù)創(chuàng)建的對象實(shí)際上是創(chuàng)建一個新對象,因此在本質(zhì)上兩者還是不一樣的,還是分離的,他們的方法還是不一樣的!
4、將共有的方法方法全局解決不一致的問題
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"); person1.sayName(); //"Nicholas" person2.sayName(); //"Greg" alert(person1 instanceof Object); //true alert(person1 instanceof Person); //true alert(person2 instanceof Object); //true alert(person2 instanceof Person); //true alert(person1.constructor == Person); //true alert(person2.constructor == Person); //true alert(person1.sayName == person2.sayName); //true
雖然上面的方法解決了一致的問題,但是定義的全局的方法本身屬于window,那么局部和全局就沒有分開!所以這個方法使用的并不多見!也不建議使用。
5、原型模式
我們創(chuàng)建的任何的一個函數(shù)都有一個原型對象,這個屬性是一個指針,它指向一個對象,而這個對象的作用是可以有特定的類型的所有的實(shí)例共享的方法!
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); //true alert(Person.prototype.isPrototypeOf(person1)); //true alert(Person.prototype.isPrototypeOf(person2)); //true //only works if Object.getPrototypeOf() is available if (Object.getPrototypeOf){ alert(Object.getPrototypeOf(person1) == Person.prototype); //true alert(Object.getPrototypeOf(person1).name); //"Nicholas" }
理解原型
無論什么時候只要是創(chuàng)建了一個函數(shù),就會創(chuàng)建一個原型屬性,這個屬性指向函數(shù)的原型對象。在默認(rèn)的情況下,原型對象都會包含一個constructor(構(gòu)造函數(shù)屬性),這個屬性包含一個指向prototype屬性所在函數(shù)的指針!
屬性讀取的順序
每當(dāng)代碼讀取某個對象的屬性時候,都會執(zhí)行一次搜索,目標(biāo)是具有給定名字的屬性,搜索從對象的實(shí)例本身開始查找,如有則返回,沒有則繼續(xù)搜索該對象的原型鏈,直至搜索到原型鏈的最外層!
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(); var person2 = new Person(); person1.name = "Greg"; alert(person1.name); //"Greg" 來自實(shí)例 alert(person2.name); //"Nicholas" 來自原型
如果刪除了這個元素的實(shí)例屬性
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(); var person2 = new Person(); person1.name = "Greg"; alert(person1.name); //"Greg" ?from instance alert(person2.name); //"Nicholas" ?from prototype delete person1.name; alert(person1.name); //"Nicholas" - from the prototype
6、hasOwnProperty方法
這個方法可以檢測一個屬性是否存在于實(shí)例中,還是存在于原型中!hasOwnProperty是從Object繼承來的,只要給定屬性存在于對象實(shí)例中,才會返回true.
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(); var person2 = new Person(); alert(person1.hasOwnProperty("name")); //false alert("name" in person1); //true person1.name = "Greg"; alert(person1.name); //"Greg" ?from instance alert(person1.hasOwnProperty("name")); //true alert("name" in person1); //true alert(person2.name); //"Nicholas" ?from prototype alert(person2.hasOwnProperty("name")); //false alert("name" in person2); //true delete person1.name; alert(person1.name); //"Nicholas" - from the prototype alert(person1.hasOwnProperty("name")); //false alert("name" in person1); //true
7、Object.keys() 可枚舉屬性方法
這個方法接收一個對象作為參數(shù),返回一個包含所有可枚舉屬性的字符串?dāng)?shù)組
function Person(){ } Person.prototype.name = "Nicholas"; Person.prototype.age = 29; Person.prototype.job = "Software Engineer"; Person.prototype.sayName = function(){ alert(this.name); }; var keys = Object.keys(Person.prototype); alert(keys); //"name,age,job,sayName" 如果想得到所有實(shí)例的屬性,無論它是否可以枚舉都可以使用這個方法來獲取 function Person(){ } Person.prototype.name = "Nicholas"; Person.prototype.age = 29; Person.prototype.job = "Software Engineer"; Person.prototype.sayName = function(){ alert(this.name); }; var keys = Object.getOwnPropertyNames(Person.prototype); alert(keys); //"constructor,name,age,job,sayName"
此方法高版本瀏覽器才支持
8、簡單的原型寫法
function Person(){ } Person.prototype = { name : "Nicholas", age : 29, job: "Software Engineer", sayName : function () { alert(this.name); } }; var friend = new Person(); alert(friend instanceof Object); //true alert(friend instanceof Person); //true alert(friend.constructor == Person); //false alert(friend.constructor == Object); //true
重寫了原型就等于將默認(rèn)的原型方法覆蓋,那么同樣的構(gòu)造方法也會被重寫,重寫的構(gòu)造方法指向了Object對象!而不是原來的對象Person
如果還是想指向之前的構(gòu)造方法,可以顯示的指定
function Person(){ } Person.prototype = { constructor : Person, name : "Nicholas", age : 29, job: "Software Engineer", sayName : function () { alert(this.name); } }; var friend = new Person(); alert(friend instanceof Object); //true alert(friend instanceof Person); //true alert(friend.constructor == Person); //true alert(friend.constructor == Object); //false
9、原型方法的動態(tài)添加
function Person(){ } Person.prototype = { constructor: Person, name : "Nicholas", age : 29, job : "Software Engineer", sayName : function () { alert(this.name); } }; var friend = new Person(); Person.prototype.sayHi = function(){ alert("hi"); }; friend.sayHi(); //"hi" ?works!
10、原生對象的原型方法
alert(typeof Array.prototype.sort); //"function" alert(typeof String.prototype.substring); //"function" String.prototype.startsWith = function (text) {//修改原生對象的原型方法 return this.indexOf(text) == 0; }; var msg = "Hello world!"; alert(msg.startsWith("Hello")); //true
11、組合使用構(gòu)造函數(shù)和原型模式創(chuàng)建對象
//構(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 () { alert(this.name); } }; var person1 = new Person("Nicholas", 29, "Software Engineer"); var person2 = new Person("Greg", 27, "Doctor"); person1.friends.push("Van"); alert(person1.friends); //"Shelby,Court,Van" alert(person2.friends); //"Shelby,Court" alert(person1.friends === person2.friends); //false alert(person1.sayName === person2.sayName); //true
12、動態(tài)原型模式
function Person(name, age, job){ //properties this.name = name; this.age = age; this.job = job; //methods if (typeof this.sayName != "function"){ Person.prototype.sayName = function(){ alert(this.name); }; } } var friend = new Person("Nicholas", 29, "Software Engineer"); friend.sayName();
13、寄生構(gòu)造函數(shù)模式
function Person(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 friend = new Person("Nicholas", 29, "Software Engineer"); friend.sayName(); //"Nicholas" function SpecialArray(){ //create the array var values = new Array(); //add the values values.push.apply(values, arguments); //assign the method values.toPipedString = function(){ return this.join("|"); }; //return it return values; } var colors = new SpecialArray("red", "blue", "green"); alert(colors.toPipedString()); //"red|blue|green" alert(colors instanceof SpecialArray);
上訴方法有一點(diǎn)說明下,由于它是依賴外層對象來創(chuàng)建一個新對象,因此不能依賴 instanceof方法來確定屬性和方法的來源!它實(shí)際上和構(gòu)造函數(shù)的沒有關(guān)系!
14、穩(wěn)妥構(gòu)造函數(shù)模式
function Person(name, age, job){ var o = new Object(); o.sayName = function(){ alert(name); }; return o; } var friend = Person("Nicholas", 29, "Software Engineer"); friend.sayName(); //"Nicholas"
此方法不依賴任何new this 關(guān)鍵符!如果要訪問對象的方法和屬性,只能通過對象已經(jīng)定義好的方法來獲取!
15、繼承
javascript實(shí)現(xiàn)繼承是通過原型鏈來實(shí)現(xiàn)的
function SuperType(){ this.property = true;//定義一個屬性 } SuperType.prototype.getSuperValue = function(){//定義的原型方法 return this.property; }; function SubType(){ this.subproperty = false; } //inherit from SuperType SubType.prototype = new SuperType(); SubType.prototype.getSubValue = function (){ return this.subproperty; }; var instance = new SubType(); alert(instance.getSuperValue()); //true alert(instance instanceof Object); //true alert(instance instanceof SuperType); //true alert(instance instanceof SubType); //true alert(Object.prototype.isPrototypeOf(instance)); //true alert(SuperType.prototype.isPrototypeOf(instance)); //true alert(SubType.prototype.isPrototypeOf(instance)); //true SubType繼承SuperType的方法和屬性,因此當(dāng)instance可以直接調(diào)用SuperType的方法! function SuperType(){ this.property = true; } SuperType.prototype.getSuperValue = function(){ return this.property; }; function SubType(){ this.subproperty = false; } //inherit from SuperType SubType.prototype = new SuperType(); //new method SubType.prototype.getSubValue = function (){ return this.subproperty; }; //override existing method SubType.prototype.getSuperValue = function (){ return false; }; var instance = new SubType(); alert(instance.getSuperValue()); //false
上面的例子說明,重寫的原型會覆蓋之前繼承的原型,最后返回的往往不是預(yù)期的效果
function SuperType(){ this.property = true; } SuperType.prototype.getSuperValue = function(){ return this.property; }; function SubType(){ this.subproperty = false; } //inherit from SuperType SubType.prototype = new SuperType(); //使用字面量添加的方法導(dǎo)致上面的方法失效了 SubType.prototype = { getSubValue : function (){ return this.subproperty; }, someOtherMethod : function (){ return false; } }; var instance = new SubType(); console.log(instance); alert(instance.getSuperValue()); //error!
下面的例子也說明重寫原型帶來的風(fēng)險(xiǎn)
function SuperType(){ this.colors = ["red", "blue", "green"]; } function SubType(){ } //inherit from SuperType SubType.prototype = new SuperType(); var instance1 = new SubType(); instance1.colors.push("black"); alert(instance1.colors); //"red,blue,green,black" var instance2 = new SubType(); alert(instance2.colors); //"red,blue,green,black"
原型共享導(dǎo)致兩個不同的對象調(diào)用的同一個數(shù)據(jù)
16、借用構(gòu)造函數(shù)來實(shí)現(xiàn)繼承
function SuperType(){ this.colors = ["red", "blue", "green"]; } function SubType(){ //inherit from SuperType SuperType.call(this); } var instance1 = new SubType(); instance1.colors.push("black"); alert(instance1.colors); //"red,blue,green,black" var instance2 = new SubType(); alert(instance2.colors); //"red,blue,green"
傳遞參數(shù)
function SuperType(name){ this.name = name; } function SubType(){ //inherit from SuperType passing in an argument SuperType.call(this, "Nicholas"); //instance property this.age = 29; } var instance = new SubType(); alert(instance.name); //"Nicholas"; alert(instance.age); //29
17、組合繼承方式
function SuperType(name){ this.name = name; this.colors = ["red", "blue", "green"]; } SuperType.prototype.sayName = function(){ alert(this.name); }; function SubType(name, age){ SuperType.call(this, name); this.age = age; }
18、原型繼承
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");
19、寄生組合式繼承
function object(o){ function F(){} F.prototype = o; return new F(); } function inheritPrototype(subType, superType){ var prototype = object(superType.prototype); //create object prototype.constructor = subType; //augment object subType.prototype = prototype; //assign object } function SuperType(name){ this.name = name; this.colors = ["red", "blue", "green"]; } SuperType.prototype.sayName = function(){ alert(this.name); }; function SubType(name, age){ SuperType.call(this, name); this.age = age; } inheritPrototype(SubType, SuperType); SubType.prototype.sayAge = function(){ alert(this.age); }; var instance1 = new SubType("Nicholas", 29); instance1.colors.push("black"); alert(instance1.colors); //"red,blue,green,black" instance1.sayName(); //"Nicholas"; instance1.sayAge(); //29 var instance2 = new SubType("Greg", 27); alert(instance2.colors); //"red,blue,green" instance2.sayName(); //"Greg"; instance2.sayAge(); //27
以上就是今天的javascript學(xué)習(xí)小結(jié),之后每天還會繼續(xù)更新,希望大家繼續(xù)關(guān)注。
- js實(shí)現(xiàn)對ajax請求面向?qū)ο蟮姆庋b
- 詳解JavaScript基于面向?qū)ο笾^承實(shí)例
- 詳解JavaScript基于面向?qū)ο笾^承
- 詳解JavaScript基于面向?qū)ο笾畡?chuàng)建對象(2)
- 詳解JavaScript基于面向?qū)ο笾畡?chuàng)建對象(1)
- Javascript簡單實(shí)現(xiàn)面向?qū)ο缶幊汤^承實(shí)例代碼
- 初步了解javascript面向?qū)ο?/a>
- js面向?qū)ο笾R妱?chuàng)建對象的幾種方式(工廠模式、構(gòu)造函數(shù)模式、原型模式)
- JavaScript的面向?qū)ο缶幊袒A(chǔ)
- 簡單分析javascript面向?qū)ο笈c原型
- JavaScript面向?qū)ο笾接徐o態(tài)變量實(shí)例分析
相關(guān)文章
JS按條件 serialize() 對應(yīng)標(biāo)簽的使用方法
serialize()方法通過序列化表單值,創(chuàng)建標(biāo)準(zhǔn)的URL編碼文本字符串,它的操作對象是代表表單元素集合的jQuery 對象。下面通過本文給大家介紹JS按條件 serialize() 對應(yīng)標(biāo)簽的相關(guān)知識,感興趣的的朋友一起看看吧2017-07-07JavaScript reduce和reduceRight詳解
這篇文章主要介紹了JavaScript reduce和reduceRight的高級用法詳解的相關(guān)資料,需要的朋友可以參考下2016-10-10js獲得當(dāng)前時區(qū)夏令時發(fā)生和終止的時間代碼
這篇文章主要介紹了js獲得當(dāng)前時區(qū)夏令時發(fā)生和終止的時間代碼,需要的朋友可以參考下2014-02-02JavaScript實(shí)現(xiàn)通過滑塊改變網(wǎng)頁顏色
這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)通過滑塊改變網(wǎng)頁顏色,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-08-08JavaScript高級程序設(shè)計(jì) 錯誤處理與調(diào)試學(xué)習(xí)筆記
JavaScript高級程序設(shè)計(jì) 錯誤處理與調(diào)試學(xué)習(xí)筆記,學(xué)習(xí)js的朋友可以參考下。2011-09-09JS判斷當(dāng)前是否平板安卓并是否支持cordova方法的示例代碼
這篇文章主要介紹了JS判斷當(dāng)前是否平板安卓并是否支持cordova方法,pc和安卓平板共用一套代碼,平板的代碼用了cordova做了一個殼子嵌套如果用了cordova就不支持elementUI中的上傳功能,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2022-08-08swiper動態(tài)改變滑動內(nèi)容的實(shí)現(xiàn)方法
假設(shè)當(dāng)前顯示的是1,往左滑動一個遞減1,往右滑動一個遞增1。下面通過實(shí)例代碼給大家講解swiper動態(tài)改變滑動內(nèi)容的實(shí)現(xiàn)方法,感興趣的朋友一起看看吧2018-01-01js實(shí)現(xiàn)iPhone界面風(fēng)格的單選框和復(fù)選框按鈕實(shí)例
這篇文章主要介紹了js實(shí)現(xiàn)iPhone界面風(fēng)格的單選框和復(fù)選框按鈕,涉及javascript動態(tài)操作頁面元素樣式的相關(guān)技巧,非常美觀大方,需要的朋友可以參考下2015-08-08javascript和jquery分別實(shí)現(xiàn)的九九乘法表代碼
javascript 九九乘法表 附j(luò)query 實(shí)現(xiàn)的九九乘法表代碼2010-03-03