亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

理解js對(duì)象

zhouzhou / 1657人閱讀

摘要:將構(gòu)造函數(shù)的作用域賦值給新對(duì)象因此指向了新對(duì)象執(zhí)行構(gòu)造函數(shù)的代碼為這個(gè)新對(duì)象添加屬性返回對(duì)象最初是用來(lái)標(biāo)識(shí)對(duì)象類型的。但提到檢測(cè)對(duì)象類型,還是使用將構(gòu)造函數(shù)當(dāng)作函數(shù)構(gòu)造函數(shù)與其他函數(shù)唯一區(qū)別。

創(chuàng)建對(duì)象

雖然Object構(gòu)造函數(shù)與對(duì)象字面量都能創(chuàng)建單個(gè)對(duì)象, 但這些方式都有明顯的缺點(diǎn): 使用同一個(gè)接口創(chuàng)建很多對(duì)象, 會(huì)產(chǎn)生大量重復(fù)代碼。

var obj = {}; //對(duì)象字面量
var obj = new Object(); //對(duì)象構(gòu)造函數(shù)(對(duì)象構(gòu)造器)
工廠模式

這種模式抽象了對(duì)象具體創(chuàng)建的過(guò)程(類似其它語(yǔ)言的類)

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("汪淼", 50, "納米");
var person2 = createPerson("楊冬", 20, "基礎(chǔ)物理學(xué)");

工廠模式解決了創(chuàng)建多個(gè)對(duì)象的問題, 確沒有解決對(duì)象識(shí)別問題(如何知道一個(gè)對(duì)象的類型)因?yàn)槭褂迷撃J讲]有給出對(duì)象的類型

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

創(chuàng)建自定義構(gòu)造函數(shù)意味著將來(lái)可以將它的實(shí)列類型標(biāo)識(shí)為一種特定的類型。(更優(yōu)點(diǎn))
這種方式定義的函數(shù)是定義在global中的

function Person (name, age, job) {
    this.name = name;
    this.age = age;
    this.job = job;
    this.sayName = function () {
      alert (this.name);
    }
}
var person1 = new Person("汪淼", 50, "納米");
var person2 = new Person("楊冬", 20, "基礎(chǔ)物理學(xué)");

與工廠模式區(qū)別

沒有顯示的創(chuàng)建對(duì)象

直接將屬性和方法賦給 this 對(duì)象

沒有return語(yǔ)句

使用new 來(lái)調(diào)用函數(shù),或者說(shuō)發(fā)生構(gòu)造函數(shù)調(diào)用時(shí),會(huì)自動(dòng)執(zhí)行下面的操作。

創(chuàng)建(或者說(shuō)構(gòu)造)一個(gè)全新的對(duì)象。

這個(gè)新對(duì)象會(huì)被執(zhí)行[[原型]]連接。

這個(gè)新對(duì)象會(huì)綁定到函數(shù)調(diào)用的this 。

如果函數(shù)沒有返回其他對(duì)象,那么new 表達(dá)式中的函數(shù)調(diào)用會(huì)自動(dòng)返回這個(gè)新對(duì)象。

高級(jí)編程對(duì)象處的說(shuō)法
1.創(chuàng)建(或者說(shuō)構(gòu)造)一個(gè)全新的對(duì)象。
2.將構(gòu)造函數(shù)的作用域賦值給新對(duì)象(因此this指向了新對(duì)象)
3.執(zhí)行構(gòu)造函數(shù)的代碼(為這個(gè)新對(duì)象添加屬性)
4.返回對(duì)象
person1.constructor == Person;
person2.constructor == Person;

constructor 最初是用來(lái)標(biāo)識(shí)對(duì)象類型的。但提到檢測(cè)對(duì)象類型,還是使用 instanceof

person1 instanceof Person // true
person2 instanceof Person // true
將構(gòu)造函數(shù)當(dāng)作函數(shù)

構(gòu)造函數(shù)與其他函數(shù)唯一區(qū)別。調(diào)用方式的不同。 用new 操作符調(diào)用就是作為構(gòu)造函數(shù),不用則為普通函數(shù)

   // 構(gòu)造函數(shù)
   var person = new Person("羅輯", 20, "宇宙社會(huì)學(xué)");
   person.sayName(); //羅輯
   // 普通函數(shù)
   Person("葉文潔", 20, "基礎(chǔ)物理學(xué)");
   window.sayName(); //葉文潔
   // 在另一個(gè)對(duì)象作用域中調(diào)用
   var o = new Object();
   Person.call(o, "泰勒", 25, "面壁者"); //call() apply() 是會(huì)立即調(diào)用函數(shù)的 而bind() 則不會(huì)
   o.sayName(); // 泰勒
