// 函數也是對象:對象分爲函數對象和普通對象 // 對象和對象的建立 var o1 = {}; var o2 = new Object(); var o3 = new f1(); var o4 = Object.create({}); // 函數和函數的建立 function f1() {} var f2 = new Function(); var f3 = function() {}; console.log("o1", typeof o1); //object console.log("o2", typeof o2); //object console.log("o3", typeof o3); //object console.log("o4", typeof o4); //object console.log("f1", typeof f1); //function console.log("f2", typeof f2); //function console.log("f3", typeof f3); //function console.log("Function", typeof Function); //function console.log("Object", typeof Object); //function
// 普通對象都是由構造函數建立,普通對象在建立的時候帶有constructor 和 __proto__ 屬性 // constructor 是一個指向其構造函數的指針 // __proto__ 是一個指向構造函數原型對象的指針 console.log("o1.constructor", o1.constructor); //ƒ Object() { [native code] } console.log("o2.constructor", o2.constructor); //ƒ Object() { [native code] } console.log("o3.constructor", o3.constructor); //ƒ f1() {} console.log("o1.prototype", o1.prototype); //undefined console.log("o2.prototype", o2.prototype); //undefined console.log("o3.prototype", o3.prototype); //undefined console.log("o1.__proto__", o1.__proto__ === Object.prototype); // true console.log("o2.__proto__", o2.__proto__ === Object.prototype); //true console.log("o3.__proto__", o3.__proto__ === f1.prototype); //true // 構造函數在建立的時候也是帶有constructor __proto__ 屬性 ,而且比普通對象多一個 prototype 屬性 // 構造函數的constructor指針都是指向 Function // 構造函數的__proto__指針都是指向 一個匿名函數 console.log("f1.constructor", f1.constructor); //ƒ Function() { [native code] } console.log("f2.constructor", f2.constructor); //ƒ Function() { [native code] } console.log("f3.constructor", f3.constructor); //ƒ Function() { [native code] } console.log("f1.prototype", f1.prototype ); //{constructor:f f1(),__proto__:Object} console.log("f2.prototype", f2.prototype); //{constructor:f anonymous(),__proto__:Object} console.log("f3.prototype", f3.prototype); //{constructor:f (),__proto__:Object} console.log("f1.__proto__", f1.__proto__); // ƒ () { [native code] } console.log("f2.__proto__", f2.__proto__); //ƒ () { [native code] } console.log("f3.__proto__", f3.__proto__); //ƒ () { [native code] }
// 因此在Function的原型實際上是一個匿名函數 console.log("Function.prototype", Function.prototype); //ƒ () { [native code] } // 那麼Function做爲構造函數其 constructor 和 __proto__ 分別指向哪裏呢? console.log("Function.constructor", Function.constructor); // ƒ Function() { [native code] } console.log("Function.__proto__", Function.__proto__); //ƒ () { [native code] } // 能夠看到 Function 的構造函數是本身 ,原型對象是匿名函數 // 那麼這個匿名函數有沒有 constructor __proto__ prototype 三個屬性呢?又分別指向哪裏呢 console.log("Function.__proto__.constructor", Function.__proto__.constructor); // ƒ Function() { [native code] } console.log("Function.__proto__.prototype", Function.__proto__.prototype); // undefined console.log("Function.__proto__.__proto__", Function.__proto__.__proto__===Object.prototype); // true // Function.__proto__ 是一個匿名函數 ,其是一個特殊的對象,沒有prototype屬性, // 和普通對象同樣只有 constructor 和 __proto__ 指針 // 咱們能夠得出這個特殊的匿名函數的__proto__指向是對象的原型 // 這個對象的原型是否還存在指針,其指向是哪裏呢? console.log("Object.prototype.constructor",Object.prototype.constructor); // ƒ Object() { [native code] } console.log("Object.prototype.__proto__",Object.prototype.__proto__); // null console.log("Object.prototype.prototype",Object.prototype.prototype); // undefined
console.log("o4.__proto__", o4.__proto__); // {} console.log("o4.prototype", o4.prototype); // undefined console.log("o4.constructor", o4.constructor); // ƒ Object() { [native code] }
// objectA instaceof objectB : instanceof 運算符用來檢測 constructor.prototype 是否存在於參數 object 的原型鏈上。 // return objectA.__proto__ === objectB.prototype console.log("o1 instanceof Object",o1 instanceof Object) // true console.log("o1 instanceof Function",o1 instanceof Function) // false console.log("f1 instanceof Object",o1 instanceof Object) // true console.log("f1 instanceof Function",o1 instanceof Function) // false console.log("Object instanceof Function",Object instanceof Function) // true console.log("Function instanceof Object",Function instanceof Object) // true
// 須要注意的是:objectA.__proto__ === objectB.prototype並非永遠成立,當objectB的prototype的指向改變的時候,則不成立。 function C() {} var c = new C(); var d = {}; console.log("c instanceof C", c instanceof C); C.prototype = d; console.log("c instanceof C", c instanceof C); // console.log("c instanceof d",c instanceof d) // Uncaught TypeError: Right-hand side of 'instanceof' is not callable var e = new C(); console.log("e.__proto__", e.__proto__); // {}