国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

js對(duì)象(一)——?jiǎng)?chuàng)建對(duì)象

xorpay / 3023人閱讀

首先是對(duì)“對(duì)象”的理解:
對(duì)象是一組沒(méi)有特定屬性的值,對(duì)象的每一個(gè)屬性或方法都有一個(gè)名字,而每一個(gè)名字都映射到一個(gè)值,其中值可以是數(shù)據(jù)或函數(shù)。每一個(gè)對(duì)象都是基于一個(gè)引用類型創(chuàng)建的,這個(gè)引用類型可以是原生類型,也可以是開(kāi)發(fā)人員自定義的類型?!叱?/pre>

(好的,這里說(shuō)的比較不容易理解)

(不急,接下來(lái)再看)

JavaScript中,一切都是對(duì)象,函數(shù)也是對(duì)象,數(shù)組也是對(duì)象,但是數(shù)組是對(duì)象的子集,而對(duì)于函數(shù)來(lái)說(shuō),函數(shù)與對(duì)象之間有一種“雞生蛋蛋生雞”的關(guān)系。

所有的對(duì)象都是由Object繼承而來(lái),而Object對(duì)象卻是一個(gè)函數(shù)。對(duì)象都是由函數(shù)來(lái)創(chuàng)建的。

比如,在控制臺(tái)中
輸入 typeof Object 結(jié)果是"function",
輸入 typeof Function 結(jié)果還是"function".

(好的,是不是更懵逼了,不急,現(xiàn)在先看一下怎么創(chuàng)建對(duì)象以及各種方法的孰優(yōu)孰劣)

創(chuàng)建對(duì)象 0. 最基本的模式:
var box=new Object(); //創(chuàng)建一個(gè) Object 對(duì)象
box.name="Lee"; //創(chuàng)建一個(gè) name 屬性并賦值
box.age= 100; //創(chuàng)建一個(gè) age 屬性并賦值
box.run= function(){ //創(chuàng)建一個(gè)run()方法并返回值 
 return this.name + this.age; 
}; 
console.log(box.run()); //輸出屬性和方法的值

優(yōu)缺點(diǎn):

優(yōu)點(diǎn):簡(jiǎn)單

缺點(diǎn):產(chǎn)生大量代碼,封裝性差

1.工廠模式:
fuction creatPerson(name,age,job){
 var  o = new Object();  //創(chuàng)建對(duì)象
 o.name = name;   //添加屬性
 o.age = age;
 o.job = job;
 o.sayName = function(){  //添加方法
 console.log(this.name);
 }
  return o; //返回對(duì)象引用
}

var person1 = creatPerson("Nicholas",29,"engineer");//實(shí)例化
var person2 = creatPerson("Mike",28,"teacher");

優(yōu)缺點(diǎn):

優(yōu)點(diǎn):解決了創(chuàng)建多個(gè)相似對(duì)象的問(wèn)題.

缺點(diǎn):但卻沒(méi)有解決對(duì)象識(shí)別問(wèn)題,即怎樣知道一個(gè)對(duì)象的類型。也就是,因?yàn)楦緹o(wú)法搞清楚他們到底是哪個(gè)對(duì)象的實(shí)例(這個(gè)可以和下面的構(gòu)造函數(shù)模式作對(duì)比)

2.構(gòu)造函數(shù)模式
function Person(name,age,job){  
    this.name = name;
    this.age = age;
    this.job = job;
    this.sayName = function(){
      console.log(this.name);
   }
}

//或
function Person(name,age,job){
    this.name = name;
    this.age = age;
    this.job = job;
    this.sayName = sayName;//注意這里不要寫括號(hào),要實(shí)現(xiàn)引用地址一致
}
function sayName(){
    console.log(this.name);
    
}//這里是在外面寫一個(gè),但這種方法會(huì)有作用域問(wèn)題,十分不推薦
 var person1 = new Person("Nicholas",29,"Engineer");//一般這樣實(shí)例化
 
 var o = new Object;;
 Person.call(o,"Kkresten",25,"Nurse");//對(duì)象冒充法實(shí)例化

區(qū)別:

沒(méi)有寫出new Object,但是后臺(tái)會(huì)自動(dòng) var obj = new Object,而this就相當(dāng)于obj

沒(méi)有 renturn 語(yǔ)句,在后臺(tái)返回

規(guī)范

函數(shù)名和實(shí)例化構(gòu)造名相同且大寫(非強(qiáng)制,主要是為了和普通函數(shù)區(qū)分開(kāi)來(lái))

