• <fieldset id="8imwq"><menu id="8imwq"></menu></fieldset>
  • <bdo id="8imwq"><input id="8imwq"></input></bdo>
    最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
    問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
    當前位置: 首頁 - 科技 - 知識百科 - 正文

    詳解js創建對象的幾種方法及繼承

    來源:懂視網 責編:小采 時間:2020-11-27 21:58:47
    文檔

    詳解js創建對象的幾種方法及繼承

    詳解js創建對象的幾種方法及繼承:創建對象 通過Object構造函數或對象字面量創建單個對象 這些方式有明顯的缺點:使用同一個接口創建很多對象,會產生大量的重復代碼。為了解決這個問題,出現了工廠模式。 工廠模式 考慮在ES中無法創建類(ES6前),開發人員發明了一種函數,用函數來封裝以特
    推薦度:
    導讀詳解js創建對象的幾種方法及繼承:創建對象 通過Object構造函數或對象字面量創建單個對象 這些方式有明顯的缺點:使用同一個接口創建很多對象,會產生大量的重復代碼。為了解決這個問題,出現了工廠模式。 工廠模式 考慮在ES中無法創建類(ES6前),開發人員發明了一種函數,用函數來封裝以特

    創建對象

    通過Object構造函數或對象字面量創建單個對象
    這些方式有明顯的缺點:使用同一個接口創建很多對象,會產生大量的重復代碼。為了解決這個問題,出現了工廠模式。

    工廠模式

    考慮在ES中無法創建類(ES6前),開發人員發明了一種函數,用函數來封裝以特定接口創建對象的細節。(實現起來是在一個函數內創建好對象,然后把對象返回)。

    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 0;
    }
    
    var person1=createPerson("Nicholas",29,"Software Engineer");
    var person2=createPerson("Greg",27,"Doctor");
    
    

    構造函數模式

    像Object和Array這樣的原生構造函數,在運行時會自動出現在執行環境。此外,也可以創建自定義的構造函數,從而定義自定義對象類型的屬性和方法。

    function Person(name,age,job){
     this.name=name;
     this.age=age;
     this.job=job;
     this.sayName=function(){
     alert(this.name);
     };
    }
    
    var person1=new Person(...);
    var person2=new Person(...);
    
    

    與工廠模式相比,具有以下特點:

    1. 沒有顯式創建對象;
    2. 直接將屬性和方法賦給了this對象;
    3. 沒有return語句;
    4. 要創建新實例,必須使用new操作符;(否則屬性和方法將會被添加到window對象)
    5. 可以使用instanceof操作符檢測對象類型

    構造函數的問題:

    構造函數內部的方法會被重復創建,不同實例內的同名函數是不相等的。可通過將方法移到構造函數外部解決這一問題,但面臨新問題:封裝性不好。

    原型模式

    我們創建的每個函數都有一個prototype屬性,這個屬性是一個指針,指向一個對象,而這個對象的用途是包含可以由特定類型的所有實例共享的屬性和方法。(prototype就是通過調用構造函數而創建的那個對象實例的原型對象)。
    使用原型對象的好處是可以讓所有對象實例共享它所包含的屬性和方法。換句話說,不必在構造函數中定義對象實例的信息,而是可以將這些信息直接添加到原型對象中。

    function Person(){
    }
    
    Person.prototype.name="Nicholas";
    Person.prototype.age=29;
    Person.prototype.job="...";
    Person.prototype.sayName=function(){
     ...
    };
    
    var person1=new Person();
    person1.sayName();//"Nicholas"
    
    

    更常見的做法是用一個包含所有屬性和方法的對象字面量來重寫整個原型對象,并重設constructor屬性。

    function Person(){
    }
    
    Person.prototype={
     name:"...",
     age:29,
     job:"...",
     sayName:function(){
     ...
     }
    };
    
    Object.defineProperty(Person.prototype,"constructor",{
     enumerable:false,
     value:Person,
    });
    
    

    原型對象的問題:

    他省略了為構造函數傳遞初始化參數這一環節,結果所有實例在默認情況下都將取得相同的屬性值,雖然這會在一定程度帶來一定的不便,但不是最大的問題,最大的問題是由其共享的本性所決定的。
    對于包含基本值的屬性可以通過在實例上添加一個同名屬性隱藏原型中的屬性。然后,對于包含引用數據類型的值來說,會導致問題。

    組合使用構造函數模式和原型模式

    這是創建自定義類型的最常見的方式。
    構造函數模式用于定義實例屬性,而原型模式用于定義方法和共享的屬性。所以每個實例都會有自己的一份實例屬性的副本,但同時共享著對方法的引用,最大限度的節省了內存。同時支持向構造函數傳遞參數。

    function Person(name,age,job){
     this.name=name;
     this.age=age;
     this.job=job;
     this.friends=["S","C"];
    }
    
    Person.prototype={
     constructor:Person,
     sayName:function(){
     alert(this.name);
     }
    };
    
    var person1=new Person(...);
    

    動態原型模式

    function Person(name,age,job){
     this.name=name;
     this.age=age;
     this.job=job;
    
     if(typeof this.sayName!="function"){
     Person.prototype.sayName=function(){
     alert(this.name);
     };
     }
    }
    
    

    這里只有sayName()不存在的情況下,才會將它添加到原型中,這段代碼只會在初次調用構造函數時才執行。這里對原型所做的修改,能夠立刻在所有實例中得到反映。

    Object.create()

    ES5定義了一個名為Object.create()的方法,它創建一個新對象,其中第一個參數是這個對象的原型,第二個參數對對象的屬性進行進一步描述。

    Object.create()介紹

    Object.create(null) 創建的對象是一個空對象,在該對象上沒有繼承 Object.prototype 原型鏈上的屬性或者方法,例如:toString(), hasOwnProperty()等方法

    Object.create()方法接受兩個參數:Object.create(obj,propertiesObject) ;

    obj:一個對象,應該是新創建的對象的原型。

    propertiesObject:可選。該參數對象是一組屬性與值,該對象的屬性名稱將是新創建的對象的屬性名稱,值是屬性描述符(這些屬性描述符的結構與Object.defineProperties()的第二個參數一樣)。注意:該參數對象不能是 undefined,另外只有該對象中自身擁有的可枚舉的屬性才有效,也就是說該對象的原型鏈上屬性是無效的。

    var o = Object.create(Object.prototype, {
     // foo會成為所創建對象的數據屬性
     foo: { 
     writable:true,
     configurable:true,
     value: "hello" 
     },
     // bar會成為所創建對象的訪問器屬性
     bar: {
     configurable: false,
     get: function() { return 10 },
     set: function(value) {
     console.log("Setting `o.bar` to", value);
     }
     }
    });
    console.log(o);//{foo:'hello'}
    var test1 = Object.create(null) ;
    console.log(test1);// {} No Properties 
    因為在bar中設置了configurable 使用set,get方法默認都是不起作用,所以bar值無法賦值或者獲取
    這里的o對象繼承了 Object.prototype Object上的原型方法
    我們可以 對象的 __proto__屬性,來獲取對象原型鏈上的方法 如:
    console.log(o.__proto__);//{__defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, __lookupSetter__: ƒ, …}
    console.log(test1.__proto__);//undefined
    

    通過打印發現, 將{}點開,顯示的是 No Properties ,也就是在對象本身不存在屬性跟方法,原型鏈上也不存在屬性和方法,

    new object()

    var test1 = {x:1};
    
    var test2 = new Object(test1);
    
    var test3 = Object.create(test1);
    console.log(test3);//{} 
    //test3等價于test5
    var test4 = function(){
      
    }
    test4.prototype = test1;
    var test5 = new test4();
    console.log(test5);
    console.log(test5.__proto__ === test3.__proto__);//true
    console.log(test2);//{x:1}
    
    var test1 = {};
    var test2 = new Object();
    var test3 = Object.create(Object.prototype);
    var test4 = Object.create(null);//console.log(test4.__proto__)=>undefined 沒有繼承原型屬性和方法
    console.log(test1.__proto__ === test2.__proto__);//true
    console.log(test1.__proto__ === test3.__proto__);//true
    console.log(test2.__proto__ === test3.__proto__);//true
    console.log(test1.__proto__ === test4.__proto__);//false
    console.log(test2.__proto__ === test4.__proto__);//false
    console.log(test3.__proto__ === test4.__proto__);//false
    
    

    總結:使用Object.create()是將對象繼承到__proto__屬性上

    var test = Object.create({x:123,y:345});
    console.log(test);//{}
    console.log(test.x);//123
    console.log(test.__proto__.x);//3
    console.log(test.__proto__.x === test.x);//true
    
    var test1 = new Object({x:123,y:345});
    console.log(test1);//{x:123,y:345}
    console.log(test1.x);//123
    console.log(test1.__proto__.x);//undefined
    console.log(test1.__proto__.x === test1.x);//false
    
    var test2 = {x:123,y:345};
    console.log(test2);//{x:123,y:345};
    console.log(test2.x);//123
    console.log(test2.__proto__.x);//undefined
    console.log(test2.__proto__.x === test2.x);//false
    
    

    繼承

    我這里就介紹一種吧,剩下的可以去權威指南里看去

    原型鏈

    ECMAScript 中描述了原型鏈的概念,并將原型鏈作為實現繼承的主要方法。其基本思想是利用原 型讓一個引用類型繼承另一個引用類型的屬性和方法。簡單回顧一下構造函數、原型和實例的關系:每 個構造函數都有一個原型對象,原型對象都包含一個指向構造函數的指針,而實例都包含一個指向原型 對象的內部指針。那么,假如我們讓原型對象等于另一個類型的實例,結果會怎么樣呢?顯然,此時的 原型對象將包含一個指向另一個原型的指針,相應地,另一個原型中也包含著一個指向另一個構造函數 的指針。假如另一個原型又是另一個類型的實例,那么上述關系依然成立,如此層層遞進,就構成了實 例與原型的鏈條。這就是所謂原型鏈的基本概念。

    實現原型鏈有一種基本模式,其代碼大致如下。

    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();
    alert(instance.getSuperValue());
    //true
    
    

    以上代碼定義了兩個類型:SuperType 和 SubType。每個類型分別有一個屬性和一個方法。它們 的主要區別是 SubType 繼承了 SuperType,而繼承是通過創建 SuperType 的實例,并將該實例賦給 SubType.prototype 實現的。實現的本質是重寫原型對象,代之以一個新類型的實例。換句話說,原 來存在于 SuperType 的實例中的所有屬性和方法,現在也存在于 SubType.prototype 中了。在確立了 繼承關系之后,我們給 SubType.prototype 添加了一個方法,這樣就在繼承了 SuperType 的屬性和方 法的基礎上又添加了一個新方法。這個例子中的實例以及構造函數和原型之間的關系如圖 6-4 所示。

    以上所述是小編給大家介紹的js創建對象的幾種方法及繼承詳解整合,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對腳本之家網站的支持!

    聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

    文檔

    詳解js創建對象的幾種方法及繼承

    詳解js創建對象的幾種方法及繼承:創建對象 通過Object構造函數或對象字面量創建單個對象 這些方式有明顯的缺點:使用同一個接口創建很多對象,會產生大量的重復代碼。為了解決這個問題,出現了工廠模式。 工廠模式 考慮在ES中無法創建類(ES6前),開發人員發明了一種函數,用函數來封裝以特
    推薦度:
    標簽: js 方式 三種
    • 熱門焦點

    最新推薦

    猜你喜歡

    熱門推薦

    專題
    Top
    主站蜘蛛池模板: 亚洲国产成人精品无码久久久久久综合 | 国产AV国片精品一区二区| 亚洲福利精品一区二区三区| 国产成人精品免费视频大全| 国产精品高清一区二区三区| 最新精品露脸国产在线 | 久久精品国产99国产精品澳门| 亚洲AV日韩精品久久久久| 久久久久国产精品嫩草影院| 亚洲精品你懂的| 国产亚洲精品一品区99热| 精品亚洲成a人片在线观看少妇| 亚洲国产精品成人久久蜜臀 | 亚洲国产精品尤物yw在线| 精品人妻伦九区久久AAA片69| 亚洲嫩草影院久久精品| 久久精品男人影院| 久久精品免费一区二区三区| 久久精品国产久精国产| 久久精品国产一区二区三区日韩| 国产精品无码无卡在线播放| 久久精品无码一区二区无码| 日产精品一线二线三线芒果| 真实国产精品vr专区| 亚洲精品无码久久毛片| 午夜国产精品无套| 亚洲精品国产自在久久| 在线精品亚洲一区二区| 亚洲欧洲精品无码AV| 亚洲av成人无码久久精品| 日韩一区精品视频一区二区| 亚洲国产第一站精品蜜芽| 四虎国产精品永久在线观看| 久久亚洲中文字幕精品有坂深雪 | 亚洲精品视频在线| 亚洲综合一区二区精品导航| 99爱在线视频这里只有精品| 国内精品99亚洲免费高清| 精品a在线观看| 日韩精品无码久久一区二区三| 亚洲国产综合精品中文字幕|