js原型鏈1

系列文章:

js原型鏈1
js原型鏈2html

1. 函數對象和普通對象

js中,萬物皆對象。對象分爲函數對象和普通對象。記住Object和Function是js自帶的函數對象。segmentfault

console.log(typeof Object); //function
console.log(typeof Function); //function

函數對象是function;普通對象是object。下面看經常使用的幾種生成對象的方法:函數

var o1 = {};
var o2 = new Object;
var o3 = new Object();
var o4 = new Object(undefined);
var o5 = new Object(null);
var o6 = Object.create(Object.prototype);
var o7 = Object.create(null);
console.log(typeof o1); // object
console.log(typeof o2); // object
console.log(typeof o3); // object
console.log(typeof o4); // object
console.log(typeof o5); // object
console.log(typeof o6); // object
console.log(typeof o7); // object

function f1(){};
var f2 = function(){};
var f3 = new Function('str','console.log(str)');
console.log(typeof f1);// function
console.log(typeof f2);// function
console.log(typeof f3);// function

var o8 = new f1();
console.log(typeof o8);// object

記住,凡是經過new Function()或function關鍵字建立的對象都是函數對象,其餘是普通對象。Object和Function也都是經過new Function()建立的。this

2. 原型對象

在js中,每當定義一個對象,對象中都會有一些預約義的屬性。其中函數對象的一個屬性就是原型對象prototype;普通對象沒有prototype,但有__proto__屬性。打印o1-o8發現,除了o7其餘都同樣。spa

o7:
Object{No Properties} 

其餘:
Object{__proto__: Object}

而f1-f3卻都不同。prototype

f1: function f1(){}
f2: function (){} // 匿名函數
f3: function anonymous(str/**/) { // anonymous意思是匿名
        console.log(str)
    }

發現打印不出prototype,咱們直接打印prototype試試:code

console.log(typeof f1.prototype);console.log(f1.prototype);
結果以下:
object
Object{constructor: f1(), __proto__: Object}

console.log(typeof f2.prototype);console.log(f2.prototype);
結果以下:
object
Object{constructor: (),__proto__: Object}

console.log(typeof f3.prototype);console.log(f3.prototype);
結果以下:
object
Object{constructor:anonymous(str/**/),__proto__:Object}

再打印Object.prototype和Functjion.prototype試試htm

console.log(typeof Object.prototype);console.log(Object.prototype);
結果以下:
object
Object{
    __defineGetter__:__defineGetter__()
    __defineSetter__:__defineSetter__()
    __lookupGetter__:__lookupGetter__()
    __lookupSetter__:__lookupSetter__()
    constructor:Object()
    hasOwnProperty:hasOwnProperty()
    isPrototypeOf:isPrototypeOf()
    propertyIsEnumerable:propertyIsEnumerable()
    toLocaleString:toLocaleString()
    toString:toString()
    valueOf:valueOf()
    get __proto__:__proto__()
    set __proto__:__proto__()
}

console.log(typeof Function.prototype);console.log(Function.prototype);
結果以下:
function
function () {}

3. 原型對象的做用

var person = function(name){
this.name = name
};
person.prototype.getName = function(){
 return this.name; 
}

var zzz = new person('zzz');
console.log(zzz.getName()); // zzz

原型鏈中增長一個函數,他的實例就能夠直接使用這個函數了。對象

4. 原理

js在建立對象的時候都有一個__proto__屬性,指向建立它的函數的prototype屬性。內存

1. console.log(zzz.__proto__ == person.prototype);// true
2. console.log(person.__proto__ == Function.prototype);// true
3. console.log(person.prototype.__proto__ == Object.prototype);// true
4. console.log(Object.__proto__ == Function.prototype);// true
5. console.log(Function.__proto__ == Function.prototype);//true
6. console.log(Function.prototype.__proto__ == Object.prototype);//true

分析1:zzz是person建立的,因此person.__proto__指向person.prototype.
分析2:person是Function建立的,因此person.__proto__指向Function.prototype.
分析3:person.prototype是個對象,是Object建立的。
分析4:Object是Function建立的。
分析5:Function也是本身建立的,比較特殊。
分析6:Function的prototype是對象,Object建立的。

總結:

1. 有prototype都是object,因此全部prototype的__proto__都指向Object的prototype。
2. Object的prototype的__prototype__特殊,指向null.
3. Function的__proto__也比較特殊,指向本身的prototype.

圖解以下:

Paste_Image.png

另外,原型對象prototype中都有一個constructor屬性,用來引用他的函數對象,即。

person.prototype.constructor === person;// true

5. 參考文章

JS原型與原型鏈終極詳解
附本身理解的原文章中的內存分析圖:

Paste_Image.png

相關文章
相關標籤/搜索