JavaScript 語言的對象體系,不是基於「類」的,而是基於構造數`constructor`和原型鏈`prototype`, 因此JS 專門使用構造函數做爲對象模板 ,一個構造函數,可生成多個實列對象,它們有相同的結構html
//constructor var Bird = function () { this.name = 'lai fu'; }; var bird1 = new Bird(); // 也可使用 new Bird; 推薦使用前者 console.log(bird1.name) // "lai fu" //ordinary var a =Bird(); console.log(a) // undefined console.log(a.name) // typeError name // 'laifu'
//使用 嚴格模式 function Fubar(foo, bar){ 'use strict'; this._foo = foo; this._bar = bar; } Fubar()// TypeError //判斷 this 不是構造函數(constructor)的實列對象 那麼手動返回自身constructor function Far(a){ if (!(this instanceof Far)) return new Far(a); this._a=a; } Far(1)._a
/** *新生成一個空對象 *連接到原型 *綁定 this *返回新對象 **/ function _new(constuctor,param) { // 得到構造函數 let Con = [].shift.call(arguments); // 連接到原型 let obj = Object.create(Con.prototype); // 綁定 this,執行構造函數 let result = Con.apply(obj, arguments) // 確保 new 出來的是個對象 return (typeof(result) === 'object' && result != null) ? result : obj } var fn = _new( function Person (name,age){ this.name = name; this.age = age }, 'Owen', 28); fn.name // 'Owen'
function f() { console.log(new.target === f); } f() // false new f() // true //可利用 它來判斷是否使用 new 命令 function f() { if (!new.target) { throw new Error('請使用 new 命令調用!'); }
f() // Uncaught Error: 請使用 new 命令調用!
- 原始的對象以字典結構保存,每個屬性名都對應一個屬性描述對象。編程
var obj = { name: "Owen" }; { name: { [[value]]: "Owen" //函數的地址 [[writable]]: true //是否可賦值 [[enumerable]]: true//是否可枚舉 [[configurable]]: true//是否可配置 } } //屬性的值保存在屬性描述對象的value屬性裏面。
若是 a 屬性的值是 引用值 那麼屬性將如下面的形式保存的:數組
var obj = { fn: function () {} }; /* { fn: { [[value]]: [[writable]]: true [[enumerable]]: true [[configurable]]: true } } */
var f n= function () {}; var obj = { f: fn }; // 單獨執行 fn() // obj 環境執行 obj.f()
(obj.fn = obj.fn)() // window // 等同於 (function () { console.log(this); })() (false || obj.fn)() // window // 等同於 (false || function () { console.log(this); })() (4, obj.fn)() // window // 等同於 (4, function () { console.log(this); })()
var o = { v: 'hello', p: [ 'Owen', 18 ], f: function f() { this.p.forEach(function (item) { console.log(this.v + '-' + item); }, this); //將外層的this傳遞給forEach方法 } } o.f() // hello-Owen hello-18