JS構造函數

JS構造函數

  • 當你感受晚的時候 正是開始的最佳時機 加油

1.構造函數的模式基礎:品牌概念

  • 品牌概念(如培訓機構是一個類 比較有名的有珠峯 千峯 達內 構造函數就爲了實現不一樣的品牌細分)
  • 萬物皆對象
  • 類: 對象的具體細分
  • 實例: 類當中的具體事務
//數組內置類: Array 每個數組都是數組內置類的實例
//對象內置類: Object 每個對象數據類型都是對象內置類的實例
//函數內置類: Function 每個函數都是函數內置類的實例
//Js中除了內置類 項目中也須要自定義類
複製代碼

2.溫習工廠模式(函數模式)

function createJsPerson() {
    var obj = {};
    obj.name = name;
    obj.writeJs = function() {
        console.log("my name is " + this.name + ",i can write js la");
    }
    return obj;
}
var p1 = createJsPerson("A",18);
p1.wrireJs();
//p1 是對象數據類型的 createJsPerson 是函數名 方法名
//經過函數的執行 返回一個對象

複製代碼

3.構造函數(主要看和工廠模式的區別)

  • 構造函數模式的目的就是爲了建立一個自定義類,而且建立這個類的實例
function CreateJsPerson(name,age) {
    this.name = name;
    this.age = age;
    this.writeJs = function() {
        console.log("my name is " + this.name + ",i can write js la");
    }
}
//不用再定義obj 也不用再return obj
var p2 = new CreateJsPerson("A",18);// CreateJsPerson就是類
p2.writeJs();
複製代碼
  • 構造函數模式和工廠模式的區別

一、執行的時候 普通函數執行(工廠模式) ---> createJsPerson() 構造函數模式 ---> new CreateJsPerson() 經過new執行後,咱們的CreateJsPerson就是一個類了(爲了和內置類有同樣的標準,首字母建議大寫),而函數執行的返回值P2就是CreateJsPerson這個類的一個實例javascript

  • 擴展
//建立一個數組
var array = [] //字面量方式
var array = new Array();//實例建立的方式 ---> 構造函數模式執行的方式
//無論哪種方式建立數組 array都是Array這個類的一個實例
複製代碼
  • JS中全部的類都是函數數據類型的 它經過new執行變成一個類,可是它自己也是一個普通的函數
  • JS中全部的實例都是對象數據類型的
  • typeOf P2 "object" 類型
  • typeOf CreateJsPerson "function" 類型

二、在函數代碼執行的時候 相同:都是造成一個私有的做用域,而後形參賦值 -->預解釋 --> 代碼從上往下執行(類也有普通函數的一面) 不一樣:在代碼執行以前,構造函數不用再本身建立對象,瀏覽器會默認建立一個對象數據類型的值(這個對象其實就是咱們當前類的一個實例),而後代碼從上往下執行,以當前實例爲執行的主體(this就是當前的實例),而後分別把屬性名和屬性值賦給當前實例java

function CreateJsPerson(name,age) {
    this.name = name; //---> this表明當前隱形的對象
    this.age = age;
    this.writeJs = function() {
        console.log("my name is " + this.name + ",i can write js la"); //this ---> p1 表明當前實例
    }
    // 把屬性名和屬性值賦值給當前實例 不用再定義obj 也不用return obj
}
var p1 = new CreateJsPerson("A",18);
p1.writeJs();
複製代碼

三、this的第4點 在構造函數模式中,類中(函數體中)出現的this.xxx = xxx中的this是當前類的一個實例數組

四、雖然p1和p2都是CreateJsPerson 這個類的實例,因此都擁有writeJs這個方法,可是不一樣實例之間的方法是不同的瀏覽器

  • console.log(p1.writeJs === p2.writeJs)// false
  • 在類中給實例增長屬性(this.xxx = xxx),屬於當前實例的私有屬性,實例和實例之間是單獨的個體,因此私有的屬性之間是不相等的

五、var res = CreateJsPerson("B",19);函數

  • 這樣不是構造函數執行,而是普通函數的執行 因爲沒有return,因此res = undefined
  • 而且CreateJsPerson這個方法中的this就是window

4.構造函數的擴展

function Fn() {
    var num = 100;
    this.x = 100;
    this.getX = function() {
        console.log(this.x);
    }
}
var f1 = new Fn;
var f2 = new Fn;
複製代碼
  • 在構造函數模式中,new Fn()執行,若是Fn不須要傳遞參數的話,後面的小括號能夠省略學習

  • this問題,在類中出現的this.xxx = xxx;中的this都是當前類的一個實例ui

  • 而某一個屬性值(方法),方法中的this須要看方法執行的時候,前面是否有"." 才知道this是誰,this

  • f1.getX() ---> this指f1,輸出100spa

  • var ss = f1.getX(); ss() ---> this 指window --->輸出undefined3d

  • console.log(f1.num) // --->輸出undefined

  • 類有普通函數的一面,當函數執行的時候,var num 其實只是當前形式的私有做用域中的私有變量而已,它和咱們的f1這個實例沒有任何關係,只有this.xxx = xxx才至關於給f1這個實例增長私有的屬性和方法,才和咱們的f1有關係

  • 在構造函數模式中,瀏覽器會默認把咱們的實例返回,返回的是一個對象數據類型的值,若是咱們本身加了return語句,返回的是一個基本數據類型的值,當前實例是不變的,例如return 100;咱們的f1仍是當前Fn類的實例,若是返回的是一個引用類型的值,當前實例會被本身返回的值給替換掉,例如return { name: 100},咱們的f1就再也不是fn的實例了,而是對象 {name:100}

  • 檢測某一個實例是否屬於這個類,--->instanceof console.log(f1 instanceof Fn) //true console.log(f1 instanceof object) //true

  • 由於全部的實例都是對象數據類型的,並且每個對象的數據類型都是object這個內置類的一個實例,因此f1也是它的一個實例

  • 對於檢測數據類型來講,typeof有本身的侷限性,不能細分object下的對象、數組、正則 。。。。。

  • var a = [];console.log(a instanceof Array) //true 說明a是一個數組

  • f1和f2都是fn這個類的一個實例,都擁有x和getX兩個屬性,可是這兩個屬性都是各自的私有屬性,因此console.log(f1.getX === f2.getX) //false

  • "in" 檢測某一屬性是否屬於這個對象,attr in Object,console.log("getX" in f1);//true getX是f1的一個私有屬性

  • (attr in object) 不論是私有屬性仍是共有屬性,只要存在,用in來檢測都是ture

  • hasOwnProperty:用來檢測某一個屬性是否爲這個對象的"私有屬性",這個方法只能檢測私有的屬性 console.log(f1.hasOwnProperty("getX") )//true 由於getX是f1的私有屬性

  • 擴展思考:檢測某一個屬性是否爲對象的"公有屬性"

function hasPubProperty() {
    return (attr in obj) && !obj.hasOwnProperty(attr)
    //首先 保證是它的一個屬性 而且還不是私有屬性 那麼只能是公有的屬性了 
}
複製代碼
  • 動力: 這是個人學習筆記,您能從中獲得收穫和進步,是我分享的動力,幫助別人,本身也會更快樂
  • 指望: 不喜勿噴,謝謝合做!若是涉及版權請及時聯繫我,立刻刪除!
相關文章
相關標籤/搜索