通過(guò)構(gòu)造函數(shù)創(chuàng)建對(duì)象,必須使用 new 運(yùn)算符

優(yōu)缺點(diǎn)

優(yōu)點(diǎn): 創(chuàng)建自定義的構(gòu)造類型意味著將來(lái)可以將它的實(shí)例標(biāo)識(shí)為一種特定的類型,(可以用instanceof 來(lái)驗(yàn)證),即可識(shí)別(這里就可以和上面工廠模式作對(duì)比了,這也是比工廠模式更強(qiáng)的地方)

缺點(diǎn):每個(gè)方法都要在每個(gè)實(shí)例上創(chuàng)建一遍,大可不必(當(dāng)函數(shù)在內(nèi)部時(shí)),

全局作用域中定義的函數(shù)只能被某個(gè)對(duì)象調(diào)用,這讓全局作用域有點(diǎn)名不副實(shí),而且,如果對(duì)象需要定義很多方法,那么就要定義很多個(gè)全局函數(shù),于是,這個(gè)自定義的引用類型就絲毫沒(méi)有封可言了(函數(shù)定義在外部時(shí))。(所以函數(shù)在內(nèi)部和外部都有缺點(diǎn))

(好的,學(xué)到這里,你已經(jīng)大體掌握了怎么創(chuàng)建一個(gè)對(duì)象,接下來(lái)將開(kāi)始學(xué)習(xí)創(chuàng)建對(duì)象高大上的方法和概念)

3. 原型模式
我們創(chuàng)建的每個(gè)函數(shù)都有一個(gè)prototype(原型)屬性,這個(gè)屬性是一個(gè)指針,指向一個(gè)對(duì)象,(屬性值是對(duì)象)而這個(gè)對(duì)象的用途是包含可以由特定類型的所有實(shí)例共享的屬性和方法。:prototype 通過(guò) 調(diào)用構(gòu)造函數(shù)而創(chuàng)建的那個(gè)對(duì)象的原型對(duì)象。使用原型的好處可以讓所有對(duì)象實(shí)例共享它所包含的屬性和方法。也就是說(shuō),不必在構(gòu)造函數(shù)中定義對(duì)象信息,而是可以直接將這些信息 添加到原型中?!叱?/pre>

(好的,又回到了懵逼的狀態(tài)了,不急,先通過(guò)例子和圖來(lái)了解一下先)

 function Person(){//構(gòu)造函數(shù)
}

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(); //實(shí)例化
person1.sayName(); //“Nicholas”
var person2 = new Person(); //實(shí)例化
person2.sayName();//"Nicholas"

如下圖:

而我自己畫(huà)了個(gè)圖來(lái)加深一下認(rèn)識(shí)(結(jié)合高程里的那段話)

(是不是有點(diǎn)懂了,接下來(lái)再逐個(gè)仔細(xì)分析)

1.對(duì)于[[Prototype]]

每一個(gè)對(duì)象都有一個(gè)這樣的隱藏屬性,它引用了創(chuàng)建這個(gè)對(duì)象的函數(shù)的prototype原型對(duì)象,我們來(lái)看一張圖:


注意:函數(shù)也是對(duì)象,自然它也有__proto__。
在控制臺(tái)中,我們發(fā)現(xiàn):

即函數(shù)的__proto__是函數(shù)類型。(也就說(shuō)函數(shù)的原型對(duì)象是函數(shù),而函數(shù)也是對(duì)象,所以函數(shù)的原型還是對(duì)象)(這里聽(tīng)著有點(diǎn)繞,但是可以先跳過(guò))

還要注意一個(gè)特例,如下圖:

這里,一切對(duì)象繼承自O(shè)bject,而我們又知道Object.prototype是它的原型對(duì)象,是一個(gè)對(duì)象,但是這個(gè)對(duì)象的__proto__卻為null,是否說(shuō)明構(gòu)建Object對(duì)象的函數(shù)沒(méi)有原型對(duì)象,因?yàn)?strong>對(duì)象都是由函數(shù)創(chuàng)建的

(對(duì)于函數(shù)與對(duì)象的關(guān)系和涉及到的原型鏈的相關(guān)知識(shí),還挺大挺深的,將多帶帶作為一個(gè)話題來(lái)討論。如果這里有點(diǎn)看得暈,可以先只是知道prototype是什么就可以了)

