系列文章:
1. 函数对象和普通对象
js中,万物皆对象。对象分为函数对象和普通对象。记住Object和Function是js自带的函数对象。
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()创建的。
2. 原型对象
在js中,每当定义一个对象,对象中都会有一些预定义的属性。其中函数对象的一个属性就是原型对象prototype;普通对象没有prototype,但有__proto__属性。打印o1-o8发现,除了o7其他都一样。
o7:
Object{No Properties}
其他:
Object{__proto__: Object}
而f1-f3却都不一样。
f1: function f1(){}
f2: function (){} // 匿名函数
f3: function anonymous(str/**/) { // anonymous意思是匿名
console.log(str)
}
发现打印不出prototype,我们直接打印prototype试试:
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试试
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.
图解如下:
另外,原型对象prototype中都有一个constructor属性,用来引用他的函数对象,即。
person.prototype.constructor === person;// true
5. 参考文章
JS原型与原型链终极详解
附自己理解的原文章中的内存分析图:
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。