国产成人精品久久免费动漫-国产成人精品天堂-国产成人精品区在线观看-国产成人精品日本-a级毛片无码免费真人-a级毛片毛片免费观看久潮喷

您的位置:首頁技術(shù)文章
文章詳情頁

JavaScript 面向?qū)ο蟪绦蛟O(shè)計詳解【類的創(chuàng)建、實例對象、構(gòu)造函數(shù)、原型等】

瀏覽:4日期:2023-10-28 09:13:28

本文實例講述了JavaScript 面向?qū)ο蟪绦蛟O(shè)計。分享給大家供大家參考,具體如下:

類的創(chuàng)建于實例對象工廠模型創(chuàng)建對象

function CreatePerson ( name,sex,age ) { var obj = new Object(); obj.name = name; obj.sex = sex; obj.age = age; obj.sayName = function () { console.log( this.name ); } return obj; }var p1 = CreatePerson(’zf’,’女’,22);p1.sayName(); //zfconsole.log( p1.name ); //zf構(gòu)造函數(shù)式

//函數(shù)的第一個字母大寫(類的模板)function Person ( name,age,sex ) { this.name = name; this.age = age; this.sex =sex; this.sayName = function () { alert(this.name); } }//構(gòu)造一個對象, 使用new關(guān)鍵字, 傳遞參數(shù), 執(zhí)行模板代碼, 返回對象。var p1 = new Person(’zf’,20,’女’); //類的概念:根據(jù)模板創(chuàng)建出不同的實例對象 console.log( p1.name );p1.sayName();

創(chuàng)建類的實例:

當作構(gòu)造函數(shù)去使用

var p1 = new Person(’a1’,20);

作為普通函數(shù)去調(diào)用

Person(’a2’,20); //在全局環(huán)境中定義屬性并賦值, 直接定義在window上。

在另個一對象的作用域中調(diào)用

var o = new Object(); Person.call(o,’a3’,23);

Object每個實例都會具有的屬性和方法:

Constructor: 保存著用于創(chuàng)建當前對象的函數(shù)。(構(gòu)造函數(shù))hasOwnProperty(propertyName):用于檢測給定的屬性在當前對象實例中(而不是原型中)是否存在。isPrototypeOf(Object): 用于檢查傳入的對象是否是另外一個對象的原型。propertyIsEnumerable(propertyName):用于檢查給定的屬性是否能夠使用for-in語句來枚舉。toLocaleString():返回對象的字符串表示。該字符串與執(zhí)行環(huán)境的地區(qū)對應(yīng).toString():返回對象的字符串表示。valueOf():返回對象的字符串、數(shù)值或布爾表示。

判斷一個對象是不是另一個對象的實例,通常使用的是 instanceof. 比較少使用constructor。

原型

創(chuàng)建每一個函數(shù)的時候,都有一個prototype屬性. 這個是屬性,是一個指針。而這個對象總是指向一個對象。這個對象 的用途就是將特定的屬性和方法包含在內(nèi),是一個實例對象, 起到了一個所有實例所共享的作用。屏蔽了,構(gòu)造函數(shù)的缺點,new 一個對象,就把構(gòu)造函數(shù)內(nèi)的方法實例化一次。

function Person () { }var obj = Person.prototype;console.log( obj ); //Person.prototype 就是一個對象//Person.prototype 內(nèi)部存在指針,指針指向一個對象。 這個對象稱之為:原型對象。原型對象,被所有的實例對象所共享。console.log( obj.constructor ); //function Person(){} //obj這個對象的構(gòu)造器就是 Person

原型圖例:

JavaScript 面向?qū)ο蟪绦蛟O(shè)計詳解【類的創(chuàng)建、實例對象、構(gòu)造函數(shù)、原型等】

console.log(Person.prototype) 的結(jié)果:

JavaScript 面向?qū)ο蟪绦蛟O(shè)計詳解【類的創(chuàng)建、實例對象、構(gòu)造函數(shù)、原型等】

常用方法Object.getPrototypeOf()

根據(jù)實例對象獲得原型對象