注意: __proto__這個(gè)指針沒(méi)有標(biāo)準(zhǔn)的方法訪問(wèn),IE 瀏覽器在腳本訪問(wèn)[[Prototype]]會(huì)不能識(shí)別,火狐和谷歌瀏覽器及其他某些瀏覽器均能識(shí)別。雖然可以輸出,但無(wú)法獲取內(nèi)部信息。([[Prototype]] 也可寫為_(kāi)_proto__)雖然無(wú)法訪問(wèn)到,但是可以通過(guò): Object.isPrototypeOf(person1)判斷這個(gè)實(shí)例對(duì)象是否指向它的原型對(duì)象 ;而我們也知道Person.prototype就是Object類型,即一個(gè)原型對(duì)象

//承接上面的代碼
Person.prototype.isPrototypeOf(person1);//true
Person.prototype.isPrototypeOf(person2);//true

2.對(duì)于原型模式的執(zhí)行流程:

①先檢查這個(gè)對(duì)象自身有無(wú)這個(gè)屬性;如果有,直接使用它。

②如果無(wú)法在對(duì)象自身找到需要的屬性,就會(huì)繼續(xù)訪問(wèn)對(duì)象的[[Prototype]]鏈,找到則直接使用,不再查找下去;如果一直找不到,最后就會(huì)返回undefined

3.可以通過(guò) hasOwnProperty()方法檢測(cè)屬性是否存在實(shí)例中,也可以通過(guò) in 來(lái)判斷 實(shí)例或原型中是否存在屬性;可以通過(guò)Object.keys()方法或Object.getOwnPropertyNames()來(lái)得到實(shí)例屬性,具體見(jiàn)高程。

4.優(yōu)缺點(diǎn):每添加一個(gè)屬性和方法就要敲一遍Person.prototype,而且視覺(jué)上說(shuō)封裝性不夠好。當(dāng)然優(yōu)點(diǎn)就是解決了上面構(gòu)造函數(shù)的問(wèn)題。

5.更簡(jiǎn)單的原型模式

 function Person(){
}
 Person.prototype = {  //將 Person.prototype 設(shè)置為等于一個(gè)以對(duì)象字面量形式創(chuàng)建的新對(duì)象
    name : "Nicholas",
    age:  29,
    job:  "software Engineer",
    sayName : function() {
       console.log(this.name);
    }
 }
//(但constructor屬性不再指向Person了,而是指向Object構(gòu)造函數(shù))
//但可以這樣手動(dòng)設(shè)置:
 function Person(){
}
 Person.prototype = {  
    constructor : Person,//手動(dòng)設(shè)置
    name : "Nicholas",
    age: 29,
    job:  "software Engineer",
    sayName : function() {
       console.log(this.name);
    }
 }
//因?yàn)榘瓷厦娴姆绞綍?huì)導(dǎo)致它的[[Enumerable]]特性被設(shè)置為true,所以還可以像下面這樣
 function Person(){
}
 Person.prototype = {  
    name : "Nicholas",
    age: 29,
    job:  "software Engineer",
    sayName : function() {
       console.log(this.name);
    }
 }
Object.definePrototype(Person.prototype,"constructor"),{
   enumerable :  false;
   value : Person
  }
}

6.原型的動(dòng)態(tài)性:

//承接上面的Person構(gòu)造函數(shù)
var friend = new Person();
Person.prototype.sayhi = function(){
    alert("hi");
};
friend.sayhi(); //"hi"沒(méi)有問(wèn)題,雖然是在實(shí)例之后添加的屬性,但是根據(jù)原型模式的搜索機(jī)制,會(huì)找到原型中的這個(gè)方法,原因:實(shí)例與原型是松散連接的
//但是:如果是這樣:
 function Person(){
}
 var friend = new Person();
 Person.prototype = {  
    name : "Nicholas",
    age:  29,
    job:  "software Engineer",
     sayName : function() {
       console.log(this.name);
    }
 }
 friend.sayName();//Uncaught TypeError: friend.sayName is not a function,雖然有將重寫的原型的指針指向Person原型對(duì)象,但是很實(shí)際上卻如下圖:

6.優(yōu)缺點(diǎn):

優(yōu)點(diǎn):解決了構(gòu)造函數(shù)出現(xiàn)的問(wèn)題(強(qiáng)大的類型識(shí)別)

缺點(diǎn):共享了引用類型的值,這個(gè)就是很少有人多帶帶使用原型模式的原因。比如下面:

 function Person(){
}
 Person.prototype = {  
    constructor : Person,
    name : "Nicholas",
    age:  29,
    job:  "software Engineer",
    friend:["Mike","Jeny"],
    sayName : function() {
       console.log(this.name);
     }
}
var person1 = new Person();
var person2 = new Person();
person1.friend.push("Van");
console.log(person1.friend);//"Mike,Jeny,Van"
console.log(person2.friend);//"Mike,Jeny,Van"
4.組合使用構(gòu)造函數(shù)和原型模式
 function Perosn(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," Engineer");

