参考http://www.jianshu.com/p/dee9f8b14771
js万物皆对象, 对象包括普通对象和函数对象(构造器对象)
- 1 构造器对象也就是函数对象, 如
var Person = function(){}
//生成方式
Person在生成时, 会隐式使用如下方式
new Function('person', 'function(){}')
生成, 而Function.prototype会将自己引用到Person.__proto__上,
so
Person.__proto__ === Function.prototype
包括其他如Object, Array, 只要是函数对象, 它们的 __ proto __ 都是Function.prototype
console.log(Object.__proto__ === Function.prototype);
console.log(Function.__proto__ === Function.prototype);
//Function.prototype = new Function();
console.log(typeof Function.prototype);//funciton
//Array.prototype = new Object();普通对象
console.log(typeof Array.prototype);//object;
通过在Array.prototype这个普通对象上定义各种方法, 如map reduce sort等
由此可以看出Function.prototype是Function,
其他的都是object,
所以可以看做是一个普通的object对象
- 2 普通对象是通过函数对象new出来的, 然后在将函数对象(构造器)的prototype属性(就是一个普通对象)赋给普通对象的__ proto __, 这样普通对象就可以调用构造器prototype上的所有方法, 如:
var Person = function(name){
this.name = name;
}
//如果不定义他的原型, 默认只是一个包含属性constructor构造函数的普通对象
//这里给Person.prototype定义一个eat属性
Person.prototype.eat = function(){
console.log('eat');
console.log(this.name);
};
var tom = new Person('tom');
//在生成tom时, 步骤如下
//(1)创建一个空对象var obj = {}
//(2)Person.apply(obj,arguments)
//apply其实是Function.prototype定义的方法
// 会让Person()函数内部的this指向obj,
所以你写的this.name就相当于obj.name1。给对象添加属性.
//(3)obj.__proto__ === Person.prototype // 搭建原型链
//这一步这是tom可以调用eat方法的关键
//(4)return obj;
// 让var tom = new Person();中的tom接收obj,也就是这里的tom就是函数内部的obj
tom.eat();//eat
总结:
除Function.prototype为Function(因为Function.prototype = new Function),
其他所有构造器对象的prototype都是一个普通的object, 可以给这个object定义不同的属性, 然后通过 new 构造器 生成普通对象, 会搭建原型链, 即
var tom = new Person();
tom.__proto__ = Person.prototype
tom就能使用Person.prototype上所有的方法, 由于Person.prototype只是个普通的object对象(通过Person生成, 包含constructor属性, 所以
Person.prototype.constructor = Person;
Person.prototype.__proto__ = Object.prototype
console.log(Object.getOwnPropertyNames(Object.prototype));
Object.prototype对象上的方法包括如下:
所以tom能使用Object.prototype的所有方法
Object.prototype.__proto__ = null;
Function.prototype为Function, 当执行
var Person = function(){}
搭建原型链时会将Function.prototype赋给Person.__ proto __属性, ,而Function.prototype是一个Function, 包含的属性值:
所以Person的call方法来源于Funciton.prototype.call, 可以直接调用Person()