每次代碼讀取一個對象的屬性的時候:首先會進行一次搜索,搜索實例對象里,看看是否存在,如果沒有,再去實例所對的原型中尋找屬性.如果有則返回,如果兩次都沒有則返回undefined

function Person () {}Person.prototype.name = ’z1’;Person.prototype.age = 20;Person.prototype.sayName = function () { console.log( ’我是原型對象方法’ ); }var p1 = new Person();console.log( p1.name ); //z1console.log( Object.getPrototypeOf(p1) ); console.log( Object.getPrototypeOf(p1) == Person.prototype ); //truehasOwnProperty()

判斷是否是 實例對象自己的屬性

function Person () {}Person.prototype.name = ’z1’;Person.prototype.age = 20;Person.prototype.sayName = function () { console.log( ’我是原型對象方法’ ); }// 判斷一個對象屬性 是屬于 原型屬性 還是屬性 實例屬性var p3 = new Person(); console.log( p3.name ); //zf 是原型上的//hasOwnProperty() 是否是 實例對象自己的屬性 console.log( p3.hasOwnProperty(’name’) ); //false in 操作符

無論是 原型的屬性, 還是實例對象的屬性, 都區(qū)分不開。 如果存在,返回true

function Person () {}Person.prototype.name = ’z1’;Person.prototype.age = 20;Person.prototype.sayName = function () { console.log( ’我是原型對象方法’ ); }//判斷屬性是否存在 實例對象 和 原型對象中. var p1 = new Person();console.log(’name’ in p1); //true //表示,name的屬性到底在不在p1的屬性中 truevar p2 = new Person();p1.name = ’zzz’;console.log(’name’ in p1); //true

判斷一個屬性是否在原型中

function Person () {}Person.prototype.name = ’z1’;Person.prototype.age = 20;Person.prototype.sayName = function () { console.log( ’我是原型對象方法’ ); }//判斷屬性是否存在 實例對象 和 原型對象中. var p1 = new Person();p1.name = ’123’;//在原型對象中,是否存在這個值//@obj 當前對象//@判斷的屬性function hasPrototypeProtoperty ( obj,attrName ) { return !obj.hasOwnProperty(attrName) && (attrName in obj); }console.log( hasPrototypeProtoperty(p1,’name’) ); //falseObject.keys()

function Person () {}Person.prototype.name = ’z1’;Person.prototype.age = 20;Person.prototype.sayName = function () { console.log( ’我是原型對象方法’ ); }//ECMA5新特性 Object.keys(); //拿到當前對象中的所有keys, 返回一個數(shù)組var p1 = new Person();p1.name = ’zz’;p1.age = 20;var attr = Object.keys(p1);console.log( attr ); //['name', 'age']var attr2 = Object.keys(p1.__proto__); console.log( attr2 ); //['name', 'age', 'sayName']var attr3 = Object.keys(Person.prototype); console.log( attr3 ); //['name', 'age', 'sayName']Object.getOwnPropertyNames()

function Person () {}Person.prototype.name = ’z1’;Person.prototype.age = 20;Person.prototype.sayName = function () { console.log( ’我是原型對象方法’ ); }var p1 = new Person();p1.name = ’zz’;p1.age = 20;//ECMA5 //constructor屬性,是無法被枚舉的. 正常的for-in循環(huán)是無法枚舉. [eable = false];//Object.getOwnPropertyNames(); //枚舉對象所有的屬性:不管該內(nèi)部屬性能夠被枚舉.var attr4 = Object.getOwnPropertyNames(Person.prototype); //['constructor', 'name', 'age', 'sayName']console.log( attr3 );isPrototypeOf()

判斷原型的方法

原型對象.isPrototypeOf(new instance);

實現(xiàn)each方法

原型的另外一個作用就是擴展對象中的屬性和方法

//遍歷多維數(shù)組var arr = [1,2,4,5,[455,[456,[345345]]]];Array.prototype.each = function ( cb ) { try { //計數(shù)器 this.i || (this.i = 0); //核心代碼 if ( this.length > 0 && cb.constructor === Function ) { while ( this.i < this.length ) { //計數(shù)器 大于 數(shù)組長度跳出 //獲得每一項值 var e = this[this.i]; //判斷是否是 數(shù)組 if ( e && e.constructor === Array ) { //遞歸 e.each(cb); } else { cb.call(null,e); } this.i++; } //使用完之后,釋放變量 this.i = null; } } catch (e) { //do someting } return this;};arr.each(function( val ){ console.log(val);});簡單原型

