原型和原型鏈類似於Java和C#的繼承;
首先在慕課網上學習到的5個關於JavaStript原型的規則。
1.所有引用類型(數組,函數,對象)除了null之外,都有對象的特徵,都可以自由擴展屬性;
2.所有的引用類型,都有__proto__(隱式原型)屬性,屬性值是一個普通的對象。
3.所有的函數,都有一個prototype(顯式原型)屬性,屬性值是也是一個普通的對象。
4.所有的引用類型(數組,對象,函數),其__proto__屬性指向它的構造函數的"prototype"屬性.
5.當試圖得到一個引用類型的屬性時,如果這個引用類型本身沒有這個屬性,那麼他會去它的__proto__(即它的構造函數的prototype中尋找).
五個規則的例子如下:
//1.所有引用類型(數組,函數,對象)除了null之外,都有對象的特徵,都可以自由擴展屬性;
var obj = {}; obj.a = 100;
var arr = []; arr.a = 10;
var fn = function () {
}
fn.a = 1;
var fn1 = new fn();//創建一個fn的實例
console.log(obj.a);
console.log(arr.a);
console.log(fn.a);
//2.所有的引用類型,都有__proto__(隱式原型)屬性,屬性值是一個普通的對象。
console.log(obj.__proto__);
console.log(arr.__proto__);
console.log(fn.__proto__);
//3.所有的函數,都有一個prototype(顯式原型)屬性,屬性值是也是一個普通的對象。
console.log(fn.prototype);
//下面兩個是未定義的
console.log(obj.prototype);//undefined 所以可見Obj和數組是沒有顯示原型的啦。
console.log(arr.prototype);//undefined
//4.所有的引用類型(數組,對象,函數),其__proto__屬性指向它的構造函數的"prototype"屬性.
console.log(fn.__proto__ === Function.prototype);//true
console.log(fn instanceof Object);
console.log(fn instanceof Function);
console.log(Function instanceof Object);
console.log(Function.__proto__ === Object.prototype)
console.log(obj.__proto__ === Object.prototype);//true
console.log(arr.__proto__ === Array.prototype);//true
/*----------------------------------------------------------------------------*/
console.log(fn1.__proto__ === fn.prototype);//true fn是fn1的構造函數,所以下面的式子爲假.
console.log((fn1.__proto__).__proto__ === Function.prototype);//false
console.log(fn1 instanceof Function);
// console.log(Object.prototype === null);
//5.當試圖得到一個引用類型的屬性時,如果這個引用類型本身沒有這個屬性,那麼他會去它的__proto__(即它的構造函數的prototype中尋找).
//構造函數:
function Foo(name,age) {
this.name = name;
}
Foo.prototype.alertName=function () {
alert(this.name);
}
//創建示例:
var f = new Foo('zhangsan')
f.printName=function () {
console.log(this.name);
}
//測試:
f.printName();
f.alertName();
console.log(f.__proto__ === Foo.prototype);
console.log(Foo instanceof Function);
但是在這也拋出疑問:
1.在例子的第五點中 f 函數是由Foo函數構造出來的,所以(f instanceof Foo)是true的;
Foo也是又Function函數構造出來的,所以(Foo instantceof Fucntion)是true;
但是(f instanceof Function)確實false;f 的最終的顯示原型是Object.這個困惑一直不解。
以下是兩個函數的原型鏈。
// __proto__ _proto__ __proto__
// f -----------> Foo.prototype -----------> Object.prototype -----------> null
// __proto__ __proto__ __proto__
// Foo -----------> Function.prototype -----------> Object.prototype -----------> null
最後推薦個幫助理解的博客。
https://www.cnblogs.com/objectorl/archive/2010/01/11/Object-instancof-Function-clarification.html