構(gòu)造函數(shù)問題

使用構(gòu)造函數(shù)的主要問題是每個(gè)方法都要在每個(gè)實(shí)例上重新創(chuàng)建一遍,創(chuàng)建多個(gè)完成相同任務(wù)的方法完全沒有必要,浪費(fèi)內(nèi)存空間

function Person(name, age, job) {
  this.name = name;
  this.age = age;
  this.job = job;
  this.sayName = new Function("alert(this.name)"); 
  // 等價(jià)于
  // this.sayName = function () {
  //    alert (this.name);
  //  }
}
差的嘗試
  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("汪淼", 50, "納米");
  var person2 = new Person("楊冬", 20, "基礎(chǔ)物理");

sayName 放到了構(gòu)造函數(shù)外部, 構(gòu)造函數(shù)內(nèi)部通過(guò)sayName指針指向sayName函數(shù);
問題: 創(chuàng)建了全局函數(shù)sayName

于是這個(gè)自定義引用類型就沒有絲毫封裝性可言

原型模式 原型模式

我們創(chuàng)建的每個(gè)函數(shù)都有一個(gè) prototype(原型屬性),該屬性是一個(gè)指針,指向一個(gè)對(duì)象,而這個(gè)對(duì)象的用途是包含可以由特定類型所有實(shí)例共享的屬性和方法。

用原型對(duì)象,可以讓所有實(shí)例共享它的屬性和方法。換句話說(shuō),不必在構(gòu)造函數(shù)中定義對(duì)象實(shí)例的信息,而是可以將這些信息直接添加到原型對(duì)象中

function Person() {

}
Person.prototype.name = "維德";
Person.prototype.age = "24";
Person.prototype.sayName = function() {
  alert(this.name);
}

var person1 = new Person();
person1.sayName(); // 維德
var person2 = new Person();
person2.sayName(); // 維德
alert(person1.sayName == person2.sayName); //true
// @todo 原型鏈圖 
更簡(jiǎn)單的原型模式
function Person(){};
Person.prototype = {
    name: "丁怡",
    age: 50,
    job: "物流",
    sayName : function(){
        console.log(this.name);
    }
};
var person1 = new Person();
person1.sayName();// "丁怡"
console.log(person1.constructor === Person);// false
console.log(person1.constructor === Object);// true

這種語(yǔ)法 constructor 不再指向Person,(每創(chuàng)建一個(gè)函數(shù),就會(huì)同時(shí)創(chuàng)建prototype, 同時(shí)這個(gè)對(duì)象也會(huì)自動(dòng)獲取constructor),而該方法本質(zhì)上相當(dāng)于完全重寫了prototype的默認(rèn)屬性,constructor 也變成了新對(duì)象的constructor屬性(指向Object構(gòu)造函數(shù)),不再指向Person函數(shù)。此時(shí)盡管instanceof操作符還能返回正確的結(jié)果,但通過(guò)constructor已經(jīng)無(wú)法確定對(duì)象的類型了

var friend = new Person();
friend instanceof Object; // true
friend instanceof Person; // true
friend constructor Person; // false
friend constructor Object; // true
修正 constructor 方法
function Person(){};
Person.prototype = {
    // 方法1:添加 constructor
    constructor: "Person",
    name: "丁怡",
    age: 50,
    job: "物流",
    sayName : function(){
        console.log(this.name);
    }
};
// 方法2:通過(guò)defineProperty() 添加
Object.defineProperty(Person.prototype,"constructor",{
    enumerable: false,
    value: Person
});
原型 1.理解原型對(duì)象

無(wú)論什么時(shí)候,只要?jiǎng)?chuàng)建了一個(gè)新函數(shù),就會(huì)根據(jù)一組特定的的規(guī)則為該函數(shù)創(chuàng)建一個(gè)prototype屬性,這個(gè)屬性指向函數(shù)的原型對(duì)象。在默認(rèn)情況下,所有的原型對(duì)象都會(huì)自動(dòng)獲取constructor(構(gòu)造函數(shù))屬性,這個(gè)屬性包含了一個(gè)指向prototype屬性所在函數(shù)數(shù)的指針