直接通過對象字面量來重寫整個原型對象(這種方法會改變原型對象的構(gòu)造器[改變?yōu)镺bject])

//簡單原型 function Person () { }Person.prototype = { constructor: Person, //原型的構(gòu)造器改變 name: ’zz’, age: 20, say: function () { console.log( this.age ); } }var p1 = new Person();console.log( p1.name );p1.say();

存在的問題,constructor屬性是無法被枚舉的。加在原型對象上,可以被枚舉,被枚舉。不符合要求。

ECMA5中的Object.defineProperty()方法可以為原型對象重新加入構(gòu)造器。constructor問題可以被避免。

//3個參數(shù), 參數(shù)1:重新設(shè)置構(gòu)造的對象 (給什么對象設(shè)置) 參數(shù)2:設(shè)置什么屬性 參數(shù)3:options配置項 (要怎么去設(shè)置)Object.defineProperty(Person.prototype,’constructor’,{ enumerable: false, //是否是 能夠 被枚舉 value: Person //值 構(gòu)造器的 引用});

原型的動態(tài)特性

注意原型和創(chuàng)建實例的前后順序

function Person () { }var p1 = new Person(); // {} Person.prototype = { constructor: Person, name: ’zf’, age: 20, say: function () { console.log(’原型’); }}//先把原型對象寫好,然后再實例化。//p1.say(); //error 因為 原型對象里面沒有任何屬性和方法var p2 = new Person();p2.say();//注意 簡單原型使用的順序(實例對象必須在原型對象之后創(chuàng)建)原型對象的常用開發(fā)模式組合構(gòu)造函數(shù)式和原型模式

function Person( name,age,firends ) { this.name = name; this.age = age; this.firends = firends; }Person.prototype = { constructor: Person, sayName: function () { console.log( this.name ); }}var p1 = new Person(’zz’,20,[’zf’]);var p2 = new Person(’zx’,22,[’z1’]);console.log( p1.firends ); //[’zf’] console.log( p2.firends ); //[’z1’]動態(tài)原型模式

就是把信息都封裝到函數(shù)中,這樣體現(xiàn)了封裝的概念。

//動態(tài)原型模式:(讓你的代碼 都封裝到一起)function Person( name,age,firends ) { this.name = name; this.age = age; this.firends = firends; //動態(tài)原型方法 if ( typeof this.sayName !== ’function’ ) { Person.prototype.sayName = function () { console.log(this.name); } } }穩(wěn)妥構(gòu)造函數(shù)式

穩(wěn)妥模式就是沒有公共屬性,而且其他方法也不引用this對象,穩(wěn)妥模式最適合在安全的環(huán)境中使用。如果程序?qū)τ诎踩砸蠛芨撸敲捶浅_m合這種模式。也不能使用new關(guān)鍵字。

//穩(wěn)妥構(gòu)造函數(shù)式 durable object (穩(wěn)妥對象)//1,沒有公共的屬性//2,不能使用this對象function Person ( name,age ) { //創(chuàng)建一個要返回的對象。 利用工廠模式思維。 var obj = new Object(); //可以定義一下是有的變量和函數(shù) private var name = name || ’zf’; // var sex = ’女’;// var sayName = function () {// } //添加一個對外的方法 obj.sayName = function () { console.log(name); } return obj; }var p1 = Person(’xixi’,20);p1.sayName(); 深入原型繼承的概念

如果讓原型對象等于另一個類型的實例,結(jié)果會怎么樣呢?顯然此時的原型對象將包含一個指向另一個原型的指針,相應(yīng)的另一個原型中也包含著一個指向另一個構(gòu)造函數(shù)的指針。

原型鏈: 利用原型讓一個引用類型繼承另外一個引用類型的屬性和方法。

