//數組內置類: Array 每個數組都是數組內置類的實例
//對象內置類: Object 每個對象數據類型都是對象內置類的實例
//函數內置類: Function 每個函數都是函數內置類的實例
//Js中除了內置類 項目中也須要自定義類
複製代碼
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 是函數名 方法名
//經過函數的執行 返回一個對象
複製代碼
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這個類的一個實例
複製代碼
二、在函數代碼執行的時候 相同:都是造成一個私有的做用域,而後形參賦值 -->預解釋 --> 代碼從上往下執行(類也有普通函數的一面) 不一樣:在代碼執行以前,構造函數不用再本身建立對象,瀏覽器會默認建立一個對象數據類型的值(這個對象其實就是咱們當前類的一個實例),而後代碼從上往下執行,以當前實例爲執行的主體(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這個方法,可是不一樣實例之間的方法是不同的瀏覽器
五、var res = CreateJsPerson("B",19);函數
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)
//首先 保證是它的一個屬性 而且還不是私有屬性 那麼只能是公有的屬性了
}
複製代碼