繼承:當前對象沒有的屬性和方法,別人有,拿來給自己用,就是繼承 1 混入式繼承 2.原型繼承 a) 給原型對象添加新成員(通過對象的動態特性),不是嚴格意義上的繼承 ,,,,實例對象繼承了原型 b) 直接替換原型對象 c) 利用混入的方式給原型對象添加成員 3.經典繼承 js var 對象1 = O ...
繼承:當前對象沒有的屬性和方法,別人有,拿來給自己用,就是繼承
1 混入式繼承
var I={ }; var obj = { name: 'jack', age:18, sayGoodbye : function () { console.log("goodbye") ; } } // 混入式繼承, a中 將繼承obj的所有屬性 for (var k in obj ) { a[k] = obj [k] ; }
2.原型繼承
- 利用原型中的成員可以被其相關對象共用這一特性,可以實現繼承
- 實現步驟
a) 給原型對象添加新成員(通過對象的動態特性),不是嚴格意義上的繼承 ,,,,實例對象繼承了原型
b) 直接替換原型對象
- 構造函數.prototypr = 新對象
- 實例對象繼承了原型(新對象)
- 如果對象原本有屬性和方法,使用替換的方法會覆蓋原有的屬性和方法
c) 利用混入的方式給原型對象添加成員
- 混入,遍歷一個對象的屬性和方法,賦值給另一個對象 for...in...
3.經典繼承
js
var 對象1 = Object.creat(對象2) ;
這時候,創建出來的對象1 繼承自對象2
Object.creat方法存在相容性問題
解決:
1.檢測瀏覽器是否支持Object.create方法,如果不支持,直接手動給Object添加create方法
2.自定義函數,在函數內部判斷瀏覽器是否支持Object.create方法,如果不支持,則手動創建對象返回,否則直接調用
function creat(obj) { if (object.creat){ return Object.creat(obj); }else{ function F(){ } F.prototype = obj; return new F(); } }
如何更安全的拓展內置對象
function MyArray() { this.name = "我是數組" } var arr = new Array(); MyArray.prototype =arr ; // 繼承後,我的數組中 就有了原生數組對象的所有屬性和方法 var myArr = new MyArray() ; // myArr 這個對象就繼承自arr
原型鏈
什麼是原型鏈
每個構造函數都有原型對象,每個對象都有構造函數,每個構造函數的原型對象都是對象,也就有構造函數
然後就形成一個鏈式的結構,我們稱之為原型鏈
原型繼承是什麼?
通過修改原型鏈的結構,實現繼承的方式就是原型繼承
屬性搜索原則
- 當訪問一個對象的成員的時候,先在自身找有沒有,如果有,直接使用
- 如果沒有找到,則去當前對象的原型對象中去找,如果有,直接使用
- 如果沒有找到,則去原型對象的原型對象中去找,如果有,直接使用
- 指導Object,如果還是沒有,則返回null
通過修改原型鏈繼承結構實現的繼承就叫原型繼承
function Person() { } ; var p = new Person() ;
p對象包含的對象有: Person.prototype中的成員 和自身擁有的成員
Person.prototype中的成員有 : Object.prototype的成員和自身的成員
Object.prototype的成員:
constructor : 指向和該原型相關的構造函數
hasOwnProperty 方法: 判斷獨享本身是否擁有某個屬性. obj.hasOwnProperty("屬性名")
isPrototypeOf 方法 判斷一個對象是不是另一個對象的原型對象。 obj.isPrototypeOf(obj2)
propertyIsEnumerable 方法 : 1.判斷屬性是否屬於對象本身 && 2.判斷屬性是否可以遍歷 是的話才返回ture。反之 false。
toString toLocaleString: 將對象轉換成字元串 toLocaleString轉換成字元串的時候應用的本地的設置模式
valueOf 方法: 在對象參與運算的時候,首先調用valueOf方法獲取對象的值,若該值無法參與運算,將會調
用toString方法
__proto__ 屬性: 指向當前對象的原型對象
Function
3種創建函數的方式:
直接聲明
函數表達式
new Function()
可以用Function 來創建函數:
語法:
var 函數名 = new Function ( ) ; // 創建一個空的函數 var 函數名 = new Function("函數體"); // 創建一個沒有參數的函數 var 函數名 = new Function("參數1","參數2","參數3",..."函數體" ) ; // 當給Function傳多個參數的時候,最後一個參數為函數體,前面的參數為創造出來的函數的形參。 Function 接收的所有的參數 都是字元串類型的 arguments 對象 arguments 對象是函數內部的一個對象,在函數調用的時候,系統會預設的將所有傳入的實參存入該對象 註意: 不管有沒有形參, 實參都會被存入該對象
var distinct = new Function(`
var arr = [];
for (var i = 0; i < arguments.length; i++) {
if(arr.indexOf(arguments[i])==-1){
arr.push(arguments[i]);
}
}
return arr;
`);
//可以使用Ese下邊的符號 來連接字元串進行換行操作 但是存在相容性問題
console.log(distinct(1, 2, 34, 34, 5, 5));
instanceof 關鍵字 //語法 對象 instanceof 構造函數 //判斷該構造函數的原型是否存在於該對象的原型鏈上 function Person(){ } //p--->Person.prototype--->Object.prototype--->null var p = new Person(); //構造函數的**原型**是否在該對象的原型鏈上! console.log(p instanceof Person);
//Object構造函數 是 通過 Function 構造函數 實例化出來的
//Function構造函數 也是 通過 Function 構造函數 實例化出來的(不要強行去理解)
//instanceof
//Object.prototype是否在Function的原型鏈上
//Function-->Function.prototype---->Object.prototype---->null
// console.log(Function instanceof Object); //true
//Function.prototype是否在Functionde原型鏈上
// console.log(Function instanceof Function);
//Object--->Function.prototype---->Object.prototype----->null
// console.log(Object instanceof Function);
// console.log(Object instanceof Object);
eval 可以將字元串 轉換成js代碼並執行
註意:當使用eval解析JSON格式字元串的時候,要註意,會將{}解析為代碼段
1.可以在JSON格式字元串前面拼接 "var 變數名 ="
eval("var 變數名 =" + JSON格式的字元串);
2.可以在JSON格式字元串前後拼接()
eval("("+JSON格式的字元串+")")
靜態成員和實例成員
靜態成員
通過構造函數去訪問的屬性和方法就是靜態成員
實例成員
通過對象(實例)去訪問的屬性和方法就是實例成員