構(gòu)造函數(shù) 原型對象 實例對象

構(gòu)造函數(shù).prototype = 原型對象

原型對象.constructor = 構(gòu)造函數(shù)

實例對象.__proto__ = 原型對象

原型對象.isPrototypeOf(實例對象)

構(gòu)造函數(shù) 實例對象 (類和實例)

isPrototypeOf(); //判斷是否 一個對象的 原型

JavaScript 面向?qū)ο蟪绦蛟O(shè)計詳解【類的創(chuàng)建、實例對象、構(gòu)造函數(shù)、原型等】

//父類的構(gòu)造函數(shù) Supfunction Sup ( name ) { this.name = name; }//父類的原型對象Sup.prototype = { constructor: Sup, sayName: function () { console.log(this.name); }}//子類的構(gòu)造函數(shù) Subfunction Sub ( age ) { this.age = age; }//如果子類的原型對象 等于 父類的 實例//1, 顯然此時的原型對象將包含一個指向另一個原型的指針//2, 相應(yīng)的另一個原型中也包含著一個指向另一個構(gòu)造函數(shù)的指針。// 實例對象.__proto__ = 原型對象// Sup的實例對象 和 Sup的原型對象 有一個關(guān)系Sub.prototype = new Sup(’zf’);// console.log( Sub.prototype.constructor ); //function Sup () {}// // console.log( Sub.prototype.__proto__ ); //Sup 的 原型對象var sub1 = new Sub(20);console.log( sub1.name ); //zfsub1.sayName(); //zf

原型鏈繼承映射圖

JavaScript 面向?qū)ο蟪绦蛟O(shè)計詳解【類的創(chuàng)建、實例對象、構(gòu)造函數(shù)、原型等】

JavaScript 面向?qū)ο蟪绦蛟O(shè)計詳解【類的創(chuàng)建、實例對象、構(gòu)造函數(shù)、原型等】

繼承的三種方式原型繼承

//原型繼承的特點://即繼承了父類的模板,又繼承了父類的原型對象。 (全方位的繼承)//父類function Person ( name,age ) { this.name = name; this.age = age; }Person.prototype.id = 10;//子類function Boy ( sex ) { this.sex = sex; }//原型繼承Boy.prototype = new Person(’zz’);var b = new Boy();console.log( b.name ); //zzconsole.log( b.id ); //10類繼承

類繼承 (只繼承模板) 不繼承原型對象 (借用構(gòu)造函數(shù)的方式繼承)

//父類function Person ( name,age ) { this.name = name; this.age = age; }Person.prototype.id = 10;//子類function Boy ( name,age,sex ) { //類繼承 Person.call(this,name,age); this.sex = sex; }var b = new Boy(’zf’,20,’女’);console.log( b.name ); //zfconsole.log( b.age ); //20console.log( b.sex ); //女console.log( b.id ); //父類的原型對象并沒有繼承過來. 混合繼承

原型繼承+類繼承

//父類 (關(guān)聯(lián)父類和子類的關(guān)系)function Person ( name,age ) { this.name = name; this.age = age; }Person.prototype.id = 10;Person.prototype.sayName = function () { console.log( this.name );}//子類function Boy ( name,age,sex ) { //1 類繼承 Person.call(this,name,age); //繼承父類的模板 this.sex = sex; } //2 原型繼承//父類的實例 和 父類的 原型對象的關(guān)系.Boy.prototype = new Person(); //繼承父類的原型對象var b = new Boy(’z1’,20,’女’);console.log( b.name );//z1console.log( b.sex ); //女console.log( b.id ); //10b.sayName(); //z1 ExtJs底層繼承方式

模擬ExtJs底層繼承一部分代碼