2.原型與 in 操作符

in 會(huì)查找 原型鏈 hasOwnProperty() 則只查找實(shí)例本身

3.更簡(jiǎn)單的原型模式
function Person(){};
Person.prototype = {
    name: "丁怡",
    age: 50,
    job: "物流",
    sayName : function(){
        console.log(this.name);
    }
};
var person1 = new Person();
person1.sayName();// "丁怡"
console.log(person1.constructor === Person);// false
console.log(person1.constructor === Object);// true
4.原型的動(dòng)態(tài)性 && 重寫原型
var friend = new Person();
Person.prototype.sayHi = function() {
  alert("hi");
}
friend.sayHi(); // hi (ok!)

重寫function原型之后

function Person() {}
var friend = new Person();
Person.prototype = {
  constructor: Person,
  name: "程心",
  age: 21,
  job: "天體物理",
  sayName: fucntion() {
    alert(this.name);
  }
};
friend.sayName(); //error  原型鏈重寫 @todo 原型鏈圖
5.原生對(duì)象的原型

js 所有原生的引用類型,都是采用這種模式(Object, Array, String)

原型對(duì)象的問題

原型模式問題在于引用類型值屬性會(huì)被所有的實(shí)例對(duì)象共享并修改,這也是很少有人多帶帶使用原型模式的原因

function Person(){}
Person.prototype = {
    constructor: Person,
    name: "bai",
    age: 29,
    job: "Software Engineer",
    friend : ["shelby","Court"],
    sayName: function(){
        console.log(this.name);
    }
};
var person1 = new Person();
var person2 = new Person();
person1.friends.push("Van");
alert(person1.friends);//["shelby","Court","Van"];
alert(person2.friends);//["shelby","Court","Van"];
alert(person1.friends === person2.friends);//true
組合使用構(gòu)造函數(shù)模式和原型模式

組合使用構(gòu)造函數(shù)模式和原型模式是創(chuàng)建自定義類型的最常見方式。構(gòu)造函數(shù)模式用于定義實(shí)例屬性,而原型模式用于定義方法和共享的屬性,這種組合模式還支持向構(gòu)造函數(shù)傳遞參數(shù)。實(shí)例對(duì)象都有自己的一份實(shí)例屬性的副本,同時(shí)又共享對(duì)方法的引用,最大限度地節(jié)省了內(nèi)存。該模式是目前使用最廣泛、認(rèn)同度最高的一種創(chuàng)建自定義對(duì)象的模式

  function Person(name, age, job) {
    this.name = name;
    this.age = age;
    this.job = job;
    this.friends = ["丁怡", "汪淼"];
  }
  Person.prototype = {
    constructor: Person,
    sayName: function() {
      alert(this.name);
    }
  }
var person1 = new Person("bai",29,"Software Engineer");
var person2 = new Person("hu",25,"Software Engineer");
person1.friends.push("楊冬");
alert(person1.friends);// ["丁怡", "汪淼", "楊冬"];
alert(person2.friends);// ["丁怡", "汪淼"];
alert(person1.friends === person2.friends);//false
alert(person1.sayName === person2.sayName);//true
動(dòng)態(tài)原型模式

動(dòng)態(tài)原型模式將組合模式中分開使用的構(gòu)造函數(shù)和原型對(duì)象都封裝到了構(gòu)造函數(shù)中,然后通過(guò)檢查方法是否被創(chuàng)建,來(lái)決定是否初始化原型對(duì)象

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);
    };
  }
}
var friend = new Person("bai",29,"Software Engineer");
friend.sayName();//"bai"
寄生構(gòu)造函數(shù)模式

該模式的基本思想是創(chuàng)建一個(gè)函數(shù),該函數(shù)的作用僅僅是封裝創(chuàng)建對(duì)象的代碼,然后再返回新創(chuàng)建的對(duì)象。該模式是工廠模式和構(gòu)造函數(shù)模式的結(jié)合

  寄生構(gòu)造函數(shù)模式與構(gòu)造函數(shù)模式有相同的問題,每個(gè)方法都要在每個(gè)實(shí)例上重新創(chuàng)建一遍,創(chuàng)建多個(gè)完成相同任務(wù)的方法完全沒有必要,浪費(fèi)內(nèi)存空間

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);
    };
    // o.sayName = new Function("console.log(this.name);");
    return o;
}
var person1 = new Person("bai", 29, "software Engineer");
var person2 = new Person("hu", 25, "software Engineer");
//具有相同作用的sayName()方法在person1和person2這兩個(gè)實(shí)例中卻占用了不同的內(nèi)存空間
console.log(person1.sayName === person2.sayName);//false

