最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解js創(chuàng)建對象的幾種方法及繼承

 更新時間:2019年04月12日 16:05:57   作者:南果梨  
這篇文章主要介紹了js創(chuàng)建對象的幾種方法及繼承,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

創(chuàng)建對象

通過Object構(gòu)造函數(shù)或?qū)ο笞置媪縿?chuàng)建單個對象
這些方式有明顯的缺點:使用同一個接口創(chuàng)建很多對象,會產(chǎn)生大量的重復(fù)代碼。為了解決這個問題,出現(xiàn)了工廠模式。

工廠模式

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

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");

構(gòu)造函數(shù)模式

像Object和Array這樣的原生構(gòu)造函數(shù),在運行時會自動出現(xiàn)在執(zhí)行環(huán)境。此外,也可以創(chuàng)建自定義的構(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(...);
var person2=new Person(...);

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

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

構(gòu)造函數(shù)的問題:

構(gòu)造函數(shù)內(nèi)部的方法會被重復(fù)創(chuàng)建,不同實例內(nèi)的同名函數(shù)是不相等的??赏ㄟ^將方法移到構(gòu)造函數(shù)外部解決這一問題,但面臨新問題:封裝性不好。

原型模式

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

function Person(){
}

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

var person1=new Person();
person1.sayName();//"Nicholas"

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

function Person(){
}

Person.prototype={
  name:"...",
  age:29,
  job:"...",
  sayName:function(){
    ...
  }
};

Object.defineProperty(Person.prototype,"constructor",{
  enumerable:false,
  value:Person,
});

原型對象的問題:

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

組合使用構(gòu)造函數(shù)模式和原型模式

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

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(...);

動態(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(){
      alert(this.name);
    };
  }
}

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

Object.create()

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

Object.create()介紹

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

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

obj:一個對象,應(yīng)該是新創(chuàng)建的對象的原型。

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

var o = Object.create(Object.prototype, {
 // foo會成為所創(chuàng)建對象的數(shù)據(jù)屬性
 foo: { 
  writable:true,
  configurable:true,
  value: "hello" 
 },
 // bar會成為所創(chuàng)建對象的訪問器屬性
 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中設(shè)置了configurable 使用set,get方法默認都是不起作用,所以bar值無法賦值或者獲取
這里的o對象繼承了 Object.prototype Object上的原型方法
我們可以 對象的 __proto__屬性,來獲取對象原型鏈上的方法 如:
console.log(o.__proto__);//{__defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, __lookupSetter__: ƒ, …}
console.log(test1.__proto__);//undefined

通過打印發(fā)現(xiàn), 將{}點開,顯示的是 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

總結(jié):使用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

繼承

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

原型鏈

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

實現(xià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;
  };
  var instance = new SubType();
alert(instance.getSuperValue());
//true

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

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

相關(guān)文章

  • JavaScript基本類型值-Undefined、Null、Boolean

    JavaScript基本類型值-Undefined、Null、Boolean

    本文主要介紹了JavaScript基本類型值-Undefined、Null、Boolean的相關(guān)知識,具有很好的參考價值,下面跟著小編一起來看下吧
    2017-02-02
  • javascript實現(xiàn)獲取中文漢字拼音首字母

    javascript實現(xiàn)獲取中文漢字拼音首字母

    這篇文章主要為大家詳細介紹了javascript實現(xiàn)獲取中文漢字拼音首字母,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-05-05
  • javascript函數(shù)的call、apply和bind的原理及作用詳解

    javascript函數(shù)的call、apply和bind的原理及作用詳解

    javascript函數(shù)的call、apply和bind?本質(zhì)是用來實現(xiàn)繼承的,專業(yè)點說法就是改變函數(shù)體內(nèi)部this的指向,當一個對象沒有某個功能時,就可以用這3個來從有相關(guān)功能的對象里借用過來,文中通過代碼示例介紹的非常詳細,需要的朋友可以參考下
    2023-05-05
  • 關(guān)于Layui Table隱藏列問題

    關(guān)于Layui Table隱藏列問題

    今天小編就為大家分享一篇關(guān)于Layui Table隱藏列問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-09-09
  • JS+HTML5實現(xiàn)上傳圖片預(yù)覽效果完整實例【測試可用】

    JS+HTML5實現(xiàn)上傳圖片預(yù)覽效果完整實例【測試可用】

    這篇文章主要介紹了JS+HTML5實現(xiàn)上傳圖片預(yù)覽效果,結(jié)合完整實例形式分析了javascript上傳圖片本地預(yù)覽的具體操作步驟與相關(guān)實現(xiàn)技巧,需要的朋友可以參考下
    2017-04-04
  • 一篇文章帶你了解JavaScript的解構(gòu)賦值

    一篇文章帶你了解JavaScript的解構(gòu)賦值

    這篇文章主要為大家介紹了JavaScript的解構(gòu)賦值,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-01-01
  • JS棧stack類的實現(xiàn)與使用方法示例

    JS棧stack類的實現(xiàn)與使用方法示例

    這篇文章主要介紹了JS棧stack類的實現(xiàn)與使用方法,結(jié)合實例形式分析了棧的原理,以及javascript定義與使用棧的基本操作技巧,需要的朋友可以參考下
    2019-01-01
  • js實現(xiàn)頁面圖片消除效果

    js實現(xiàn)頁面圖片消除效果

    這篇文章主要為大家詳細介紹了js實現(xiàn)頁面圖片消除效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-03-03
  • js實現(xiàn)計算器和計時器功能

    js實現(xiàn)計算器和計時器功能

    這篇文章主要為大家詳細介紹了js實現(xiàn)計算器和計時器功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-07-07
  • JS基礎(chǔ)之邏輯結(jié)構(gòu)與循環(huán)操作示例

    JS基礎(chǔ)之邏輯結(jié)構(gòu)與循環(huán)操作示例

    這篇文章主要介紹了JS基礎(chǔ)之邏輯結(jié)構(gòu)與循環(huán)操作,結(jié)合實例形式分析了JavaScript邏輯判斷、流程控制、循環(huán)語句等相關(guān)操作技巧,需要的朋友可以參考下
    2020-01-01

最新評論

高安市| 城固县| 乌兰察布市| 克拉玛依市| 绥棱县| 苍南县| 独山县| 容城县| 尼玛县| 灵台县| 临夏县| 阿坝| 中宁县| 平罗县| 海晏县| 汉阴县| 景洪市| 江山市| 尼玛县| 柳河县| 武胜县| 图们市| 札达县| 竹溪县| 嵊泗县| 公安县| 边坝县| 山东| 调兵山市| 绥阳县| 朝阳区| 建湖县| 罗田县| 调兵山市| 安徽省| 舞钢市| 宁国市| 桐城市| 盐城市| 巴彦淖尔市| 颍上县|