//ExtJs 繼承//2件事: 繼承了1次父類的模板,繼承了一次父類的原型對象function Person ( name,age ) { this.name = name; this.age = age; }Person.prototype = { constructor: Person, sayHello: function () { console.log(’hello world!’); } }function Boy ( name,age,sex ) { //call 綁定父類的模板函數(shù) 實現(xiàn) 借用構(gòu)造函數(shù)繼承 只復(fù)制了父類的模板 // Person.call(this,name,age); Boy.superClass.constructor.call(this,name,age); this.sex = sex; }//原型繼承的方式: 即繼承了父類的模板,又繼承了父類的原型對象。// Boy.prototype = new Person();//只繼承 父類的原型對象 extend(Boy,Person); // 目的 只繼承 父類的原型對象 , 需要那兩個類產(chǎn)生關(guān)聯(lián)關(guān)系.//給子類加了一個原型對象的方法。Boy.prototype.sayHello = function () { console.log(’hi,js’); }var b = new Boy(’zf’,20,’男’);console.log( b.name );console.log( b.sex );b.sayHello(); Boy.superClass.sayHello.call(b);//extend方法//sub子類, sup 父類function extend ( sub,sup ) { //目的, 實現(xiàn)只繼承 父類的原型對象。 從原型對象入手 //1,創(chuàng)建一個空函數(shù), 目的:空函數(shù)進行中轉(zhuǎn) var F = new Function(); // 用一個空函數(shù)進行中轉(zhuǎn)。 // 把父類的模板屏蔽掉, 父類的原型取到。 F.prototype = sup.prototype; //2實現(xiàn)空函數(shù)的原型對象 和 超類的原型對象轉(zhuǎn)換 sub.prototype = new F(); //3原型繼承 //做善后處理。 還原構(gòu)造器 , sub.prototype.constructor = sub; //4 ,還原子類的構(gòu)造器 // 保存一下父類的原型對象 // 因為 ①方便解耦, 減低耦合性 ② 可以方便獲得父類的原型對象 sub.superClass = sup.prototype; //5 ,保存父類的原型對象。 //自定義一個子類的靜態(tài)屬性 , 接受父類的原型對象。 //判斷父類的原型對象的構(gòu)造器, (防止簡單原型中給更改為 Object) if ( sup.prototype.constructor == Object.prototype.constructor ) { sup.prototype.constructor = sup; //還原父類原型對象的構(gòu)造器 } }

感興趣的朋友可以使用在線HTML/CSS/JavaScript代碼運行工具:http://tools.jb51.net/code/HtmlJsRun測試上述代碼運行效果。

更多關(guān)于JavaScript相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《javascript面向?qū)ο笕腴T教程》、《JavaScript錯誤與調(diào)試技巧總結(jié)》、《JavaScript數(shù)據(jù)結(jié)構(gòu)與算法技巧總結(jié)》、《JavaScript遍歷算法與技巧總結(jié)》及《JavaScript數(shù)學(xué)運算用法總結(jié)》

希望本文所述對大家JavaScript程序設(shè)計有所幫助。

標簽: JavaScript
相關(guān)文章:
主站蜘蛛池模板: 久爱免费观看在线网站 | 欧美激情成人网 | 欧美日韩一区二区视频图片 | 国产欧美日韩综合二区三区 | 台湾三级香港三级在线理论 | 日韩高清在线二区 | 国产免费自拍 | 性感美女一级片 | 一级黄色毛片播放 | 嫩草影院在线观看网站成人 | 久久久久久久久中文字幕 | 欧美日韩视频在线第一区二区三区 | 欧美午夜在线播放 | 久久精品国产400部免费看 | 一级片aaaa | 久久免费精品视频 | 免费精品99久久国产综合精品 | 中文字幕在线视频观看 | 欧美jlzz18性欧美 | 日韩欧美不卡一区二区三区 | 亚洲网站免费观看 | 神马午夜视频 | 亚洲欧美一区二区三区 | 国产精品久久久久三级 | 欧美日本国产 | 亚洲国产成人久久综合一区77 | 欧美日韩无 | 国内精品九一在线播放 | 日本久久久久久久 | 国产91精品露脸国语对白 | 午夜在线播放免费人成无 | 亚洲天堂色网站 | 成年人午夜影院 | 日韩免费视频播播 | 国产综合在线观看 | 日本视频在线免费播放 | 在线观看亚洲视频 | 99久久精品免费看国产一区二区 | 91青草久久久久久清纯 | 成人毛片免费网站 | 一级毛片免费观看视频 |