優(yōu)缺點(diǎn):

優(yōu)點(diǎn):解決了引用類型實(shí)例共享的問(wèn)題

缺點(diǎn):封裝性不夠好

## 5.動(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);//只有在sayName方法不存在的情況下才會(huì)被添加到原型中
  }
}
//這段代碼在初次調(diào)用構(gòu)造函數(shù)時(shí)才會(huì)執(zhí)行,此后,原型已經(jīng)初始化
var friend  = new Person("Nicholas",29,"Engineer");

優(yōu)缺點(diǎn):

優(yōu)點(diǎn):既得到了封裝,又實(shí)現(xiàn)了原型方法共享,并且屬性都保持獨(dú)立??梢哉f(shuō)是非常完美了,其實(shí)說(shuō)白了這種方法就是解決上面構(gòu)造函數(shù)的方法不需要每次都創(chuàng)建一遍的問(wèn)題。

缺點(diǎn):不能使用對(duì)象字面量重寫原型,會(huì)使之前定義的原型對(duì)象的方法失效。

(好了,學(xué)到這里,大概常用的創(chuàng)建對(duì)象的方法就已經(jīng)掌握了,接下來(lái)還有兩種不常用的方法可以了解一下)

6.寄生構(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");

function SpecialArray(){
//創(chuàng)建數(shù)組
var values = new Array();
//用push方法初始化數(shù)組的值
values.push.apply(values,arguments);
//添加方法
values.toPipedString = function(){
 return this.join("|");
}
//返回?cái)?shù)組
 return values;
}
var colors = new SpecialArray("red","blue","green");
console.log(colors.toPipedString()); //"red|blue|green"

優(yōu)缺點(diǎn):

構(gòu)造函數(shù)返回的對(duì)象與在構(gòu)造函數(shù)外部創(chuàng)建的對(duì)象沒(méi)有什么不同,為此不能依賴instanceof操作符來(lái)確定對(duì)象的類型:

console.log(friend instanceof Person) // false

因此,可以使用其他模式的情況下不使用此類型

7.穩(wěn)妥構(gòu)造函數(shù)模式
function Person(name,age,job){
 //創(chuàng)建要返回的對(duì)象
 var o = new Object();
//可以在這里定義私有變量和函數(shù)
//添加方法
 o.sayName = function(){
 console.log(name);
 }
//返回對(duì)象
  return o;
}
var friend =  Person("Nicholas",29,"Software Engineer");
friend.sayName();

區(qū)別:

不引用this的對(duì)象

不使用new操作符

優(yōu)點(diǎn):安全

(好了,js對(duì)象的創(chuàng)建就大概有這幾種方法,其實(shí)最常用的貌似還是構(gòu)造函數(shù)的模式,但是原型相關(guān)的東西也是必須要掌握的)

最后,歡迎大家圍觀指正!

參考:《javascript高級(jí)程序設(shè)計(jì)》

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/95166.html

相關(guān)文章

  • 關(guān)于javascript的原型和原型鏈,看我就夠了(

    摘要:要用作原型的對(duì)象。函數(shù)對(duì)象可以創(chuàng)建普通對(duì)象,這個(gè)我們上面講過(guò)了回顧一下這是一個(gè)自定義構(gòu)造函數(shù)普通對(duì)象沒(méi)法創(chuàng)建函數(shù)對(duì)象,凡是通過(guò)創(chuàng)建的對(duì)象都是函數(shù)對(duì)象,其他都是普通對(duì)象通常通過(guò)創(chuàng)建,可以通過(guò)來(lái)判斷。 關(guān)于js的原型和原型鏈,有人覺(jué)得這是很頭疼的一塊知識(shí)點(diǎn),其實(shí)不然,它很基礎(chǔ),不信,往下看要了解原型和原型鏈,我們得先從對(duì)象說(shuō)起 創(chuàng)建對(duì)象 創(chuàng)建對(duì)象的三種方式: 對(duì)象直接量 通過(guò)對(duì)象直接量創(chuàng)建...

    MoAir 評(píng)論0 收藏0
  • javascript引擎執(zhí)行的過(guò)程的理解--語(yǔ)法分析和預(yù)編譯階段

    摘要:所以覺(jué)得把這個(gè)執(zhí)行的詳細(xì)過(guò)程整理一下,幫助更好的理解。類似的語(yǔ)法報(bào)錯(cuò)的如下圖所示三預(yù)編譯階段代碼塊通過(guò)語(yǔ)法分析階段之后,語(yǔ)法都正確的下回進(jìn)入預(yù)編譯階段。另開(kāi)出新文章詳細(xì)分析,主要介紹執(zhí)行階段中的同步任務(wù)執(zhí)行和異步任務(wù)執(zhí)行機(jī)制事件循環(huán)。 一、概述 js是一種非常靈活的語(yǔ)言,理解js引擎的執(zhí)行過(guò)程對(duì)于我們學(xué)習(xí)js是非常有必要的??戳撕芏噙@方便文章,大多數(shù)是講的是事件循環(huán)(event loo...

    molyzzx 評(píng)論0 收藏0
  • javascript系列--javascript引擎執(zhí)行的過(guò)程的理解--語(yǔ)法分析和預(yù)編譯階段

    摘要:所以覺(jué)得把這個(gè)執(zhí)行的詳細(xì)過(guò)程整理一下,幫助更好的理解。類似的語(yǔ)法報(bào)錯(cuò)的如下圖所示三預(yù)編譯階段代碼塊通過(guò)語(yǔ)法分析階段之后,語(yǔ)法都正確的下回進(jìn)入預(yù)編譯階段。另開(kāi)出新文章詳細(xì)分析,主要介紹執(zhí)行階段中的同步任務(wù)執(zhí)行和異步任務(wù)執(zhí)行機(jī)制事件循環(huán)。 一、概述 js是一種非常靈活的語(yǔ)言,理解js引擎的執(zhí)行過(guò)程對(duì)于我們學(xué)習(xí)js是非常有必要的。看了很多這方便文章,大多數(shù)是講的是事件循環(huán)(event loo...

    malakashi 評(píng)論0 收藏0
  • JS面向對(duì)象編程之封裝

    摘要:在基于原型的面向?qū)ο蠓绞街?,?duì)象則是依靠構(gòu)造函數(shù)和原型構(gòu)造出來(lái)的。來(lái)看下面的例子優(yōu)點(diǎn)與單純使用構(gòu)造函數(shù)不一樣,原型對(duì)象中的方法不會(huì)在實(shí)例中重新創(chuàng)建一次,節(jié)約內(nèi)存。 我們所熟知的面向?qū)ο笳Z(yǔ)言如 C++、Java 都有類的的概念,類是實(shí)例的類型模板,比如Student表示學(xué)生這種類型,而不表示任何具體的某個(gè)學(xué)生,而實(shí)例就是根據(jù)這個(gè)類型創(chuàng)建的一個(gè)具體的對(duì)象,比如zhangsan、lisi,由...

    YFan 評(píng)論0 收藏0
  • JS基礎(chǔ)(對(duì)象創(chuàng)建,構(gòu)造函數(shù)、原型、實(shí)例之間關(guān)系,繼承方式)

    摘要:對(duì)象創(chuàng)建的三種方式字面量創(chuàng)建方式系統(tǒng)內(nèi)置構(gòu)造函數(shù)方式自定義構(gòu)造函數(shù)構(gòu)造函數(shù)原型實(shí)例之間的關(guān)系實(shí)例是由構(gòu)造函數(shù)實(shí)例化創(chuàng)建的,每個(gè)函數(shù)在被創(chuàng)建的時(shí)候,都會(huì)默認(rèn)有一個(gè)對(duì)象。 JS 對(duì)象創(chuàng)建的三種方式 //字面量創(chuàng)建方式 var person= { name:jack?。? //系統(tǒng)內(nèi)置構(gòu)造函數(shù)方式 var person= new Object(); person.name = jack; ...

    PAMPANG 評(píng)論0 收藏0
  • [譯]執(zhí)行上下文、作用域鏈和JS內(nèi)部機(jī)制

    摘要:執(zhí)行上下文作用域鏈和內(nèi)部機(jī)制一執(zhí)行上下文執(zhí)行上下文是代碼的執(zhí)行環(huán)境,它包括的值變量對(duì)象和函數(shù)。創(chuàng)建作用域鏈一旦可變對(duì)象創(chuàng)建完,引擎就開(kāi)始初始化作用域鏈。 執(zhí)行上下文、作用域鏈和JS內(nèi)部機(jī)制(Execution context, Scope chain and JavaScript internals) 一、執(zhí)行上下文 執(zhí)行上下文(Execution context EC)是js代碼的執(zhí)...

    caozhijian 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<