使用new 操作符會(huì)默認(rèn)返回新對(duì)象實(shí)例,這里return 重寫了調(diào)用構(gòu)造函數(shù)的時(shí)返回的值

穩(wěn)妥構(gòu)造函數(shù)模式

所謂穩(wěn)妥對(duì)象指沒有公共屬性,而且其方法也不引用this的對(duì)象。穩(wěn)妥對(duì)象最適合在一些安全環(huán)境中(這些環(huán)境會(huì)禁止使用this和new)或者在防止數(shù)據(jù)被其他應(yīng)用程序改動(dòng)時(shí)使用

  穩(wěn)妥構(gòu)造函數(shù)與寄生構(gòu)造函數(shù)模式相似,但有兩點(diǎn)不同:一是新創(chuàng)建對(duì)象的實(shí)例方法不引用this;二是不使用new操作符調(diào)用構(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;
}
//在穩(wěn)妥模式創(chuàng)建的對(duì)象中,除了使用sayName()方法之外,沒有其他方法訪問name的值
var friend = Person("bai",29,"Software Engineer");
friend.sayName();//"bai"

與寄生構(gòu)造函數(shù)模式相似,使用穩(wěn)妥構(gòu)造函數(shù)模式創(chuàng)建的對(duì)象與構(gòu)造函數(shù)之間也沒有什么關(guān)系,因此instanceof操作符對(duì)這種對(duì)象也沒有什么意義

最后

本文從使用Object構(gòu)造函數(shù)與對(duì)象字面量創(chuàng)建一個(gè)對(duì)象開始說(shuō)起,創(chuàng)建多個(gè)對(duì)象會(huì)造成代碼冗余;使用工廠模式可以解決該問題,但存在對(duì)象識(shí)別的問題;接著介紹了構(gòu)造函數(shù)模式,該模式解決了對(duì)象識(shí)別的問題,但存在關(guān)于方法的重復(fù)創(chuàng)建問題;接著介紹了原型模式,該模式的特點(diǎn)就在于共享,但引出了引用類型值屬性會(huì)被所有的實(shí)例對(duì)象共享并修改的問題;最后,提出了構(gòu)造函數(shù)和原型組合模式,構(gòu)造函數(shù)模式用于定義實(shí)例屬性,而原型模式用于定義方法和共享的屬性,這種組合模式還支持向構(gòu)造函數(shù)傳遞參數(shù),該模式是目前使用最廣泛的一種模式。此外,一些模式下面還有一些解決特殊需求的拓展模式(寄生構(gòu)造函數(shù)模式, 穩(wěn)妥寄生模式)

Object構(gòu)造函數(shù)與對(duì)象字面量創(chuàng)建一個(gè)對(duì)象 創(chuàng)建多個(gè)對(duì)象會(huì)造成代碼冗余

使用工廠模式可以解決該問題 存在對(duì)象識(shí)別的問題

介紹了構(gòu)造函數(shù)模式,該模式解決了對(duì)象識(shí)別的問題 但存在關(guān)于方法的重復(fù)創(chuàng)建問題

介紹了原型模式,該模式的特點(diǎn)就在于共享 但引出了引用類型值屬性會(huì)被所有的實(shí)例對(duì)象共享并修改的問題

提出了構(gòu)造函數(shù)和原型組合模式,構(gòu)造函數(shù)模式用于定義實(shí)例屬性,而原型模式用于定義方法和共享的屬性,這種組合模式還支持向構(gòu)造函數(shù)傳遞參數(shù),該模式是目前使用最廣泛的一種模式

一些模式下面還有一些解決特殊需求的拓展模式(寄生構(gòu)造函數(shù)模式, 穩(wěn)妥寄生模式)

參考

javascript面向?qū)ο笙盗械诙獎(jiǎng)?chuàng)建對(duì)象的5種模式

javascript高級(jí)編程

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/88929.html

