十五、JavaScript面向物件
一、面向物件概念
-
-
面向物件,是一種程式設計思想、語法、方法、程式碼編寫的方式
-
面向物件
-
關注注重物件的操作
-
可以設定屬性/鍵名
-
可以設定屬性值/鍵值
-
可以設定函式
-
-
可以將需要執行的程式內容,都定義給物件
-
呼叫物件的函式,來執行程式
-
-
有JavaScript提供好的內建物件,或者別人寫的第三方外掛
-
二、工廠模式建立物件
-
以固定的模式,生成物件
-
1 function createObj(n, a, s) {2 // 建立物件 3 const obj = {}; 4 // 給物件新增屬性和屬性值 5 obj.name = n; 6 obj.age = a; 7 obj.sex = s; 8 // 給物件新增函式方法 9 obj.fun = function () { 10 console.log(this.name, this.age, this.sex); 11 } 12 // 返回這個物件 13 return obj; 14 } 15 16 const obj1 = createObj('張三', 18, '男'); 17 console.log(obj1);
三、建構函式創造物件
建構函式:本質還是一個函式,是一個專門生成物件的函式,生成的這個物件,有屬性屬性值,還有函式方法
-
定義函式時,還是按照原始方法定義函式
-
1 function CreateObj(n, a, s) { 2 console.log(this); 3 4 this.name = n; 5 this.age = a; 6 this.sex = s; 7 this.fun = function () { 8 console.log(this); 9 // console.log(this.name,this.age,this.sex);10 } 11 } 12 const obj1 = new CreateObj('張三', 18, '男');
-
-
與 new 一起使用的函式,不用再定義建立物件和返回值物件
-
所謂的建構函式,本質上就還是一個函式
-
為了區分建構函式和普通函式,JavaScript約定俗成
-
建構函式,函式名稱 大駝峰命名法
-
普通函式,函式名稱 小駝峰命名法
-
-
this指向
-
使用 function 定義的函式,this指向,看的是呼叫之前寫的內容
-
建構函式的 this,指向的都是通過建構函式,建立的物件
-
-
建構函式的返回值,一定是一個物件,通過建構函式生成的物件,稱為例項化物件
-
四、原型
-
每一個函式天生就具有的自帶的屬性,叫做prototype
-
以物件的形式,儲存公共的內容
-
建構函式也是函式,也有 prototype
-
1 // 通過公共空間 prototype 定義函式方法 2 function CreateObj(name,age){ 3 this.name = name; 4 this.age = age; 5 } 6 7 CreateObj.prototype.fun = function(){ 8 console.log(this.name,this.age); 9 } 10 11 const obj1 = new CreateObj('張三' , 18); 12 const obj2 = new CreateObj('李四' , 20);
-
-
prototype:是每個 函式 都天生就具有的屬性,是 物件
-
例項化物件,也是物件,只不過是通過建構函式生成的例項化物件
-
此時例項化物件 __proto__ 指向的地址就是建構函式 prototype 記憶體地址
-
通過 _
-
-
例項化物件在呼叫屬性和函式方法時,優先呼叫例項化物件本身的屬性和函式方法(也就是說例項化物件中有name屬性,prototype中也有name屬性,優先呼叫例項化物件本身的name屬性)
-
如果呼叫例項化物件本身沒有的屬性,會去 __proto__ 也就是建構函式prototype中找是否有這個屬性
-
如果有,就呼叫這個屬性
-
如果都沒有這個屬性,執行結果是undefined
-
-
如果想直接呼叫 __proto__ 也就是 建構函式 prototype 中定義的屬性,可以使用語法,例項化物件.__proto__.屬性
-
-
-
-
每一個函式,天生都具有 prototype
-
-
__proto__:原型屬性
-
每一個物件,天生都具有 __proto__
-
-
JavaScript中每一種資料型別本質上都是物件型別,每一種資料型別實際上都有__proto__屬性
-
每一個數據型別 / 資料,都可以通過 __proto__ 找到生成這個資料型別的 建構函式的prototype
-
建構函式,本身也有 __proto__ 可以再找這個建構函式的父級建構函式
-
六、精確檢驗資料型別的方法
1、
1 // Object.prototype.toString.call( 要檢查的資料 ) 2 3 console.log(Object.prototype.toString.call(true)); // [object Boolean] 4 console.log(Object.prototype.toString.call(100)); // [object Number] 5 console.log(Object.prototype.toString.call(100.123));// [object Number] 6 console.log(Object.prototype.toString.call(1e3)); // [object Number] 7 console.log(Object.prototype.toString.call(NaN)); // [object Number] 8 console.log(Object.prototype.toString.call('sting')); // [object String] 9 console.log(Object.prototype.toString.call(undefined)); // [object Undefined] 10 console.log(Object.prototype.toString.call(null)); // [object Null] 11 console.log(Object.prototype.toString.call([])); // [object Array] 12 console.log(Object.prototype.toString.call({})); // [object Object] 13 console.log(Object.prototype.toString.call(function () { })); // [object Function] 14 console.log(Object.prototype.toString.call(new Date())); // [object Date] 15 console.log(Object.prototype.toString.call(/^\d$/)); // [object RegExp]
判斷資料是否是某個具體的資料型別時,判斷的字串也必須有 [ ]
1 console.log(Object.prototype.toString.call(true) === '[object Boolean]');
2、instanceof
1 {} instanceof Object; //true 2 [] instanceof Array; //true 3 [] instanceof Object; //true 4 "123" instanceof String; //false 5 new String(123) instanceof String; //true
3、constructor
-
-
然後在prototype上新增一個constructor屬性,並讓其指向F的引用
-
F利用原型物件的constructor屬性引用了自身
-
當F作為建構函式建立物件時,原型上的constructor屬性被遺傳到了新建立的物件上
-
1 ''.constructor == String // true 2 new Number(1).constructor == Number // true 3 true.constructor == Bollean // true 4 new Function().constructor == Function //true 5 new Date().constructor == Date // true 6 new Error().constructor == Error // true 7 [].constructor == Array // true 8 document.constructor == HTMLDoucment // true 9 window.constructor == window //true