方法javascript
<html> <head> <title></title> </head> <script type="text/javascript"> //原型鏈:a1對象(實例對象)還讓A.prototype對象(原型對象)之間的鏈接,叫作原型鏈 //2個對象。之間有一個連接 _proto_ //a1下是沒有num1(A中沒有this.num1=20),會繼續經過a1._proto_找num1。 //a1下有num1(A中沒有this.num1=20),再也不會繼續經過a1._proto_找num1, //即便A.prototype.num1 = 10; alert(a1.num1);依然是20 //.... //原型鏈最外層:Object.prototype function A() { //this.num1=20 } //A.prototype.num1 = 10; /*Function.prototype.num1 = 30;*/ Object.prototype.num1 = 40; /*A.prototype.num1 = 60*/ A.prototype.fun = function () { alert(this.num1) }; var a1 = new A(); a1.fun(); alert(a1.num1); </script> <body> </body> </html>
繼承:子對象的屬性修改,不能致使父對象的屬性的改變
1:Object.create(對象原型)
2:inherit4objfun
我畫了一張圖
html
<!DOCTYPE html> <html lang="ZH-CN"> <head></head> <script type="text/javascript"> function inherit4fun(Child, Parent) { function F() {}; // 定義一個臨時函數 F.prototype = Parent.prototype; // 把父類的原型賦給臨時函數的原型 Child.prototype = new F(); // 把子類的原型賦值爲f的對象 } function inherit4objfun(p){ if(p == null) throw TypeError(); //能夠不用es5中的Object.create //if(Object.create)return Object.create(p); var t = typeof p; if(t !== "object" && t !== "function") throw TypeError(); function f(){} f.prototype = p; return new f(); } function Person(name, age) { this.name = name; this.age = age; this.aler = function () { console.log(`Person.function-aler`);//``es6 的字符串 能夠換行 // console.log(`Per // son.function-aler`);//``es6 的字符串 能夠換行 } } //由於prototype是對象,能夠寫成無序鍵值對 Person.prototype = { sayHi: function () { console.log('Person.prototype-sayhi'); }, sayHello: function () { console.log('Person.prototype-sayhello'); } } function Student(sname, sage) { Person.call(this, sname, sage); } /* 錯誤重現1 //Student.prototype = Person.prototype; //當修改Student.prototype時候,Person.prototype也會被修改 //Student.prototype.saystu =function () {console.log('saystu');} */ /* 錯誤重現2 //當改變Student.prototype時候,原來的會被覆蓋 // Student.prototype = { // saystu: function () { // console.log('saystu'); // } // } */ /* 正確重現1 //當改變Student.prototype時候,原來的會被覆蓋,達不到子類繼承父類,或者子類原型能夠增長方法不影響到父類原型 //此時就須要將二者的方法合併。-->將基類原型的方法拷貝到子類原型上 相似$.extend 拷貝繼承 (淺拷貝就行了,原型中通常存方法) // Student.prototype = new Person(); // Student.prototype.constructor = Student; // Student.prototype.saystu =function () {console.log('saystu');} */ /* 正確重現2 // inherit4fun(Student,Person); // Student.prototype.saystu =function () {console.log('saystu');} */ /* 正確重現3 */ Student.prototype=inherit4objfun(Person.prototype); Student.prototype.saystu =function () {console.log('saystu');} /* 正確重現4 對象的繼承 */ var o={x:1} var childObj=inherit4objfun(o); childObj.y=2; console.log(childObj)//打印不出繼承的屬性。 console.log(childObj.x+childObj.y)//3 var stu1 = new Student("zg", 18); var p1 = new Person(" ls", 20); console.log(stu1,p1) //Student.prototype增長saystu方法,而後看Person.prototype是否增長,增長即是錯誤的 console.log(Student.prototype,Person.prototype ) stu1.aler(); stu1.sayHi(); stu1.sayHello(); //stu1.saystu(); </script> <body> </body> </html>
叫法:散列 散列表 hash hashtable``字典 dictionary``關聯數組 associate array
種類:1,宿主對象(瀏覽器定義)
,dom對象 bom對象(window location navigatior),這些瀏覽器定義的方法能夠當成普通的js函數
,能夠把宿主瀏覽器對象當成內置對象
。
2,內置對象(js定義)
50多種。3,自定義對象
特性:擴展標記(是否能夠向改對象 添加新屬性)!!
,類(class)
,原型(prototype)
java
/* 內置對象舉例 更多https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects 錯誤 Error,EvalError,InternalError,RangeError,ReferenceError,SyntaxError,TypeError,URIError 8種 帶索引的集合Array,Int8Array,Uint8Array,Uint8ClampedArray,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array 10種 帶鍵的集合Map, Set ,WeakMap ,WeakSet 4種 結構化數據ArrayBuffer ,SharedArrayBuffer, Atomics, DataView, JSON 5種 控制抽象對象 Promise, Generator ,GeneratorFunction 3種 反射 Reflect, Proxy 2種 國際化ECMA腳本的多語言附加組件。Intl,Intl.Collator,Intl.DateTimeFormat,Intl.NumberFormat 非標準對象Iterator ,ParallelArray ,StopIteration 其餘arguments */ console.log({}.toString.call(new Error())) //[object Error] console.log({}.toString.call(new SyntaxError('errmsg'))) //[object Error] var buffer = new ArrayBuffer(2); var a=new DataView(buffer) console.log({}.toString.call(a)) //[object DataView] function* gen() { yield 1;yield 2;yield 3;} var g = gen() onsole.log({}.toString.call(g)) //[object Generator] console.log({}.toString.call(Infinity)) //[object Number] console.log({}.toString.call(new Float32Array(2))) //[object Float32Array]
種類:繼承屬性(inherited property)
,自有屬性(own property)
屬性特性(property attribute)
1,數據屬性特性
可枚舉(enumerable) 默認true。for-in遍歷出
,可配置(configurable)
,可寫(writable)
,值(value)
2,訪問器屬性特性
將數據屬性的 可寫
和值
特性換成set(val)
, get()
方法function!
可枚舉(enumerable)默認true。for-in遍歷出
,可配置(configurable)
,set(val)function
,get()function
----
----es6
Object.defineProperty()
,Object.defineProperties()
getOwnPropertyDescriptor(obj,attr)
,getOwnPropertyDescriptors(obj)(參數只有對象,注意返回值)
/* 不明確聲明,特性值默認false,value默認undefined, 區分經常使用方式 */ //defineProperty var obj={}; Object.defineProperty(obj,'a',{configurable:true}) //{configurable:true,enumerable:false,value:undefined,writable:false} Object.getOwnPropertyDescriptor(obj,'a') /* { a: Object __proto__: Object } */ Object.getOwnPropertyDescriptors(obj) ------------------------------------------------------- //defineProperties /* { a:{configurable:false,enumerable:false,value:undefined,writable:false}, b:{configurable:false,enumerable:false,value:undefined,writable:false}, __proto__:Object... } */ var obj={}; Object.defineProperties(obj,{a:{enumerable:false},b:{writable:false}}) Object.getOwnPropertyDescriptors(obj) ------------------------------------------------------- //經常使用默認true Object.getOwnPropertyDescriptors({a:1},'a')//{configurable:true,enumerable:true,value:1,writable:true}
var o={a:1}; o.b=2 console.dir(o)//{a:1,b:2} Object.preventExtensions(o) o.c=3 console.dir(o)//{a:1,b:2} 不可添加 o.b=4 console.dir(o)//{a:1,b:4} 能夠編輯
var parentObj={a1:'a1'}; Object.defineProperties(parentObj,{a2:{enumerable:true,value:'a2'},a3:{enumerable:false,value:'a3'}}) var childObj=inherit4objfun(parentObj); childObj.b1='b1'; Object.defineProperties(childObj,{b2:{enumerable:true,value:'b2'},b3:{enumerable:false,value:'b3'}}) /* ------------------------------------------ for in 自己,繼承,可枚舉 ---------------------------------------------------- */ for(var attr in childObj){console.info(`自身和繼承的枚舉屬性`+attr)}//a1 a2 b1 b2 /* ------------------------------------------ Object.keys(obj) 自己,可枚舉 ---------------------------------------------------- */ console.log(`自身的枚舉屬性`+Object.keys(childObj))//["b1", "b2"] /* ------------------------------------------ Object.getOwnPropertyNames(obj) 自己全部屬性,包括不可枚舉---------------------------------------------------- */ console.log(`自身的全部屬性,包括不可枚舉`+Object.getOwnPropertyNames(childObj))//["b1", "b2"] var arr=[6,'a'] Object.getOwnPropertyNames(arr)//["0", "1","length"] Object.getOwnPropertyNames(Object.prototype) //["__defineGetter__", "__defineSetter__", "hasOwnProperty", "__lookupGetter__", "__lookupSetter__", "propertyIsEnumerable", "constructor", "toString", "toLocaleString", "valueOf", "isPrototypeOf", "__proto__"] Object.getOwnPropertyNames(Object) //["length", "name", "arguments", "caller", "prototype", "assign", "create", "getOwnPropertyDescriptor", "getOwnPropertyNames", "getOwnPropertySymbols", "is", //"preventExtensions", "seal", "defineProperties", "defineProperty", "freeze", "getPrototypeOf", "isExtensible", "isFrozen", "isSealed", "keys", "setPrototypeOf", "entries", "values", "getOwnPropertyDescriptors"]
childObj.hasOwnProperty('a1')//false 繼承不能檢測 childObj.hasOwnProperty('a3')//false childObj.hasOwnProperty('b1')//true childObj.hasOwnProperty('b3')//true 自有不可枚舉的也能檢測出來 childObj.propertyIsEnumerable('a1')//false 繼承不能檢測 childObj.propertyIsEnumerable('a3')//false childObj.propertyIsEnumerable('b1')//true 只有自有可枚舉屬性 childObj.propertyIsEnumerable('b3')//false
//防止內存泄漏 var a={b:{c:0}} //delete b.c delete a.b//切斷b屬性(對象)與宿主a(對象)的聯繫 刪除的b對象的引用{{c:0}}依然存在 要檢測遍歷b屬性中是否含有屬性,再遞歸檢測屬性是否含有屬性,直到最後不含有。防止內存泄漏 //假如從var a={b:{c:{d:{e:1}}}}刪除b屬性 //從裏到外刪除 //delete a.b.c.d.e //delete a.b.c.d //delete a.b.c //delete a.b
var o={a:1}; var c; Object.defineProperty(o,'b',{configurable: false, enumerable: true, get: function () { return 11; }, set: function proxySetter(newVal) { }}) o.b=8