相關(guān)文章

  • javascript引擎執(zhí)行的過(guò)程的理解--語(yǔ)法分析和預(yù)編譯階段

    摘要:所以覺得把這個(gè)執(zhí)行的詳細(xì)過(guò)程整理一下,幫助更好的理解。類似的語(yǔ)法報(bào)錯(cuò)的如下圖所示三預(yù)編譯階段代碼塊通過(guò)語(yǔ)法分析階段之后,語(yǔ)法都正確的下回進(jìn)入預(yù)編譯階段。另開出新文章詳細(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ù)編譯階段

    摘要:所以覺得把這個(gè)執(zhí)行的詳細(xì)過(guò)程整理一下,幫助更好的理解。類似的語(yǔ)法報(bào)錯(cuò)的如下圖所示三預(yù)編譯階段代碼塊通過(guò)語(yǔ)法分析階段之后,語(yǔ)法都正確的下回進(jìn)入預(yù)編譯階段。另開出新文章詳細(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
  • [ 學(xué)習(xí)路線 ] 學(xué)完這些去阿里!GOGOGO

    摘要:以下知識(shí)點(diǎn)是前輩師兄總結(jié)基礎(chǔ)語(yǔ)義化標(biāo)簽引進(jìn)了一些新的標(biāo)簽,特別注意等,注意的標(biāo)題結(jié)構(gòu)理解瀏覽器解析的過(guò)程,理解的樹形結(jié)構(gòu),及相應(yīng)理解標(biāo)簽在各個(gè)瀏覽器上的默認(rèn)樣式代理樣式,理解中的重置樣式表的概念理解等功能性標(biāo)簽理解標(biāo)簽,理解文件提交過(guò)程推薦 以下知識(shí)點(diǎn)是前輩師兄總結(jié) 1、HTML/HTML5基礎(chǔ): 1.0、語(yǔ)義化H5標(biāo)簽1.1、H5引進(jìn)了一些新的標(biāo)簽,特別注意article...

    zhaochunqi 評(píng)論0 收藏0
  • [ 學(xué)習(xí)路線 ] 學(xué)完這些去阿里!GOGOGO

    摘要:以下知識(shí)點(diǎn)是前輩師兄總結(jié)基礎(chǔ)語(yǔ)義化標(biāo)簽引進(jìn)了一些新的標(biāo)簽,特別注意等,注意的標(biāo)題結(jié)構(gòu)理解瀏覽器解析的過(guò)程,理解的樹形結(jié)構(gòu),及相應(yīng)理解標(biāo)簽在各個(gè)瀏覽器上的默認(rèn)樣式代理樣式,理解中的重置樣式表的概念理解等功能性標(biāo)簽理解標(biāo)簽,理解文件提交過(guò)程推薦 以下知識(shí)點(diǎn)是前輩師兄總結(jié) 1、HTML/HTML5基礎(chǔ): 1.0、語(yǔ)義化H5標(biāo)簽1.1、H5引進(jìn)了一些新的標(biāo)簽,特別注意article...

    learn_shifeng 評(píng)論0 收藏0
  • 形象化模擬作用域鏈,深入理解js作用域、閉包

    摘要:至此作用域鏈創(chuàng)建完畢。好了,通過(guò)深入理解作用域鏈,我們能跟好的理解的運(yùn)行機(jī)制和閉包的原理。 前言 理解javascript中的作用域和作用域鏈對(duì)我們理解js這們語(yǔ)言。這次想深入的聊下關(guān)于js執(zhí)行的內(nèi)部機(jī)制,主要討論下,作用域,作用域鏈,閉包的概念。為了更好的理解這些東西,我模擬了當(dāng)一個(gè)函數(shù)執(zhí)行時(shí),js引擎做了哪些事情--那些我們看不見的動(dòng)作。 關(guān)鍵詞: 執(zhí)行環(huán)境 作用域 作用域鏈 變...

    txgcwm 評(píng)論0 收藏0
  • JS每日一題:如何理解es6中的Proxy?

    20190124問: 如何理解es6中的Proxy? 試題解析:對(duì)proxy的理解,可能會(huì)延伸到vue的雙向綁定 Proxy(代理) 定義 可以理解為為目標(biāo)對(duì)象架設(shè)一層攔截,外界對(duì)該對(duì)象的訪問,都必須通過(guò)這層攔截 簡(jiǎn)單示例: const obj = new Proxy({}, { get: (target, key, receiver) => { return JS ...

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

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

0條評(píng)論

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