一. 普通對象與函數對象 JavaScript 中,萬物皆對象!但對象也是有區別的。分為普通對象和函數對象,Object 、Function 是 JS 自帶的函數對象。 o1 o2 o3 為普通對象,f1 f2 f3 為函數對象 (凡是通過 new Function() 創建的對象都是函數對象,其他 ...
一. 普通對象與函數對象
JavaScript 中,萬物皆對象!但對象也是有區別的。分為普通對象和函數對象,Object 、Function 是 JS 自帶的函數對象。
o1 o2 o3 為普通對象,f1 f2 f3 為函數對象 (凡是通過 new Function() 創建的對象都是函數對象,其他的都是普通對象)
var o1 = {}; var o2 =new Object(); var o3 = new f1(); function f1(){}; var f2 = function(){}; var f3 = new Function('str','console.log(str)'); console.log(typeof Object); //function console.log(typeof Function); //function console.log(typeof f1); //function console.log(typeof f2); //function console.log(typeof f3); //function console.log(typeof o1); //object console.log(typeof o2); //object console.log(typeof o3); //object
構造函數(擴展)
1.var a = {} 其實是 var a = new Object()的語法糖 (a 的構造函數是 Object 函數)
2.var a = [] 其實是 var a = new Array()的語法糖 (a 的構造函數是 Array 函數)
3.function Foo(){...}其實是 var Foo = new Function(...) (Foo 的構造函數是 Function 函數)
二. 構造函數
function Person(name, age, job) { this.name = name; this.age = age; this.job = job; this.sayName = function() { alert(this.name) } } var person1 = new Person('Zaxlct', 28, 'Software Engineer'); var person2 = new Person('Mick', 23, 'Doctor');
person1 和 person2 都是 Person 的實例,兩個實例都有一個 constructor
(構造函數)屬性,該屬性(是一個指針)指向 Person,其層級如下:
所以可以得出:
console.log(person1.constructor == Person); //true
console.log(person2.constructor == Person); //true
person1 和 person2 都是 構造函數 Person 的實例
實例的構造函數屬性(constructor)指向構造函數
三. 原型對象
在 JavaScript 中,每當定義一個對象(函數也是對象)時候,對象中都會包含一些預定義的屬性。其中每個函數對象都有一個prototype
屬性(只有函數才有prototype,實例只有__proto__),這個屬性指向函數的原型對象。
註意:
1.只有函數才有prototype,實例(new Animal)只有__proto__
2.函數是Function的實例,函數的prototype是Object的實例
3.Function.__proto__ == Function.prototype
4.Object.prototype.__proto__ == null
比如:
function Animal() {}
const a = new Animal()
1. a.__proto__ == Animal.prototype
2. Animal.prototype.constructor == Animal
3. 只要用function聲明的Animal,就會帶一個prototype屬性,而Animal是Function的實例 【Animal instanceof Function 為true】,Animal.__proto__ == Function.prototype
4. Animal.prototype是Animal上一個屬性,是一個對象屬性,它【Animal.prototype instanceof Object 為true】,Animal.prototype.__proto__ == Object.prototype
四. 原型對象繼承
當我們聲明一個function關鍵字的方法時,會為這個方法添加一個prototype屬性,指向預設的原型對象,並且此prototype的constructor屬性也指向方法對象
function Person() {
}
var person = new Person();
Person 就是一個構造函數,我們使用 new 創建了一個實例對象 person
第一:
每個函數都有一個 prototype 屬性
每一個JavaScript對象(null除外)在創建的時候就會與之關聯另一個對象,這個對象就是我們所說的原型,每一個對象都會從原型"繼承"屬性。
每一個JavaScript對象(除了 null )都具有的一個屬性,叫proto,這個屬性會指向該對象的原型
每個原型都有一個 constructor 屬性指向關聯的構造函數 實例原型指向構造函數
最終原型鏈
1)什麼是原型鏈?
原型鏈的核心就是依賴對象的_proto_的指向,當自身不存在的屬性時,就一層層的扒出創建對象的構造函數,直至到Object時,就沒有_proto_指向了。
2)如何分析原型鏈?
因為_proto_實質找的是prototype,所以我們只要找這個鏈條上的構造函數的prototype。其中Object.prototype是沒有_proto_屬性的,它==null。
最簡單的原型鏈分析
function Person(name){
this.name = name;
}
var p = new Person();
//p ---> Person.prototype --->Object.prototype---->null